]> Cypherpunks repositories - gostls13.git/commitdiff
net/url: make URL implement encoding.BinaryMarshaler, BinaryUnmarshaler
authorRuss Cox <rsc@golang.org>
Wed, 19 Oct 2016 18:06:54 +0000 (14:06 -0400)
committerBrad Fitzpatrick <bradfitz@golang.org>
Sat, 22 Oct 2016 17:20:21 +0000 (17:20 +0000)
This makes it possible to use URLs with gob.

Ideally we'd also implement TextMarshaler and TextUnmarshaler,
but that would change the JSON encoding of a URL from something like:

{"Scheme":"https","Opaque":"","User":null,"Host":"www.google.com","Path":"/x","RawPath":"","ForceQuery":false,"RawQuery":"y=z","Fragment":""}

to something like:

"https://www.google.com/x?y=z"

That'd be nice, but it would break code expecting the old form.

Fixes #10964.

Change-Id: I83f06bc2bedd2ba8a5d8eef03ea0056d045c258f
Reviewed-on: https://go-review.googlesource.com/31467
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/net/url/url.go
src/net/url/url_test.go

index 525dbeee33e43f978c82f67b09ab2f06447c1b00..0931296468239a5c796bf69f7bf84b6c11e8ff7c 100644 (file)
@@ -1025,3 +1025,19 @@ func portOnly(hostport string) string {
        }
        return hostport[colon+len(":"):]
 }
+
+// Marshaling interface implementations.
+// Would like to implement MarshalText/UnmarshalText but that will change the JSON representation of URLs.
+
+func (u *URL) MarshalBinary() (text []byte, err error) {
+       return []byte(u.String()), nil
+}
+
+func (u *URL) UnmarshalBinary(text []byte) error {
+       u1, err := Parse(string(text))
+       if err != nil {
+               return err
+       }
+       *u = *u1
+       return nil
+}
index 344ecdcee4e4a321b891285fd4d11cb05aeb3e60..eebc1112c1552da10de1b7fc898175392133a3a7 100644 (file)
@@ -5,6 +5,10 @@
 package url
 
 import (
+       "bytes"
+       encodingPkg "encoding"
+       "encoding/gob"
+       "encoding/json"
        "fmt"
        "io"
        "net"
@@ -1624,3 +1628,54 @@ func TestURLPort(t *testing.T) {
                }
        }
 }
+
+var _ encodingPkg.BinaryMarshaler = (*URL)(nil)
+var _ encodingPkg.BinaryUnmarshaler = (*URL)(nil)
+
+func TestJSON(t *testing.T) {
+       u, err := Parse("https://www.google.com/x?y=z")
+       if err != nil {
+               t.Fatal(err)
+       }
+       js, err := json.Marshal(u)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // If only we could implement TextMarshaler/TextUnmarshaler,
+       // this would work:
+       //
+       // if string(js) != strconv.Quote(u.String()) {
+       //      t.Errorf("json encoding: %s\nwant: %s\n", js, strconv.Quote(u.String()))
+       // }
+
+       u1 := new(URL)
+       err = json.Unmarshal(js, u1)
+       if err != nil {
+               t.Fatal(err)
+       }
+       if u1.String() != u.String() {
+               t.Errorf("json decoded to: %s\nwant: %s\n", u1, u)
+       }
+}
+
+func TestGob(t *testing.T) {
+       u, err := Parse("https://www.google.com/x?y=z")
+       if err != nil {
+               t.Fatal(err)
+       }
+       var w bytes.Buffer
+       err = gob.NewEncoder(&w).Encode(u)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       u1 := new(URL)
+       err = gob.NewDecoder(&w).Decode(u1)
+       if err != nil {
+               t.Fatal(err)
+       }
+       if u1.String() != u.String() {
+               t.Errorf("json decoded to: %s\nwant: %s\n", u1, u)
+       }
+}