summaryrefslogtreecommitdiff
path: root/src/cmd/go/http.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/go/http.go')
-rw-r--r--src/cmd/go/http.go52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/cmd/go/http.go b/src/cmd/go/http.go
index 8d9b2a165..6de9a3e1e 100644
--- a/src/cmd/go/http.go
+++ b/src/cmd/go/http.go
@@ -13,8 +13,11 @@ package main
import (
"fmt"
+ "io"
"io/ioutil"
+ "log"
"net/http"
+ "net/url"
)
// httpGET returns the data from an HTTP GET request for the given URL.
@@ -33,3 +36,52 @@ func httpGET(url string) ([]byte, error) {
}
return b, nil
}
+
+// httpClient is the default HTTP client, but a variable so it can be
+// changed by tests, without modifying http.DefaultClient.
+var httpClient = http.DefaultClient
+
+// httpsOrHTTP returns the body of either the importPath's
+// https resource or, if unavailable, the http resource.
+func httpsOrHTTP(importPath string) (urlStr string, body io.ReadCloser, err error) {
+ fetch := func(scheme string) (urlStr string, res *http.Response, err error) {
+ u, err := url.Parse(scheme + "://" + importPath)
+ if err != nil {
+ return "", nil, err
+ }
+ u.RawQuery = "go-get=1"
+ urlStr = u.String()
+ if buildV {
+ log.Printf("Fetching %s", urlStr)
+ }
+ res, err = httpClient.Get(urlStr)
+ return
+ }
+ closeBody := func(res *http.Response) {
+ if res != nil {
+ res.Body.Close()
+ }
+ }
+ urlStr, res, err := fetch("https")
+ if err != nil || res.StatusCode != 200 {
+ if buildV {
+ if err != nil {
+ log.Printf("https fetch failed.")
+ } else {
+ log.Printf("ignoring https fetch with status code %d", res.StatusCode)
+ }
+ }
+ closeBody(res)
+ urlStr, res, err = fetch("http")
+ }
+ if err != nil {
+ closeBody(res)
+ return "", nil, err
+ }
+ // Note: accepting a non-200 OK here, so people can serve a
+ // meta import in their http 404 page.
+ if buildV {
+ log.Printf("Parsing meta tags from %s (status code %d)", urlStr, res.StatusCode)
+ }
+ return urlStr, res.Body, nil
+}