aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/net/url/url.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/net/url/url.go')
-rw-r--r--libgo/go/net/url/url.go90
1 files changed, 55 insertions, 35 deletions
diff --git a/libgo/go/net/url/url.go b/libgo/go/net/url/url.go
index d90f5f0..20de0f6 100644
--- a/libgo/go/net/url/url.go
+++ b/libgo/go/net/url/url.go
@@ -425,31 +425,31 @@ func (u *Userinfo) String() string {
return s
}
-// Maybe rawurl is of the form scheme:path.
+// Maybe rawURL is of the form scheme:path.
// (Scheme must be [a-zA-Z][a-zA-Z0-9+-.]*)
-// If so, return scheme, path; else return "", rawurl.
-func getscheme(rawurl string) (scheme, path string, err error) {
- for i := 0; i < len(rawurl); i++ {
- c := rawurl[i]
+// If so, return scheme, path; else return "", rawURL.
+func getScheme(rawURL string) (scheme, path string, err error) {
+ for i := 0; i < len(rawURL); i++ {
+ c := rawURL[i]
switch {
case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':
// do nothing
case '0' <= c && c <= '9' || c == '+' || c == '-' || c == '.':
if i == 0 {
- return "", rawurl, nil
+ return "", rawURL, nil
}
case c == ':':
if i == 0 {
return "", "", errors.New("missing protocol scheme")
}
- return rawurl[:i], rawurl[i+1:], nil
+ return rawURL[:i], rawURL[i+1:], nil
default:
// we have encountered an invalid character,
// so there is no valid scheme
- return "", rawurl, nil
+ return "", rawURL, nil
}
}
- return "", rawurl, nil
+ return "", rawURL, nil
}
// split slices s into two substrings separated by the first occurrence of
@@ -466,15 +466,15 @@ func split(s string, sep byte, cutc bool) (string, string) {
return s[:i], s[i:]
}
-// Parse parses rawurl into a URL structure.
+// Parse parses a raw url into a URL structure.
//
-// The rawurl may be relative (a path, without a host) or absolute
+// The url may be relative (a path, without a host) or absolute
// (starting with a scheme). Trying to parse a hostname and path
// without a scheme is invalid but may not necessarily return an
// error, due to parsing ambiguities.
-func Parse(rawurl string) (*URL, error) {
+func Parse(rawURL string) (*URL, error) {
// Cut off #frag
- u, frag := split(rawurl, '#', true)
+ u, frag := split(rawURL, '#', true)
url, err := parse(u, false)
if err != nil {
return nil, &Error{"parse", u, err}
@@ -483,20 +483,20 @@ func Parse(rawurl string) (*URL, error) {
return url, nil
}
if err = url.setFragment(frag); err != nil {
- return nil, &Error{"parse", rawurl, err}
+ return nil, &Error{"parse", rawURL, err}
}
return url, nil
}
-// ParseRequestURI parses rawurl into a URL structure. It assumes that
-// rawurl was received in an HTTP request, so the rawurl is interpreted
+// ParseRequestURI parses a raw url into a URL structure. It assumes that
+// url was received in an HTTP request, so the url is interpreted
// only as an absolute URI or an absolute path.
-// The string rawurl is assumed not to have a #fragment suffix.
+// The string url 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, error) {
- url, err := parse(rawurl, true)
+func ParseRequestURI(rawURL string) (*URL, error) {
+ url, err := parse(rawURL, true)
if err != nil {
- return nil, &Error{"parse", rawurl, err}
+ return nil, &Error{"parse", rawURL, err}
}
return url, nil
}
@@ -505,27 +505,27 @@ func ParseRequestURI(rawurl string) (*URL, error) {
// 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.
-func parse(rawurl string, viaRequest bool) (*URL, error) {
+func parse(rawURL string, viaRequest bool) (*URL, error) {
var rest string
var err error
- if stringContainsCTLByte(rawurl) {
+ if stringContainsCTLByte(rawURL) {
return nil, errors.New("net/url: invalid control character in URL")
}
- if rawurl == "" && viaRequest {
+ if rawURL == "" && viaRequest {
return nil, errors.New("empty url")
}
url := new(URL)
- if rawurl == "*" {
+ if rawURL == "*" {
url.Path = "*"
return url, nil
}
// Split off possible leading "http:", "mailto:", etc.
// Cannot contain escaped characters.
- if url.Scheme, rest, err = getscheme(rawurl); err != nil {
+ if url.Scheme, rest, err = getScheme(rawURL); err != nil {
return nil, err
}
url.Scheme = strings.ToLower(url.Scheme)
@@ -909,15 +909,22 @@ func (v Values) Del(key string) {
delete(v, key)
}
+// Has checks whether a given key is set.
+func (v Values) Has(key string) bool {
+ _, ok := v[key]
+ return ok
+}
+
// ParseQuery parses the URL-encoded query string and returns
// a map listing the values specified for each key.
// ParseQuery always returns a non-nil map containing all the
// valid query parameters found; err describes the first decoding error
// encountered, if any.
//
-// Query is expected to be a list of key=value settings separated by
-// ampersands or semicolons. A setting without an equals sign is
-// interpreted as a key set to an empty value.
+// Query is expected to be a list of key=value settings separated by ampersands.
+// A setting without an equals sign is interpreted as a key set to an empty
+// value.
+// Settings containing a non-URL-encoded semicolon are considered invalid.
func ParseQuery(query string) (Values, error) {
m := make(Values)
err := parseQuery(m, query)
@@ -927,11 +934,15 @@ func ParseQuery(query string) (Values, error) {
func parseQuery(m Values, query string) (err error) {
for query != "" {
key := query
- if i := strings.IndexAny(key, "&;"); i >= 0 {
+ if i := strings.IndexAny(key, "&"); i >= 0 {
key, query = key[:i], key[i+1:]
} else {
query = ""
}
+ if strings.Contains(key, ";") {
+ err = fmt.Errorf("invalid semicolon separator in query")
+ continue
+ }
if key == "" {
continue
}
@@ -1009,6 +1020,8 @@ func resolvePath(base, ref string) string {
)
first := true
remaining := full
+ // We want to return a leading '/', so write it now.
+ dst.WriteByte('/')
for i >= 0 {
i = strings.IndexByte(remaining, '/')
if i < 0 {
@@ -1023,10 +1036,12 @@ func resolvePath(base, ref string) string {
}
if elem == ".." {
- str := dst.String()
+ // Ignore the leading '/' we already wrote.
+ str := dst.String()[1:]
index := strings.LastIndexByte(str, '/')
dst.Reset()
+ dst.WriteByte('/')
if index == -1 {
first = true
} else {
@@ -1045,7 +1060,12 @@ func resolvePath(base, ref string) string {
dst.WriteByte('/')
}
- return "/" + strings.TrimPrefix(dst.String(), "/")
+ // We wrote an initial '/', but we don't want two.
+ r := dst.String()
+ if len(r) > 1 && r[1] == '/' {
+ r = r[1:]
+ }
+ return r
}
// IsAbs reports whether the URL is absolute.
@@ -1058,11 +1078,11 @@ func (u *URL) IsAbs() bool {
// 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)
+ refURL, err := Parse(ref)
if err != nil {
return nil, err
}
- return u.ResolveReference(refurl), nil
+ return u.ResolveReference(refURL), nil
}
// ResolveReference resolves a URI reference to an absolute URI from
@@ -1151,8 +1171,8 @@ func (u *URL) Port() string {
// splitHostPort separates host and port. If the port is not valid, it returns
// the entire input as host, and it doesn't check the validity of the host.
// Unlike net.SplitHostPort, but per RFC 3986, it requires ports to be numeric.
-func splitHostPort(hostport string) (host, port string) {
- host = hostport
+func splitHostPort(hostPort string) (host, port string) {
+ host = hostPort
colon := strings.LastIndexByte(host, ':')
if colon != -1 && validOptionalPort(host[colon:]) {