aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenny Grant <kennygrant@gmail.com>2017-03-15 21:55:04 +0000
committerBrad Fitzpatrick <bradfitz@golang.org>2017-03-24 19:10:33 +0000
commitf1e880386b668a26dd6b7afdea43c9041a917fa5 (patch)
tree478f4ffb051dd6e06f68972f7020dcff1fbe90c9
parent369d1083a74b6a965a33510489ab381d937812ae (diff)
downloadgo-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.go1
-rw-r--r--src/net/http/server.go42
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.