diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-07-22 18:15:38 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-07-22 18:15:38 +0000 |
commit | be239ed2ba619747b64629895116f209b58baee8 (patch) | |
tree | abdbd898676e1f853fca2d7e031d105d7ebcf676 /libgo/go/net/url | |
parent | 8f60bf3b0c426d469b5e65e1ad943e21ad42d957 (diff) | |
download | gcc-be239ed2ba619747b64629895116f209b58baee8.tar.gz |
libgo: update to go1.7rc3
Reviewed-on: https://go-review.googlesource.com/25150
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@238662 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go/net/url')
-rw-r--r-- | libgo/go/net/url/url.go | 65 | ||||
-rw-r--r-- | libgo/go/net/url/url_test.go | 39 |
2 files changed, 74 insertions, 30 deletions
diff --git a/libgo/go/net/url/url.go b/libgo/go/net/url/url.go index 1a93e3496ed..30e92779370 100644 --- a/libgo/go/net/url/url.go +++ b/libgo/go/net/url/url.go @@ -3,9 +3,13 @@ // license that can be found in the LICENSE file. // Package url parses URLs and implements query escaping. -// See RFC 3986. package url +// See RFC 3986. This package generally follows RFC 3986, except where +// it deviates for compatibility reasons. When sending changes, first +// search old issues for history on decisions. Unit tests should also +// contain references to issue numbers with details. + import ( "bytes" "errors" @@ -307,14 +311,15 @@ func escape(s string, mode encoding) string { // construct a URL struct directly and set the Opaque field instead of Path. // These still work as well. type URL struct { - Scheme string - Opaque string // encoded opaque data - User *Userinfo // username and password information - Host string // host or host:port - Path string - RawPath string // encoded path hint (Go 1.5 and later only; see EscapedPath method) - RawQuery string // encoded query values, without '?' - Fragment string // fragment for references, without '#' + Scheme string + Opaque string // encoded opaque data + User *Userinfo // username and password information + Host string // host or host:port + Path string + RawPath string // encoded path hint (Go 1.5 and later only; see EscapedPath method) + ForceQuery bool // append a query ('?') even if RawQuery is empty + RawQuery string // encoded query values, without '?' + Fragment string // fragment for references, without '#' } // User returns a Userinfo containing the provided username @@ -410,10 +415,11 @@ func split(s string, c string, cutc bool) (string, string) { // Parse parses rawurl into a URL structure. // The rawurl may be relative or absolute. -func Parse(rawurl string) (url *URL, err error) { +func Parse(rawurl string) (*URL, error) { // Cut off #frag u, frag := split(rawurl, "#", true) - if url, err = parse(u, false); err != nil { + url, err := parse(u, false) + if err != nil { return nil, err } if frag == "" { @@ -425,16 +431,16 @@ func Parse(rawurl string) (url *URL, err error) { return url, nil } -// ParseRequestURI parses rawurl into a URL structure. It assumes that +// ParseRequestURI parses rawurl into a URL structure. It assumes that // rawurl was received in an HTTP request, so the rawurl is interpreted // only as an absolute URI or an absolute path. // The string rawurl is assumed not to have a #fragment suffix. // (Web browsers strip #fragment before sending the URL to a web server.) -func ParseRequestURI(rawurl string) (url *URL, err error) { +func ParseRequestURI(rawurl string) (*URL, error) { return parse(rawurl, true) } -// parse parses a URL from a string in one of two contexts. If +// parse parses a URL from a string in one of two contexts. If // viaRequest is true, the URL is assumed to have arrived via an HTTP request, // in which case only absolute URLs or path-absolute relative URLs are allowed. // If viaRequest is false, all forms of relative URLs are allowed. @@ -459,7 +465,12 @@ func parse(rawurl string, viaRequest bool) (url *URL, err error) { } url.Scheme = strings.ToLower(url.Scheme) - rest, url.RawQuery = split(rest, "?", true) + if strings.HasSuffix(rest, "?") && strings.Count(rest, "?") == 1 { + url.ForceQuery = true + rest = rest[:len(rest)-1] + } else { + rest, url.RawQuery = split(rest, "?", true) + } if !strings.HasPrefix(rest, "/") { if url.Scheme != "" { @@ -511,7 +522,7 @@ func parseAuthority(authority string) (user *Userinfo, host string, err error) { return nil, host, nil } userinfo := authority[:i] - if strings.Index(userinfo, ":") < 0 { + if !strings.Contains(userinfo, ":") { if userinfo, err = unescape(userinfo, encodeUserPassword); err != nil { return nil, "", err } @@ -684,7 +695,7 @@ func (u *URL) String() string { } buf.WriteString(path) } - if u.RawQuery != "" { + if u.ForceQuery || u.RawQuery != "" { buf.WriteByte('?') buf.WriteString(u.RawQuery) } @@ -709,8 +720,8 @@ func (v Values) Get(key string) string { if v == nil { return "" } - vs, ok := v[key] - if !ok || len(vs) == 0 { + vs := v[key] + if len(vs) == 0 { return "" } return vs[0] @@ -738,10 +749,10 @@ func (v Values) Del(key string) { // ParseQuery always returns a non-nil map containing all the // valid query parameters found; err describes the first decoding error // encountered, if any. -func ParseQuery(query string) (m Values, err error) { - m = make(Values) - err = parseQuery(m, query) - return +func ParseQuery(query string) (Values, error) { + m := make(Values) + err := parseQuery(m, query) + return m, err } func parseQuery(m Values, query string) (err error) { @@ -845,8 +856,8 @@ func (u *URL) IsAbs() bool { return u.Scheme != "" } -// Parse parses a URL in the context of the receiver. The provided URL -// may be relative or absolute. Parse returns nil, err on parse +// Parse parses a URL in the context of the receiver. The provided URL +// may be relative or absolute. Parse returns nil, err on parse // failure, otherwise its return value is the same as ResolveReference. func (u *URL) Parse(ref string) (*URL, error) { refurl, err := Parse(ref) @@ -858,7 +869,7 @@ func (u *URL) Parse(ref string) (*URL, error) { // ResolveReference resolves a URI reference to an absolute URI from // an absolute base URI, per RFC 3986 Section 5.2. The URI reference -// may be relative or absolute. ResolveReference always returns a new +// may be relative or absolute. ResolveReference always returns a new // URL instance, even if the returned URL is identical to either the // base or reference. If ref is an absolute URL, then ResolveReference // ignores base and returns a copy of ref. @@ -913,7 +924,7 @@ func (u *URL) RequestURI() string { result = u.Scheme + ":" + result } } - if u.RawQuery != "" { + if u.ForceQuery || u.RawQuery != "" { result += "?" + u.RawQuery } return result diff --git a/libgo/go/net/url/url_test.go b/libgo/go/net/url/url_test.go index d3f8487bd7c..7560f22c4a1 100644 --- a/libgo/go/net/url/url_test.go +++ b/libgo/go/net/url/url_test.go @@ -72,6 +72,28 @@ var urltests = []URLTest{ }, "ftp://john%20doe@www.google.com/", }, + // empty query + { + "http://www.google.com/?", + &URL{ + Scheme: "http", + Host: "www.google.com", + Path: "/", + ForceQuery: true, + }, + "", + }, + // query ending in question mark (Issue 14573) + { + "http://www.google.com/?foo=bar?", + &URL{ + Scheme: "http", + Host: "www.google.com", + Path: "/", + RawQuery: "foo=bar?", + }, + "", + }, // query { "http://www.google.com/?q=go+language", @@ -553,8 +575,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", - u.Opaque, u.Scheme, user, pass, u.Host, u.Path, u.RawPath, u.RawQuery, u.Fragment) + return fmt.Sprintf("opaque=%q, scheme=%q, user=%#v, pass=%#v, host=%q, path=%q, rawpath=%q, rawq=%q, frag=%q, forcequery=%v", + u.Opaque, u.Scheme, user, pass, u.Host, u.Path, u.RawPath, u.RawQuery, u.Fragment, u.ForceQuery) } func DoTest(t *testing.T, parse func(string) (*URL, error), name string, tests []URLTest) { @@ -589,7 +611,7 @@ func BenchmarkString(b *testing.B) { g = u.String() } b.StopTimer() - if w := tt.roundtrip; g != w { + if w := tt.roundtrip; b.N > 0 && g != w { b.Errorf("Parse(%q).String() == %q, want %q", tt.in, g, w) } } @@ -874,11 +896,13 @@ var resolveReferenceTests = []struct { // Absolute URL references {"http://foo.com?a=b", "https://bar.com/", "https://bar.com/"}, {"http://foo.com/", "https://bar.com/?a=b", "https://bar.com/?a=b"}, + {"http://foo.com/", "https://bar.com/?", "https://bar.com/?"}, {"http://foo.com/bar", "mailto:foo@example.com", "mailto:foo@example.com"}, // Path-absolute references {"http://foo.com/bar", "/baz", "http://foo.com/baz"}, {"http://foo.com/bar?a=b#f", "/baz", "http://foo.com/baz"}, + {"http://foo.com/bar?a=b", "/baz?", "http://foo.com/baz?"}, {"http://foo.com/bar?a=b", "/baz?c=d", "http://foo.com/baz?c=d"}, // Scheme-relative @@ -1217,6 +1241,15 @@ var requritests = []RequestURITest{ }, "//foo", }, + { + &URL{ + Scheme: "http", + Host: "example.com", + Path: "/foo", + ForceQuery: true, + }, + "/foo?", + }, } func TestRequestURI(t *testing.T) { |