mirror of
https://github.com/golang/go
synced 2024-11-22 04:34:39 -07:00
net/http: redirect handlers from mux.Handler() shouldn't clear the query string
R=bradfitz, alberto.garcia.hierro, rsc, adg CC=golang-dev https://golang.org/cl/7099045
This commit is contained in:
parent
c51152f438
commit
716a409b90
@ -277,6 +277,7 @@ var serveMuxRegister = []struct {
|
||||
{"/search", serve(201)},
|
||||
{"codesearch.google.com/search", serve(202)},
|
||||
{"codesearch.google.com/", serve(203)},
|
||||
{"example.com/", HandlerFunc(checkQueryStringHandler)},
|
||||
}
|
||||
|
||||
// serve returns a handler that sends a response with the given code.
|
||||
@ -286,6 +287,21 @@ func serve(code int) HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// checkQueryStringHandler checks if r.URL.RawQuery has the same value
|
||||
// as the URL excluding the scheme and the query string and sends 200
|
||||
// response code if it is, 500 otherwise.
|
||||
func checkQueryStringHandler(w ResponseWriter, r *Request) {
|
||||
u := *r.URL
|
||||
u.Scheme = "http"
|
||||
u.Host = r.Host
|
||||
u.RawQuery = ""
|
||||
if "http://"+r.URL.RawQuery == u.String() {
|
||||
w.WriteHeader(200)
|
||||
} else {
|
||||
w.WriteHeader(500)
|
||||
}
|
||||
}
|
||||
|
||||
var serveMuxTests = []struct {
|
||||
method string
|
||||
host string
|
||||
@ -344,6 +360,61 @@ func TestServeMuxHandler(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var serveMuxTests2 = []struct {
|
||||
method string
|
||||
host string
|
||||
url string
|
||||
code int
|
||||
redirOk bool
|
||||
}{
|
||||
{"GET", "google.com", "/", 404, false},
|
||||
{"GET", "example.com", "/test/?example.com/test/", 200, false},
|
||||
{"GET", "example.com", "test/?example.com/test/", 200, true},
|
||||
}
|
||||
|
||||
// TestServeMuxHandlerRedirects tests that automatic redirects generated by
|
||||
// mux.Handler() shouldn't clear the request's query string.
|
||||
func TestServeMuxHandlerRedirects(t *testing.T) {
|
||||
mux := NewServeMux()
|
||||
for _, e := range serveMuxRegister {
|
||||
mux.Handle(e.pattern, e.h)
|
||||
}
|
||||
|
||||
for _, tt := range serveMuxTests2 {
|
||||
tries := 1
|
||||
turl := tt.url
|
||||
for tries > 0 {
|
||||
u, e := url.Parse(turl)
|
||||
if e != nil {
|
||||
t.Fatal(e)
|
||||
}
|
||||
r := &Request{
|
||||
Method: tt.method,
|
||||
Host: tt.host,
|
||||
URL: u,
|
||||
}
|
||||
h, _ := mux.Handler(r)
|
||||
rr := httptest.NewRecorder()
|
||||
h.ServeHTTP(rr, r)
|
||||
if rr.Code != 301 {
|
||||
if rr.Code != tt.code {
|
||||
t.Errorf("%s %s %s = %d, want %d", tt.method, tt.host, tt.url, rr.Code, tt.code)
|
||||
}
|
||||
break
|
||||
}
|
||||
if !tt.redirOk {
|
||||
t.Errorf("%s %s %s, unexpected redirect", tt.method, tt.host, tt.url)
|
||||
break
|
||||
}
|
||||
turl = rr.HeaderMap.Get("Location")
|
||||
tries--
|
||||
}
|
||||
if tries < 0 {
|
||||
t.Errorf("%s %s %s, too many redirects", tt.method, tt.host, tt.url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests for http://code.google.com/p/go/issues/detail?id=900
|
||||
func TestMuxRedirectLeadingSlashes(t *testing.T) {
|
||||
paths := []string{"//foo.txt", "///foo.txt", "/../../foo.txt"}
|
||||
|
@ -1448,7 +1448,9 @@ 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)
|
||||
return RedirectHandler(p, StatusMovedPermanently), pattern
|
||||
url := *r.URL
|
||||
url.Path = p
|
||||
return RedirectHandler(url.String(), StatusMovedPermanently), pattern
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user