]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: normalize empty port in URL.Host's ":port"
authorEmmanuel Odeke <emm.odeke@gmail.com>
Sat, 16 Apr 2016 09:04:00 +0000 (02:04 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Sat, 16 Apr 2016 15:31:33 +0000 (15:31 +0000)
- Ensures that the empty port and preceeding ":"
in a URL.Host are stripped.
Normalize the empty port in a URL.Host's ":port" as
mandated by RFC 3986 Section 6.2.3 which states that:
`Likewise an explicit ":port", for which the port is empty or
the default for the scheme, is equivalent to one where the port
and its ":" delimiter are elided and thus should be
removed by scheme-based normalization.`

- Moves function `hasPort` from client.go (where it was defined but
not used directly), to http.go the common area.

Fixes #14836

Change-Id: I2067410377be9c71106b1717abddc2f8b1da1c03
Reviewed-on: https://go-review.googlesource.com/22140
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/net/http/client.go
src/net/http/http.go
src/net/http/request.go
src/net/http/request_test.go

index ee0fd2cb62a388f73d3809cc32aeda96268544d9..f8ab675a3de04794384b97cefe9beac77dd2523d 100644 (file)
@@ -110,10 +110,6 @@ type RoundTripper interface {
        RoundTrip(*Request) (*Response, error)
 }
 
-// Given a string of the form "host", "host:port", or "[ipv6::address]:port",
-// return true if the string includes a port.
-func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") }
-
 // refererForURL returns a referer without any authentication info or
 // an empty string if lastReq scheme is https and newReq scheme is http.
 func refererForURL(lastReq, newReq *url.URL) string {
index 7484348f522943c64138fc8e361033368fc4c02b..a121628632f99aadee7e62147cfed6b8e2e87819 100644 (file)
@@ -4,6 +4,10 @@
 
 package http
 
+import (
+       "strings"
+)
+
 // maxInt64 is the effective "infinite" value for the Server and
 // Transport's byte-limiting readers.
 const maxInt64 = 1<<63 - 1
@@ -18,3 +22,16 @@ type contextKey struct {
 }
 
 func (k *contextKey) String() string { return "net/http context value " + k.name }
+
+// Given a string of the form "host", "host:port", or "[ipv6::address]:port",
+// return true if the string includes a port.
+func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") }
+
+// removeEmptyPort strips the empty port in ":port" to ""
+// as mandated by RFC 3986 Section 6.2.3.
+func removeEmptyPort(host string) string {
+       if hasPort(host) {
+               return strings.TrimSuffix(host, ":")
+       }
+       return host
+}
index bac2de1a2ed7705b1e897f5a78ea5773ca0f7ee1..a49ab369644f318bf18b1ee99988a610632f07f1 100644 (file)
@@ -660,6 +660,8 @@ func NewRequest(method, urlStr string, body io.Reader) (*Request, error) {
        if !ok && body != nil {
                rc = ioutil.NopCloser(body)
        }
+       // The host's colon:port should be normalized. See Issue 14836.
+       u.Host = removeEmptyPort(u.Host)
        req := &Request{
                Method:     method,
                URL:        u,
index ff4837f2faadde59ba158f3903559314a2eaed84..82c7af3cda8dbedeff0a0bc4f79a9115dba1b936 100644 (file)
@@ -398,11 +398,13 @@ var newRequestHostTests = []struct {
 
        {"http://192.168.0.1/", "192.168.0.1"},
        {"http://192.168.0.1:8080/", "192.168.0.1:8080"},
+       {"http://192.168.0.1:/", "192.168.0.1"},
 
        {"http://[fe80::1]/", "[fe80::1]"},
        {"http://[fe80::1]:8080/", "[fe80::1]:8080"},
        {"http://[fe80::1%25en0]/", "[fe80::1%en0]"},
        {"http://[fe80::1%25en0]:8080/", "[fe80::1%en0]:8080"},
+       {"http://[fe80::1%25en0]:/", "[fe80::1%en0]"},
 }
 
 func TestNewRequestHost(t *testing.T) {