summaryrefslogtreecommitdiff
path: root/libgo/go/net/url
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2016-07-22 18:15:38 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2016-07-22 18:15:38 +0000
commitbe239ed2ba619747b64629895116f209b58baee8 (patch)
treeabdbd898676e1f853fca2d7e031d105d7ebcf676 /libgo/go/net/url
parent8f60bf3b0c426d469b5e65e1ad943e21ad42d957 (diff)
downloadgcc-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.go65
-rw-r--r--libgo/go/net/url/url_test.go39
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) {