summaryrefslogtreecommitdiff
path: root/src/pkg/http/client.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/http/client.go')
-rw-r--r--src/pkg/http/client.go95
1 files changed, 4 insertions, 91 deletions
diff --git a/src/pkg/http/client.go b/src/pkg/http/client.go
index af11a4b74..24758eee1 100644
--- a/src/pkg/http/client.go
+++ b/src/pkg/http/client.go
@@ -13,49 +13,9 @@ import (
"io"
"net"
"os"
- "strconv"
"strings"
)
-// Response represents the response from an HTTP request.
-type Response struct {
- Status string // e.g. "200 OK"
- StatusCode int // e.g. 200
-
- // Header maps header keys to values. If the response had multiple
- // headers with the same key, they will be concatenated, with comma
- // delimiters. (Section 4.2 of RFC 2616 requires that multiple headers
- // be semantically equivalent to a comma-delimited sequence.)
- //
- // Keys in the map are canonicalized (see CanonicalHeaderKey).
- Header map[string]string
-
- // Stream from which the response body can be read.
- Body io.ReadCloser
-}
-
-// GetHeader returns the value of the response header with the given
-// key, and true. If there were multiple headers with this key, their
-// values are concatenated, with a comma delimiter. If there were no
-// response headers with the given key, it returns the empty string and
-// false. Keys are not case sensitive.
-func (r *Response) GetHeader(key string) (value string) {
- value, _ = r.Header[CanonicalHeaderKey(key)]
- return
-}
-
-// AddHeader adds a value under the given key. Keys are not case sensitive.
-func (r *Response) AddHeader(key, value string) {
- key = CanonicalHeaderKey(key)
-
- oldValues, oldValuesPresent := r.Header[key]
- if oldValuesPresent {
- r.Header[key] = oldValues + "," + value
- } else {
- r.Header[key] = value
- }
-}
-
// Given a string of the form "host", "host:port", or "[ipv6::address]:port",
// return true if the string includes a port.
func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") }
@@ -68,43 +28,6 @@ type readClose struct {
io.Closer
}
-// ReadResponse reads and returns an HTTP response from r.
-func ReadResponse(r *bufio.Reader) (*Response, os.Error) {
- resp := new(Response)
-
- // Parse the first line of the response.
- resp.Header = make(map[string]string)
-
- line, err := readLine(r)
- if err != nil {
- return nil, err
- }
- f := strings.Split(line, " ", 3)
- if len(f) < 3 {
- 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, &badStringError{"malformed HTTP status code", f[1]}
- }
-
- // Parse the response headers.
- for {
- key, value, err := readKeyValue(r)
- if err != nil {
- return nil, err
- }
- if key == "" {
- break // end of response header
- }
- resp.AddHeader(key, value)
- }
-
- return resp, nil
-}
-
-
// Send issues an HTTP request. Caller should close resp.Body when done reading it.
//
// TODO: support persistent connections (multiple requests on a single connection).
@@ -141,23 +64,13 @@ func send(req *Request) (resp *Response, err os.Error) {
}
reader := bufio.NewReader(conn)
- resp, err = ReadResponse(reader)
+ resp, err = ReadResponse(reader, req.Method)
if err != nil {
conn.Close()
return nil, err
}
- r := io.Reader(reader)
- if v := resp.GetHeader("Transfer-Encoding"); v == "chunked" {
- r = newChunkedReader(reader)
- } else if v := resp.GetHeader("Content-Length"); v != "" {
- n, err := strconv.Atoi64(v)
- if err != nil {
- return nil, &badStringError{"invalid Content-Length", v}
- }
- r = io.LimitReader(r, n)
- }
- resp.Body = readClose{r, conn}
+ resp.Body = readClose{resp.Body, conn}
return
}
@@ -180,8 +93,8 @@ func shouldRedirect(statusCode int) bool {
// 303 (See Other)
// 307 (Temporary Redirect)
//
-// finalURL is the URL from which the response was fetched -- identical to the input
-// URL unless redirects were followed.
+// finalURL is the URL from which the response was fetched -- identical to the
+// input 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) {