summaryrefslogtreecommitdiff
path: root/src/pkg/http/request.go
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-06-10 10:59:18 +0200
committerOndřej Surý <ondrej@sury.org>2011-06-10 10:59:18 +0200
commitc29cace1e8f3260389ea78fa4ef86d80cd5e5275 (patch)
tree947e4435053998a194caacab99bf614d8fd5bc78 /src/pkg/http/request.go
parent56135c623a865c501ab31cc940c0e22ece2673f4 (diff)
downloadgolang-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.go67
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)
}