1
0
mirror of https://github.com/golang/go synced 2024-11-18 06:04:53 -07:00

net/url: make URL implement encoding.BinaryMarshaler, BinaryUnmarshaler

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>
This commit is contained in:
Russ Cox 2016-10-19 14:06:54 -04:00 committed by Brad Fitzpatrick
parent 6eae03e136
commit 6595709154
2 changed files with 71 additions and 0 deletions

View 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
}

View 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)
}
}