Commit bdb61f4a authored by Matt Holt's avatar Matt Holt Committed by GitHub

Merge pull request #1409 from mastercactapus/not_a_directory

return 404 for "not a directory" errors
parents 1183d91c 18edf586
...@@ -56,6 +56,9 @@ func (fs FileServer) serveFile(w http.ResponseWriter, r *http.Request, name stri ...@@ -56,6 +56,9 @@ func (fs FileServer) serveFile(w http.ResponseWriter, r *http.Request, name stri
f, err := fs.Root.Open(name) f, err := fs.Root.Open(name)
if err != nil { if err != nil {
// TODO: remove when http.Dir handles this
// Go issue #18984
err = mapFSRootOpenErr(err)
if os.IsNotExist(err) { if os.IsNotExist(err) {
return http.StatusNotFound, nil return http.StatusNotFound, nil
} else if os.IsPermission(err) { } else if os.IsPermission(err) {
...@@ -230,3 +233,35 @@ var staticEncodingPriority = []string{ ...@@ -230,3 +233,35 @@ var staticEncodingPriority = []string{
"br", "br",
"gzip", "gzip",
} }
// mapFSRootOpenErr maps the provided non-nil error
// to a possibly better non-nil error. In particular, it turns OS-specific errors
// about opening files in non-directories into os.ErrNotExist.
//
// TODO: remove when http.Dir handles this
// Go issue #18984
func mapFSRootOpenErr(originalErr error) error {
if os.IsNotExist(originalErr) || os.IsPermission(originalErr) {
return originalErr
}
perr, ok := originalErr.(*os.PathError)
if !ok {
return originalErr
}
name := perr.Path
parts := strings.Split(name, string(filepath.Separator))
for i := range parts {
if parts[i] == "" {
continue
}
fi, err := os.Stat(strings.Join(parts[:i+1], string(filepath.Separator)))
if err != nil {
return originalErr
}
if !fi.IsDir() {
return os.ErrNotExist
}
}
return originalErr
}
...@@ -178,6 +178,11 @@ func TestServeHTTP(t *testing.T) { ...@@ -178,6 +178,11 @@ func TestServeHTTP(t *testing.T) {
expectedBodyContent: testFiles[filepath.Join("webroot", "sub", "brotli.html.br")], expectedBodyContent: testFiles[filepath.Join("webroot", "sub", "brotli.html.br")],
expectedEtag: `W/"1e240-e"`, expectedEtag: `W/"1e240-e"`,
}, },
// Test 20 - treat existing file as a directory.
{
url: "https://foo/file1.html/other",
expectedStatus: http.StatusNotFound,
},
} }
for i, test := range tests { for i, test := range tests {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment