diff options
Diffstat (limited to 'src/pkg/http/client.go')
-rw-r--r-- | src/pkg/http/client.go | 48 |
1 files changed, 25 insertions, 23 deletions
diff --git a/src/pkg/http/client.go b/src/pkg/http/client.go index 8c17eb8e3..14131ec8e 100644 --- a/src/pkg/http/client.go +++ b/src/pkg/http/client.go @@ -78,7 +78,7 @@ type readClose struct { // connections, it may no longer make sense to have a method with this signature. func send(req *Request) (resp *Response, err os.Error) { if req.Url.Scheme != "http" { - return nil, os.ErrorString("Unsupported protocol: " + req.Url.Scheme); + return nil, &badStringError{"unsupported protocol scheme", req.Url.Scheme}; } addr := req.Url.Host; @@ -87,7 +87,7 @@ func send(req *Request) (resp *Response, err os.Error) { } conn, err := net.Dial("tcp", "", addr); if err != nil { - return nil, os.ErrorString("Error dialing " + addr + ": " + err.String()); + return nil, err; } // Close the connection if we encounter an error during header parsing. We'll @@ -110,12 +110,12 @@ func send(req *Request) (resp *Response, err os.Error) { } f := strings.Split(line, " ", 3); if len(f) < 3 { - return nil, os.ErrorString(fmt.Sprintf("Invalid first line in HTTP response: %q", line)); + return nil, &badStringError{"malformed HTTP response", line}; } resp.Status = f[1] + " " + f[2]; resp.StatusCode, err = strconv.Atoi(f[1]); if err != nil { - return nil, os.ErrorString(fmt.Sprintf("Invalid status code in HTTP response: %q", line)); + return nil, &badStringError{"malformed HTTP status code", f[1]}; } // Parse the response headers. @@ -165,34 +165,36 @@ func shouldRedirect(statusCode int) bool { // URL unless redirects were followed. // // Caller should close r.Body when done reading it. -func Get(url string) (r *Response, finalUrl string, err os.Error) { +func Get(url string) (r *Response, finalURL string, err os.Error) { // TODO: if/when we add cookie support, the redirected request shouldn't // necessarily supply the same cookies as the original. - // TODO: adjust referrer header on redirects. - for redirectCount := 0; redirectCount < 10; redirectCount++ { - var req Request; - req.Url, err = ParseURL(url); - if err != nil { - return nil, url, err; + // TODO: set referrer header on redirects. + for redirect := 0;; redirect++ { + if redirect >= 10 { + err = os.ErrorString("stopped after 10 redirects"); + break; } - r, err := send(&req); - if err != nil { - return nil, url, err; + var req Request; + if req.Url, err = ParseURL(url); err != nil { + break; } - - if !shouldRedirect(r.StatusCode) { - return r, url, nil; + if r, err = send(&req); err != nil { + break; } - - r.Body.Close(); - url := r.GetHeader("Location"); - if url == "" { - return r, url, os.ErrorString("302 result with no Location header"); + if shouldRedirect(r.StatusCode) { + r.Body.Close(); + if url = r.GetHeader("Location"); url == "" { + err = os.ErrorString(fmt.Sprintf("%d response missing Location header", r.StatusCode)); + break; + } } + finalURL = url; + return; } - return nil, url, os.ErrorString("Too many redirects"); + err = &URLError{"Get", url, err}; + return; } |