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 | } |
81 |
Members