From: Kenny Grant Date: Wed, 15 Mar 2017 21:55:04 +0000 (+0000) Subject: net/http: strip port from host in mux Handler X-Git-Tag: go1.9beta1~990 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=f1e880386b668a26dd6b7afdea43c9041a917fa5;p=gostls13.git 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 Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- 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 ":". +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.