mirror of
https://github.com/golang/go
synced 2024-11-25 18:07:57 -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)},
|
{"/search", serve(201)},
|
||||||
{"codesearch.google.com/search", serve(202)},
|
{"codesearch.google.com/search", serve(202)},
|
||||||
{"codesearch.google.com/", serve(203)},
|
{"codesearch.google.com/", serve(203)},
|
||||||
|
{"example.com/", HandlerFunc(checkQueryStringHandler)},
|
||||||
}
|
}
|
||||||
|
|
||||||
// serve returns a handler that sends a response with the given code.
|
// 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 {
|
var serveMuxTests = []struct {
|
||||||
method string
|
method string
|
||||||
host 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
|
// Tests for http://code.google.com/p/go/issues/detail?id=900
|
||||||
func TestMuxRedirectLeadingSlashes(t *testing.T) {
|
func TestMuxRedirectLeadingSlashes(t *testing.T) {
|
||||||
paths := []string{"//foo.txt", "///foo.txt", "/../../foo.txt"}
|
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 r.Method != "CONNECT" {
|
||||||
if p := cleanPath(r.URL.Path); p != r.URL.Path {
|
if p := cleanPath(r.URL.Path); p != r.URL.Path {
|
||||||
_, pattern = mux.handler(r.Host, p)
|
_, 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