github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/src/cmd/go/http.go (about)

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build !cmd_go_bootstrap
     6  
     7  // This code is compiled into the real 'go' binary, but it is not
     8  // compiled into the binary that is built during all.bash, so as
     9  // to avoid needing to build net (and thus use cgo) during the
    10  // bootstrap process.
    11  
    12  package main
    13  
    14  import (
    15  	"cmd/internal/browser"
    16  	"crypto/tls"
    17  	"fmt"
    18  	"io"
    19  	"io/ioutil"
    20  	"log"
    21  	"net/http"
    22  	"net/url"
    23  	"time"
    24  )
    25  
    26  // httpClient is the default HTTP client, but a variable so it can be
    27  // changed by tests, without modifying http.DefaultClient.
    28  var httpClient = http.DefaultClient
    29  
    30  // impatientInsecureHTTPClient is used in -insecure mode,
    31  // when we're connecting to https servers that might not be there
    32  // or might be using self-signed certificates.
    33  var impatientInsecureHTTPClient = &http.Client{
    34  	Timeout: 5 * time.Second,
    35  	Transport: &http.Transport{
    36  		Proxy: http.ProxyFromEnvironment,
    37  		TLSClientConfig: &tls.Config{
    38  			InsecureSkipVerify: true,
    39  		},
    40  	},
    41  }
    42  
    43  type httpError struct {
    44  	status     string
    45  	statusCode int
    46  	url        string
    47  }
    48  
    49  func (e *httpError) Error() string {
    50  	return fmt.Sprintf("%s: %s", e.url, e.status)
    51  }
    52  
    53  // httpGET returns the data from an HTTP GET request for the given URL.
    54  func httpGET(url string) ([]byte, error) {
    55  	resp, err := httpClient.Get(url)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  	defer resp.Body.Close()
    60  	if resp.StatusCode != 200 {
    61  		err := &httpError{status: resp.Status, statusCode: resp.StatusCode, url: url}
    62  
    63  		return nil, err
    64  	}
    65  	b, err := ioutil.ReadAll(resp.Body)
    66  	if err != nil {
    67  		return nil, fmt.Errorf("%s: %v", url, err)
    68  	}
    69  	return b, nil
    70  }
    71  
    72  // httpsOrHTTP returns the body of either the importPath's
    73  // https resource or, if unavailable, the http resource.
    74  func httpsOrHTTP(importPath string, security securityMode) (urlStr string, body io.ReadCloser, err error) {
    75  	fetch := func(scheme string) (urlStr string, res *http.Response, err error) {
    76  		u, err := url.Parse(scheme + "://" + importPath)
    77  		if err != nil {
    78  			return "", nil, err
    79  		}
    80  		u.RawQuery = "go-get=1"
    81  		urlStr = u.String()
    82  		if buildV {
    83  			log.Printf("Fetching %s", urlStr)
    84  		}
    85  		if security == insecure && scheme == "https" { // fail earlier
    86  			res, err = impatientInsecureHTTPClient.Get(urlStr)
    87  		} else {
    88  			res, err = httpClient.Get(urlStr)
    89  		}
    90  		return
    91  	}
    92  	closeBody := func(res *http.Response) {
    93  		if res != nil {
    94  			res.Body.Close()
    95  		}
    96  	}
    97  	urlStr, res, err := fetch("https")
    98  	if err != nil {
    99  		if buildV {
   100  			log.Printf("https fetch failed: %v", err)
   101  		}
   102  		if security == insecure {
   103  			closeBody(res)
   104  			urlStr, res, err = fetch("http")
   105  		}
   106  	}
   107  	if err != nil {
   108  		closeBody(res)
   109  		return "", nil, err
   110  	}
   111  	// Note: accepting a non-200 OK here, so people can serve a
   112  	// meta import in their http 404 page.
   113  	if buildV {
   114  		log.Printf("Parsing meta tags from %s (status code %d)", urlStr, res.StatusCode)
   115  	}
   116  	return urlStr, res.Body, nil
   117  }
   118  
   119  func queryEscape(s string) string { return url.QueryEscape(s) }
   120  func openBrowser(url string) bool { return browser.Open(url) }