github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/vndr/godl/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 godl 6 7 import ( 8 "fmt" 9 "io" 10 "io/ioutil" 11 "net/http" 12 "net/url" 13 "time" 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 var impatientHTTPClient = &http.Client{ 20 Timeout: time.Duration(5 * time.Second), 21 } 22 23 type httpError struct { 24 status string 25 statusCode int 26 url string 27 } 28 29 func (e *httpError) Error() string { 30 return fmt.Sprintf("%s: %s", e.url, e.status) 31 } 32 33 // httpGET returns the data from an HTTP GET request for the given URL. 34 func httpGET(url string) ([]byte, error) { 35 resp, err := httpClient.Get(url) 36 if err != nil { 37 return nil, err 38 } 39 defer resp.Body.Close() 40 if resp.StatusCode != 200 { 41 err := &httpError{status: resp.Status, statusCode: resp.StatusCode, url: url} 42 43 return nil, err 44 } 45 b, err := ioutil.ReadAll(resp.Body) 46 if err != nil { 47 return nil, fmt.Errorf("%s: %v", url, err) 48 } 49 return b, nil 50 } 51 52 // httpsOrHTTP returns the body of either the importPath's 53 // https resource or, if unavailable, the http resource. 54 func httpsOrHTTP(importPath string, security securityMode) (urlStr string, body io.ReadCloser, err error) { 55 fetch := func(scheme string) (urlStr string, res *http.Response, err error) { 56 u, err := url.Parse(scheme + "://" + importPath) 57 if err != nil { 58 return "", nil, err 59 } 60 u.RawQuery = "go-get=1" 61 urlStr = u.String() 62 if security == insecure && scheme == "https" { // fail earlier 63 res, err = impatientHTTPClient.Get(urlStr) 64 } else { 65 res, err = httpClient.Get(urlStr) 66 } 67 return 68 } 69 closeBody := func(res *http.Response) { 70 if res != nil { 71 res.Body.Close() 72 } 73 } 74 urlStr, res, err := fetch("https") 75 if err != nil { 76 if security == insecure { 77 closeBody(res) 78 urlStr, res, err = fetch("http") 79 } 80 } 81 if err != nil { 82 closeBody(res) 83 return "", nil, err 84 } 85 // Note: accepting a non-200 OK here, so people can serve a 86 // meta import in their http 404 page. 87 return urlStr, res.Body, nil 88 }