diff options
| author | Ondřej Surý <ondrej@sury.org> | 2011-06-10 10:59:18 +0200 |
|---|---|---|
| committer | Ondřej Surý <ondrej@sury.org> | 2011-06-10 10:59:18 +0200 |
| commit | c29cace1e8f3260389ea78fa4ef86d80cd5e5275 (patch) | |
| tree | 947e4435053998a194caacab99bf614d8fd5bc78 /src/pkg/http/request.go | |
| parent | 56135c623a865c501ab31cc940c0e22ece2673f4 (diff) | |
| download | golang-c29cace1e8f3260389ea78fa4ef86d80cd5e5275.tar.gz | |
Imported Upstream version 2011.06.09upstream-weekly/2011.06.09
Diffstat (limited to 'src/pkg/http/request.go')
| -rw-r--r-- | src/pkg/http/request.go | 67 |
1 files changed, 55 insertions, 12 deletions
diff --git a/src/pkg/http/request.go b/src/pkg/http/request.go index 2f6b651c3..bdc3a7e4f 100644 --- a/src/pkg/http/request.go +++ b/src/pkg/http/request.go @@ -90,10 +90,10 @@ type Request struct { // // then // - // Header = map[string]string{ - // "Accept-Encoding": "gzip, deflate", - // "Accept-Language": "en-us", - // "Connection": "keep-alive", + // Header = map[string][]string{ + // "Accept-Encoding": {"gzip, deflate"}, + // "Accept-Language": {"en-us"}, + // "Connection": {"keep-alive"}, // } // // HTTP defines that header names are case-insensitive. @@ -141,7 +141,7 @@ type Request struct { UserAgent string // The parsed form. Only available after ParseForm is called. - Form map[string][]string + Form Values // The parsed multipart form, including file uploads. // Only available after ParseMultipartForm is called. @@ -238,9 +238,9 @@ const defaultUserAgent = "Go http package" // TransferEncoding // Body // -// If Body is present but Content-Length is <= 0, Write adds -// "Transfer-Encoding: chunked" to the header. Body is closed after -// it is sent. +// If Body is present, Content-Length is <= 0 and TransferEncoding +// hasn't been set to "identity", Write adds "Transfer-Encoding: +// chunked" to the header. Body is closed after it is sent. func (req *Request) Write(w io.Writer) os.Error { return req.write(w, false) } @@ -488,6 +488,11 @@ func NewRequest(method, url string, body io.Reader) (*Request, os.Error) { default: req.ContentLength = -1 // chunked } + if req.ContentLength == 0 { + // To prevent chunking and disambiguate this + // from the default ContentLength zero value. + req.TransferEncoding = []string{"identity"} + } } return req, nil @@ -597,18 +602,56 @@ func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) { return req, nil } +// Values maps a string key to a list of values. +// It is typically used for query parameters and form values. +// Unlike in the Header map, the keys in a Values map +// are case-sensitive. +type Values map[string][]string + +// Get gets the first value associated with the given key. +// If there are no values associated with the key, Get returns +// the empty string. To access multiple values, use the map +// directly. +func (v Values) Get(key string) string { + if v == nil { + return "" + } + vs, ok := v[key] + if !ok || len(vs) == 0 { + return "" + } + return vs[0] +} + +// Set sets the key to value. It replaces any existing +// values. +func (v Values) Set(key, value string) { + v[key] = []string{value} +} + +// Add adds the key to value. It appends to any existing +// values associated with key. +func (v Values) Add(key, value string) { + v[key] = append(v[key], value) +} + +// Del deletes the values associated with key. +func (v Values) Del(key string) { + v[key] = nil, false +} + // ParseQuery parses the URL-encoded query string and returns // a map listing the values specified for each key. // ParseQuery always returns a non-nil map containing all the // valid query parameters found; err describes the first decoding error // encountered, if any. -func ParseQuery(query string) (m map[string][]string, err os.Error) { - m = make(map[string][]string) +func ParseQuery(query string) (m Values, err os.Error) { + m = make(Values) err = parseQuery(m, query) return } -func parseQuery(m map[string][]string, query string) (err os.Error) { +func parseQuery(m Values, query string) (err os.Error) { for _, kv := range strings.Split(query, "&", -1) { if len(kv) == 0 { continue @@ -641,7 +684,7 @@ func (r *Request) ParseForm() (err os.Error) { return } - r.Form = make(map[string][]string) + r.Form = make(Values) if r.URL != nil { err = parseQuery(r.Form, r.URL.RawQuery) } |
