diff options
author | Kenny Grant <kennygrant@gmail.com> | 2017-03-15 21:55:04 +0000 |
---|---|---|
committer | Brad Fitzpatrick <bradfitz@golang.org> | 2017-03-24 19:10:33 +0000 |
commit | f1e880386b668a26dd6b7afdea43c9041a917fa5 (patch) | |
tree | 478f4ffb051dd6e06f68972f7020dcff1fbe90c9 | |
parent | 369d1083a74b6a965a33510489ab381d937812ae (diff) | |
download | go-f1e880386b668a26dd6b7afdea43c9041a917fa5.tar.gz go-f1e880386b668a26dd6b7afdea43c9041a917fa5.zip |
net/http: strip port from host in mux Handler
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>
-rw-r--r-- | src/net/http/serve_test.go | 1 | ||||
-rw-r--r-- | src/net/http/server.go | 42 |
2 files changed, 34 insertions, 9 deletions
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go index be429e5725..9fb2d249a2 100644 --- a/src/net/http/serve_test.go +++ b/src/net/http/serve_test.go @@ -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, ""}, diff --git a/src/net/http/server.go b/src/net/http/server.go index 3276f0e975..f8398900c5 100644 --- a/src/net/http/server.go +++ b/src/net/http/server.go @@ -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. |