mirror of
https://github.com/golang/go
synced 2024-11-12 09:50:21 -07:00
http: make serveFile redirects relative to work with StripPrefix
serveFile was using absolute redirects, which didn't work under StripPrefix. Now it uses relative redirects. R=golang-dev, rsc, bradfitz CC=golang-dev, kevlar https://golang.org/cl/4789042
This commit is contained in:
parent
08bfb39515
commit
3de6228aea
@ -102,8 +102,10 @@ func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec
|
||||
const indexPage = "/index.html"
|
||||
|
||||
// redirect .../index.html to .../
|
||||
// can't use Redirect() because that would make the path absolute,
|
||||
// which would be a problem running under StripPrefix
|
||||
if strings.HasSuffix(r.URL.Path, indexPage) {
|
||||
Redirect(w, r, r.URL.Path[0:len(r.URL.Path)-len(indexPage)+1], StatusMovedPermanently)
|
||||
localRedirect(w, r, "./")
|
||||
return
|
||||
}
|
||||
|
||||
@ -128,12 +130,12 @@ func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec
|
||||
url := r.URL.Path
|
||||
if d.IsDirectory() {
|
||||
if url[len(url)-1] != '/' {
|
||||
Redirect(w, r, url+"/", StatusMovedPermanently)
|
||||
localRedirect(w, r, path.Base(url)+"/")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if url[len(url)-1] == '/' {
|
||||
Redirect(w, r, url[0:len(url)-1], StatusMovedPermanently)
|
||||
localRedirect(w, r, "../"+path.Base(url))
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -221,6 +223,16 @@ func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec
|
||||
}
|
||||
}
|
||||
|
||||
// localRedirect gives a Moved Permanently response.
|
||||
// It does not convert relative paths to absolute paths like Redirect does.
|
||||
func localRedirect(w ResponseWriter, r *Request, newPath string) {
|
||||
if q := r.URL.RawQuery; q != "" {
|
||||
newPath += "?" + q
|
||||
}
|
||||
w.Header().Set("Location", newPath)
|
||||
w.WriteHeader(StatusMovedPermanently)
|
||||
}
|
||||
|
||||
// ServeFile replies to the request with the contents of the named file or directory.
|
||||
func ServeFile(w ResponseWriter, r *Request, name string) {
|
||||
dir, file := filepath.Split(name)
|
||||
|
@ -87,6 +87,30 @@ func TestServeFile(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var fsRedirectTestData = []struct {
|
||||
original, redirect string
|
||||
}{
|
||||
{"/test/index.html", "/test/"},
|
||||
{"/test/testdata", "/test/testdata/"},
|
||||
{"/test/testdata/file/", "/test/testdata/file"},
|
||||
}
|
||||
|
||||
func TestFSRedirect(t *testing.T) {
|
||||
ts := httptest.NewServer(StripPrefix("/test", FileServer(Dir("."))))
|
||||
defer ts.Close()
|
||||
|
||||
for _, data := range fsRedirectTestData {
|
||||
res, err := Get(ts.URL + data.original)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
res.Body.Close()
|
||||
if g, e := res.Request.URL.Path, data.redirect; g != e {
|
||||
t.Errorf("redirect from %s: got %s, want %s", data.original, g, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type testFileSystem struct {
|
||||
open func(name string) (File, os.Error)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user