summaryrefslogtreecommitdiff
path: root/src/pkg/http/response.go
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-06-30 15:34:22 +0200
committerOndřej Surý <ondrej@sury.org>2011-06-30 15:34:22 +0200
commitd39f5aa373a4422f7a5f3ee764fb0f6b0b719d61 (patch)
tree1833f8b72a4b3a8f00d0d143b079a8fcad01c6ae /src/pkg/http/response.go
parent8652e6c371b8905498d3d314491d36c58d5f68d5 (diff)
downloadgolang-upstream/58.tar.gz
Imported Upstream version 58upstream/58
Diffstat (limited to 'src/pkg/http/response.go')
-rw-r--r--src/pkg/http/response.go57
1 files changed, 18 insertions, 39 deletions
diff --git a/src/pkg/http/response.go b/src/pkg/http/response.go
index 1f725ecdd..42e60c1f6 100644
--- a/src/pkg/http/response.go
+++ b/src/pkg/http/response.go
@@ -8,11 +8,9 @@ package http
import (
"bufio"
- "fmt"
"io"
"net/textproto"
"os"
- "sort"
"strconv"
"strings"
)
@@ -32,10 +30,6 @@ type Response struct {
ProtoMajor int // e.g. 1
ProtoMinor int // e.g. 0
- // RequestMethod records the method used in the HTTP request.
- // Header fields such as Content-Length have method-specific meaning.
- RequestMethod string // e.g. "HEAD", "CONNECT", "GET", etc.
-
// 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
@@ -70,19 +64,26 @@ type Response struct {
// Trailer maps trailer keys to values, in the same
// format as the header.
Trailer Header
+
+ // The Request that was sent to obtain this Response.
+ // Request's Body is nil (having already been consumed).
+ // This is only populated for Client requests.
+ Request *Request
}
-// ReadResponse reads and returns an HTTP response from r. The RequestMethod
-// parameter specifies the method used in the corresponding request (e.g.,
-// "GET", "HEAD"). Clients must call resp.Body.Close when finished reading
-// resp.Body. After that call, clients can inspect resp.Trailer to find
-// key/value pairs included in the response trailer.
-func ReadResponse(r *bufio.Reader, requestMethod string) (resp *Response, err os.Error) {
+// ReadResponse reads and returns an HTTP response from r. The
+// req parameter specifies the Request that corresponds to
+// this Response. Clients must call resp.Body.Close when finished
+// reading resp.Body. After that call, clients can inspect
+// resp.Trailer to find key/value pairs included in the response
+// trailer.
+func ReadResponse(r *bufio.Reader, req *Request) (resp *Response, err os.Error) {
tp := textproto.NewReader(r)
resp = new(Response)
- resp.RequestMethod = strings.ToUpper(requestMethod)
+ resp.Request = req
+ resp.Request.Method = strings.ToUpper(resp.Request.Method)
// Parse the first line of the response.
line, err := tp.ReadLine()
@@ -166,7 +167,9 @@ func (r *Response) ProtoAtLeast(major, minor int) bool {
func (resp *Response) Write(w io.Writer) os.Error {
// RequestMethod should be upper-case
- resp.RequestMethod = strings.ToUpper(resp.RequestMethod)
+ if resp.Request != nil {
+ resp.Request.Method = strings.ToUpper(resp.Request.Method)
+ }
// Status line
text := resp.Status
@@ -192,7 +195,7 @@ func (resp *Response) Write(w io.Writer) os.Error {
}
// Rest of header
- err = writeSortedHeader(w, resp.Header, respExcludeHeader)
+ err = resp.Header.WriteSubset(w, respExcludeHeader)
if err != nil {
return err
}
@@ -213,27 +216,3 @@ func (resp *Response) Write(w io.Writer) os.Error {
// Success
return nil
}
-
-func writeSortedHeader(w io.Writer, h Header, exclude map[string]bool) os.Error {
- keys := make([]string, 0, len(h))
- for k := range h {
- if exclude == nil || !exclude[k] {
- keys = append(keys, k)
- }
- }
- sort.SortStrings(keys)
- for _, k := range keys {
- for _, v := range h[k] {
- v = strings.Replace(v, "\n", " ", -1)
- v = strings.Replace(v, "\r", " ", -1)
- v = strings.TrimSpace(v)
- if v == "" {
- continue
- }
- if _, err := fmt.Fprintf(w, "%s: %s\r\n", k, v); err != nil {
- return err
- }
- }
- }
- return nil
-}