]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: strip port from host in mux Handler
authorKenny Grant <kennygrant@gmail.com>
Wed, 15 Mar 2017 21:55:04 +0000 (21:55 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Fri, 24 Mar 2017 19:10:33 +0000 (19:10 +0000)
This change strips the port in mux.Handler before attempting to
match handlers and adds a test for a request with port.

CONNECT requests continue to use the original path and port.

Fixes #10463

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

src/net/http/serve_test.go
src/net/http/server.go

index be429e57256106f98b8006e4fe64bfbad6a61d1a..9fb2d249a25b6e7df7bb76fdb7492cc75708266d 100644 (file)
@@ -337,6 +337,7 @@ var serveMuxTests = []struct {
        {"GET", "codesearch.google.com", "/search/", 203, "codesearch.google.com/"},
        {"GET", "codesearch.google.com", "/search/foo", 203, "codesearch.google.com/"},
        {"GET", "codesearch.google.com", "/", 203, "codesearch.google.com/"},
+       {"GET", "codesearch.google.com:443", "/", 203, "codesearch.google.com/"},
        {"GET", "images.google.com", "/search", 201, "/search"},
        {"GET", "images.google.com", "/search/", 404, ""},
        {"GET", "images.google.com", "/search/foo", 404, ""},
index 3276f0e9754eee6c0df81b541cecc43ace7fb418..f8398900c538d89df619297a16a011a42c7d6ecd 100644 (file)
@@ -2167,6 +2167,19 @@ func cleanPath(p string) string {
        return np
 }
 
+// stripHostPort returns h without any trailing ":<port>".
+func stripHostPort(h string) string {
+       // If no port on host, return unchanged
+       if strings.IndexByte(h, ':') == -1 {
+               return h
+       }
+       host, _, err := net.SplitHostPort(h)
+       if err != nil {
+               return h // on error, return unchanged
+       }
+       return host
+}
+
 // Find a handler on a handler map given a path string.
 // Most-specific (longest) pattern wins.
 func (mux *ServeMux) match(path string) (h Handler, pattern string) {
@@ -2195,7 +2208,10 @@ func (mux *ServeMux) match(path string) (h Handler, pattern string) {
 // consulting r.Method, r.Host, and r.URL.Path. It always returns
 // a non-nil handler. If the path is not in its canonical form, the
 // handler will be an internally-generated handler that redirects
-// to the canonical path.
+// to the canonical path. If the host contains a port, it is ignored
+// when matching handlers.
+//
+// The path and host are used unchanged for CONNECT requests.
 //
 // Handler also returns the registered pattern that matches the
 // request or, in the case of internally-generated redirects,
@@ -2204,16 +2220,24 @@ func (mux *ServeMux) match(path string) (h Handler, pattern string) {
 // If there is no registered handler that applies to the request,
 // Handler returns a ``page not found'' handler and an empty pattern.
 func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
-       if r.Method != "CONNECT" {
-               if p := cleanPath(r.URL.Path); p != r.URL.Path {
-                       _, pattern = mux.handler(r.Host, p)
-                       url := *r.URL
-                       url.Path = p
-                       return RedirectHandler(url.String(), StatusMovedPermanently), pattern
-               }
+
+       // CONNECT requests are not canonicalized.
+       if r.Method == "CONNECT" {
+               return mux.handler(r.Host, r.URL.Path)
+       }
+
+       // All other requests have any port stripped and path cleaned
+       // before passing to mux.handler.
+       host := stripHostPort(r.Host)
+       path := cleanPath(r.URL.Path)
+       if path != r.URL.Path {
+               _, pattern = mux.handler(host, path)
+               url := *r.URL
+               url.Path = path
+               return RedirectHandler(url.String(), StatusMovedPermanently), pattern
        }
 
-       return mux.handler(r.Host, r.URL.Path)
+       return mux.handler(host, r.URL.Path)
 }
 
 // handler is the main implementation of Handler.