aboutsummaryrefslogtreecommitdiff
path: root/src/pkg
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2011-09-06 12:24:24 -0400
committerRuss Cox <rsc@golang.org>2011-09-06 12:24:24 -0400
commit686181edfed0f738fe6aafe76fafded9d0be155b (patch)
tree765cb7944dc64b1bd5d8b2e1c075952240cae72c /src/pkg
parent5ddf6255a13c5a23663ca49db2d038c6530cb7a1 (diff)
downloadgo-686181edfed0f738fe6aafe76fafded9d0be155b.tar.xz
url: handle ; in ParseQuery
Most web frameworks allow ; as a synonym for &, following a recommendation in some versions of the HTML specification. Do the same. Remove overuse of Split. Move ParseQuery tests from package http to package url. Fixes #2210. R=golang-dev, r CC=golang-dev https://golang.org/cl/4973062
Diffstat (limited to 'src/pkg')
-rw-r--r--src/pkg/http/request_test.go51
-rw-r--r--src/pkg/url/url.go30
-rw-r--r--src/pkg/url/url_test.go62
3 files changed, 76 insertions, 67 deletions
diff --git a/src/pkg/http/request_test.go b/src/pkg/http/request_test.go
index 869cd57b69..175d6f170b 100644
--- a/src/pkg/http/request_test.go
+++ b/src/pkg/http/request_test.go
@@ -20,57 +20,6 @@ import (
"url"
)
-type stringMultimap map[string][]string
-
-type parseTest struct {
- query string
- out stringMultimap
-}
-
-var parseTests = []parseTest{
- {
- query: "a=1&b=2",
- out: stringMultimap{"a": []string{"1"}, "b": []string{"2"}},
- },
- {
- query: "a=1&a=2&a=banana",
- out: stringMultimap{"a": []string{"1", "2", "banana"}},
- },
- {
- query: "ascii=%3Ckey%3A+0x90%3E",
- out: stringMultimap{"ascii": []string{"<key: 0x90>"}},
- },
-}
-
-func TestParseForm(t *testing.T) {
- for i, test := range parseTests {
- form, err := url.ParseQuery(test.query)
- if err != nil {
- t.Errorf("test %d: Unexpected error: %v", i, err)
- continue
- }
- if len(form) != len(test.out) {
- t.Errorf("test %d: len(form) = %d, want %d", i, len(form), len(test.out))
- }
- for k, evs := range test.out {
- vs, ok := form[k]
- if !ok {
- t.Errorf("test %d: Missing key %q", i, k)
- continue
- }
- if len(vs) != len(evs) {
- t.Errorf("test %d: len(form[%q]) = %d, want %d", i, k, len(vs), len(evs))
- continue
- }
- for j, ev := range evs {
- if v := vs[j]; v != ev {
- t.Errorf("test %d: form[%q][%d] = %q, want %q", i, k, j, v, ev)
- }
- }
- }
- }
-}
-
func TestQuery(t *testing.T) {
req := &Request{Method: "GET"}
req.URL, _ = url.Parse("http://www.google.com/search?q=foo&q=bar")
diff --git a/src/pkg/url/url.go b/src/pkg/url/url.go
index d07b016118..9d193482ce 100644
--- a/src/pkg/url/url.go
+++ b/src/pkg/url/url.go
@@ -532,20 +532,28 @@ func ParseQuery(query string) (m Values, err os.Error) {
}
func parseQuery(m Values, query string) (err os.Error) {
- for _, kv := range strings.Split(query, "&") {
- if len(kv) == 0 {
+ for query != "" {
+ key := query
+ if i := strings.IndexAny(key, "&;"); i >= 0 {
+ key, query = key[:i], key[i+1:]
+ } else {
+ query = ""
+ }
+ if key == "" {
continue
}
- kvPair := strings.SplitN(kv, "=", 2)
-
- var key, value string
- var e os.Error
- key, e = QueryUnescape(kvPair[0])
- if e == nil && len(kvPair) > 1 {
- value, e = QueryUnescape(kvPair[1])
+ value := ""
+ if i := strings.Index(key, "="); i >= 0 {
+ key, value = key[:i], key[i+1:]
+ }
+ key, err1 := QueryUnescape(key)
+ if err1 != nil {
+ err = err1
+ continue
}
- if e != nil {
- err = e
+ value, err1 = QueryUnescape(value)
+ if err1 != nil {
+ err = err1
continue
}
m[key] = append(m[key], value)
diff --git a/src/pkg/url/url_test.go b/src/pkg/url/url_test.go
index af394d4fb4..8c27e18e1a 100644
--- a/src/pkg/url/url_test.go
+++ b/src/pkg/url/url_test.go
@@ -11,11 +11,6 @@ import (
"testing"
)
-// TODO(rsc):
-// test Unescape
-// test Escape
-// test Parse
-
type URLTest struct {
in string
out *URL
@@ -696,3 +691,60 @@ func TestQueryValues(t *testing.T) {
t.Errorf("second Get(bar) = %q, want %q", g, e)
}
}
+
+type parseTest struct {
+ query string
+ out Values
+}
+
+var parseTests = []parseTest{
+ {
+ query: "a=1&b=2",
+ out: Values{"a": []string{"1"}, "b": []string{"2"}},
+ },
+ {
+ query: "a=1&a=2&a=banana",
+ out: Values{"a": []string{"1", "2", "banana"}},
+ },
+ {
+ query: "ascii=%3Ckey%3A+0x90%3E",
+ out: Values{"ascii": []string{"<key: 0x90>"}},
+ },
+ {
+ query: "a=1;b=2",
+ out: Values{"a": []string{"1"}, "b": []string{"2"}},
+ },
+ {
+ query: "a=1&a=2;a=banana",
+ out: Values{"a": []string{"1", "2", "banana"}},
+ },
+}
+
+func TestParseQuery(t *testing.T) {
+ for i, test := range parseTests {
+ form, err := ParseQuery(test.query)
+ if err != nil {
+ t.Errorf("test %d: Unexpected error: %v", i, err)
+ continue
+ }
+ if len(form) != len(test.out) {
+ t.Errorf("test %d: len(form) = %d, want %d", i, len(form), len(test.out))
+ }
+ for k, evs := range test.out {
+ vs, ok := form[k]
+ if !ok {
+ t.Errorf("test %d: Missing key %q", i, k)
+ continue
+ }
+ if len(vs) != len(evs) {
+ t.Errorf("test %d: len(form[%q]) = %d, want %d", i, k, len(vs), len(evs))
+ continue
+ }
+ for j, ev := range evs {
+ if v := vs[j]; v != ev {
+ t.Errorf("test %d: form[%q][%d] = %q, want %q", i, k, j, v, ev)
+ }
+ }
+ }
+ }
+}