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