Skip to content

Commit

Permalink
net/url: add OmitHost bool to url.URL
Browse files Browse the repository at this point in the history
Previously, myscheme:/path and myscheme:///path were treated as the same URL
although materially different. The distinction made clear by RFC 3986 sec. 5.3 where
a different recomposition behavior is expected when a URI reference has an undefined
host(authority) as in myscheme:/path vs. one with an empty host(authority)
as in myscheme:///path.

This change fixes the Parse/String roundtrip limitation for URLs with an undefined
host and a single slash.

Fixes #46059

Change-Id: I1b8d6042135513616374ff8c8dfb1cdb640f8efe
Reviewed-on: https://go-review.googlesource.com/c/go/+/391294
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
  • Loading branch information
willpoint authored and odeke-em committed Mar 14, 2022
1 parent 3c2e73c commit ab0f761
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 15 deletions.
28 changes: 19 additions & 9 deletions src/net/url/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ type URL struct {
Host string // host or host:port
Path string // path (relative paths may omit leading slash)
RawPath string // encoded path hint (see EscapedPath method)
OmitHost bool // do not emit empty host (authority)
ForceQuery bool // append a query ('?') even if RawQuery is empty
RawQuery string // encoded query values, without '?'
Fragment string // fragment for references, without '#'
Expand Down Expand Up @@ -556,7 +557,12 @@ func parse(rawURL string, viaRequest bool) (*URL, error) {
if err != nil {
return nil, err
}
} else if url.Scheme != "" && strings.HasPrefix(rest, "/") {
// OmitHost is set to true when rawURL has an empty host (authority).
// See golang.org/issue/46059.
url.OmitHost = true
}

// Set Path and, optionally, RawPath.
// RawPath is a hint of the encoding of Path. We don't want to set it if
// the default escaping of Path is equivalent, to help make sure that people
Expand Down Expand Up @@ -806,15 +812,19 @@ func (u *URL) String() string {
buf.WriteString(u.Opaque)
} else {
if u.Scheme != "" || u.Host != "" || u.User != nil {
if u.Host != "" || u.Path != "" || u.User != nil {
buf.WriteString("//")
}
if ui := u.User; ui != nil {
buf.WriteString(ui.String())
buf.WriteByte('@')
}
if h := u.Host; h != "" {
buf.WriteString(escape(h, encodeHost))
if u.OmitHost && u.Host == "" && u.User == nil {
// omit empty host
} else {
if u.Host != "" || u.Path != "" || u.User != nil {
buf.WriteString("//")
}
if ui := u.User; ui != nil {
buf.WriteString(ui.String())
buf.WriteByte('@')
}
if h := u.Host; h != "" {
buf.WriteString(escape(h, encodeHost))
}
}
}
path := u.EscapedPath()
Expand Down
13 changes: 7 additions & 6 deletions src/net/url/url_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,15 @@ var urltests = []URLTest{
},
"http:%2f%2fwww.google.com/?q=go+language",
},
// non-authority with path
// non-authority with path; see golang.org/issue/46059
{
"mailto:/webmaster@golang.org",
&URL{
Scheme: "mailto",
Path: "/webmaster@golang.org",
Scheme: "mailto",
Path: "/webmaster@golang.org",
OmitHost: true,
},
"mailto:///webmaster@golang.org", // unfortunate compromise
"",
},
// non-authority
{
Expand Down Expand Up @@ -625,8 +626,8 @@ func ufmt(u *URL) string {
pass = p
}
}
return fmt.Sprintf("opaque=%q, scheme=%q, user=%#v, pass=%#v, host=%q, path=%q, rawpath=%q, rawq=%q, frag=%q, rawfrag=%q, forcequery=%v",
u.Opaque, u.Scheme, user, pass, u.Host, u.Path, u.RawPath, u.RawQuery, u.Fragment, u.RawFragment, u.ForceQuery)
return fmt.Sprintf("opaque=%q, scheme=%q, user=%#v, pass=%#v, host=%q, path=%q, rawpath=%q, rawq=%q, frag=%q, rawfrag=%q, forcequery=%v, omithost=%t",
u.Opaque, u.Scheme, user, pass, u.Host, u.Path, u.RawPath, u.RawQuery, u.Fragment, u.RawFragment, u.ForceQuery, u.OmitHost)
}

func BenchmarkString(b *testing.B) {
Expand Down

0 comments on commit ab0f761

Please sign in to comment.