net/http: don't call FileSystem.Open with unclean index.html path

Fixes #8722

LGTM=adg
R=adg
CC=golang-codereviews
https://golang.org/cl/142090043
This commit is contained in:
Brad Fitzpatrick 2014-09-15 07:14:33 -04:00
parent 5d5312c5dd
commit bb431245cc
2 changed files with 38 additions and 1 deletions

View file

@ -381,7 +381,7 @@ func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec
// use contents of index.html for directory, if present
if d.IsDir() {
index := name + indexPage
index := strings.TrimSuffix(name, "/") + indexPage
ff, err := fs.Open(index)
if err == nil {
defer ff.Close()

View file

@ -877,4 +877,41 @@ func TestLinuxSendfileChild(*testing.T) {
}
}
func TestFileServerCleanPath(t *testing.T) {
tests := []struct {
path string
wantCode int
wantOpen []string
}{
{"/", 200, []string{"/", "/index.html"}},
{"/dir", 301, []string{"/dir"}},
{"/dir/", 200, []string{"/dir", "/dir/index.html"}},
}
for _, tt := range tests {
var log []string
rr := httptest.NewRecorder()
req, _ := NewRequest("GET", "http://foo.localhost"+tt.path, nil)
FileServer(fileServerCleanPathDir{&log}).ServeHTTP(rr, req)
if !reflect.DeepEqual(log, tt.wantOpen) {
t.Logf("For %s: Opens = %q; want %q", tt.path, log, tt.wantOpen)
}
if rr.Code != tt.wantCode {
t.Logf("For %s: Response code = %d; want %d", tt.path, rr.Code, tt.wantCode)
}
}
}
type fileServerCleanPathDir struct {
log *[]string
}
func (d fileServerCleanPathDir) Open(path string) (File, error) {
*(d.log) = append(*(d.log), path)
if path == "/" || path == "/dir" || path == "/dir/" {
// Just return back something that's a directory.
return Dir(".").Open(".")
}
return nil, os.ErrNotExist
}
type panicOnSeek struct{ io.ReadSeeker }