mirror of
https://github.com/golang/go
synced 2024-11-21 18:34:44 -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"
|
const indexPage = "/index.html"
|
||||||
|
|
||||||
// redirect .../index.html to .../
|
// 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) {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,12 +130,12 @@ func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec
|
|||||||
url := r.URL.Path
|
url := r.URL.Path
|
||||||
if d.IsDirectory() {
|
if d.IsDirectory() {
|
||||||
if url[len(url)-1] != '/' {
|
if url[len(url)-1] != '/' {
|
||||||
Redirect(w, r, url+"/", StatusMovedPermanently)
|
localRedirect(w, r, path.Base(url)+"/")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if url[len(url)-1] == '/' {
|
if url[len(url)-1] == '/' {
|
||||||
Redirect(w, r, url[0:len(url)-1], StatusMovedPermanently)
|
localRedirect(w, r, "../"+path.Base(url))
|
||||||
return
|
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.
|
// ServeFile replies to the request with the contents of the named file or directory.
|
||||||
func ServeFile(w ResponseWriter, r *Request, name string) {
|
func ServeFile(w ResponseWriter, r *Request, name string) {
|
||||||
dir, file := filepath.Split(name)
|
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 {
|
type testFileSystem struct {
|
||||||
open func(name string) (File, os.Error)
|
open func(name string) (File, os.Error)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user