github.com/bgentry/go@v0.0.0-20150121062915-6cf5a733d54d/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  	"fmt"
    16  	"io"
    17  	"io/ioutil"
    18  	"log"
    19  	"net/http"
    20  	"net/url"
    21  )
    22  
    23  // httpClient is the default HTTP client, but a variable so it can be
    24  // changed by tests, without modifying http.DefaultClient.
    25  var httpClient = http.DefaultClient
    26  
    27  // httpGET returns the data from an HTTP GET request for the given URL.
    28  func httpGET(url string) ([]byte, error) {
    29  	resp, err := httpClient.Get(url)
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  	defer resp.Body.Close()
    34  	if resp.StatusCode != 200 {
    35  		return nil, fmt.Errorf("%s: %s", url, resp.Status)
    36  	}
    37  	b, err := ioutil.ReadAll(resp.Body)
    38  	if err != nil {
    39  		return nil, fmt.Errorf("%s: %v", url, err)
    40  	}
    41  	return b, nil
    42  }
    43  
    44  // httpsOrHTTP returns the body of either the importPath's
    45  // https resource or, if unavailable, the http resource.
    46  func httpsOrHTTP(importPath string) (urlStr string, body io.ReadCloser, err error) {
    47  	fetch := func(scheme string) (urlStr string, res *http.Response, err error) {
    48  		u, err := url.Parse(scheme + "://" + importPath)
    49  		if err != nil {
    50  			return "", nil, err
    51  		}
    52  		u.RawQuery = "go-get=1"
    53  		urlStr = u.String()
    54  		if buildV {
    55  			log.Printf("Fetching %s", urlStr)
    56  		}
    57  		res, err = httpClient.Get(urlStr)
    58  		return
    59  	}
    60  	closeBody := func(res *http.Response) {
    61  		if res != nil {
    62  			res.Body.Close()
    63  		}
    64  	}
    65  	urlStr, res, err := fetch("https")
    66  	if err != nil || res.StatusCode != 200 {
    67  		if buildV {
    68  			if err != nil {
    69  				log.Printf("https fetch failed.")
    70  			} else {
    71  				log.Printf("ignoring https fetch with status code %d", res.StatusCode)
    72  			}
    73  		}
    74  		closeBody(res)
    75  		urlStr, res, err = fetch("http")
    76  	}
    77  	if err != nil {
    78  		closeBody(res)
    79  		return "", nil, err
    80  	}
    81  	// Note: accepting a non-200 OK here, so people can serve a
    82  	// meta import in their http 404 page.
    83  	if buildV {
    84  		log.Printf("Parsing meta tags from %s (status code %d)", urlStr, res.StatusCode)
    85  	}
    86  	return urlStr, res.Body, nil
    87  }