]> Cypherpunks repositories - gostls13.git/commitdiff
url: handle ; in ParseQuery
authorRuss Cox <rsc@golang.org>
Tue, 6 Sep 2011 16:24:24 +0000 (12:24 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 6 Sep 2011 16:24:24 +0000 (12:24 -0400)
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

src/pkg/http/request_test.go
src/pkg/url/url.go
src/pkg/url/url_test.go

index 869cd57b696858cb7daa4583674955beb6adcb78..175d6f170b831ee3ac7ff51660dfe7c949b46c34 100644 (file)
@@ -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")
index d07b016118fb387bea9974b80ba28fb768414097..9d193482ce4d3d05c559ffd83af3021977e66f27 100644 (file)
@@ -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)
index af394d4fb4a0094dbdbbe426c3b8e10f9d8f091d..8c27e18e1aa19854fd57ca01b20e395c1d2084f8 100644 (file)
@@ -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)
+                               }
+                       }
+               }
+       }
+}