mirror of https://github.com/golang/go.git
handle error inside serveFile
This commit is contained in:
parent
dbbbe96fd5
commit
7399288d66
|
|
@ -78,15 +78,11 @@ func (d Dir) Open(name string) (File, error) {
|
|||
if dir == "" {
|
||||
dir = "."
|
||||
}
|
||||
if fi, _ := os.Stat(dir); fi != nil && !fi.IsDir() {
|
||||
return nil, errors.New("http: attempting to traverse a non-directory")
|
||||
}
|
||||
fullName := filepath.Join(dir, path)
|
||||
f, err := os.Open(fullName)
|
||||
if err != nil {
|
||||
return nil, mapOpenError(err, fullName, filepath.Separator, os.Stat)
|
||||
}
|
||||
|
||||
return f, nil
|
||||
}
|
||||
|
||||
|
|
@ -664,11 +660,16 @@ func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec
|
|||
localRedirect(w, r, path.Base(url)+"/")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if url[len(url)-1] == '/' {
|
||||
localRedirect(w, r, "../"+path.Base(url))
|
||||
} else if url[len(url)-1] == '/' {
|
||||
base := path.Base(url)
|
||||
if base == "/" || base == "." {
|
||||
// The FileSystem maps a path like "/" or "/./" to a file instead of a directory.
|
||||
msg := "http: attempting to traverse a non-directory"
|
||||
Error(w, msg, StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
localRedirect(w, r, "../"+base)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -475,6 +475,12 @@ func TestDirJoin(t *testing.T) {
|
|||
test(Dir("/etc"), "/hosts")
|
||||
test(Dir("/etc"), "hosts")
|
||||
test(Dir("/etc"), "../../../../hosts")
|
||||
|
||||
// Not really directories, but since we use this trick in
|
||||
// ServeFile, test it:
|
||||
test(Dir("/etc/hosts"), "")
|
||||
test(Dir("/etc/hosts"), "/")
|
||||
test(Dir("/etc/hosts"), "../")
|
||||
}
|
||||
|
||||
func TestEmptyDirOpenCWD(t *testing.T) {
|
||||
|
|
@ -491,22 +497,6 @@ func TestEmptyDirOpenCWD(t *testing.T) {
|
|||
test(Dir("./"))
|
||||
}
|
||||
|
||||
// issue 63769
|
||||
func TestDirNormalFile(t *testing.T) {
|
||||
test := func(d Dir, filename string) {
|
||||
f, err := d.Open(filename)
|
||||
if err == nil {
|
||||
f.Close()
|
||||
t.Fatalf("got nil, want error")
|
||||
}
|
||||
}
|
||||
|
||||
test(Dir("testdata/index.html"), "")
|
||||
test(Dir("testdata/index.html"), "/")
|
||||
test(Dir("testdata/index.html"), "..")
|
||||
test(Dir("testdata/index.html"), "../")
|
||||
}
|
||||
|
||||
func TestServeFileContentType(t *testing.T) { run(t, testServeFileContentType) }
|
||||
func testServeFileContentType(t *testing.T, mode testMode) {
|
||||
const ctype = "icecream/chocolate"
|
||||
|
|
@ -1682,15 +1672,25 @@ func (grw gzipResponseWriter) Flush() {
|
|||
// Issue 63769
|
||||
func TestFileServerDirWithRootFile(t *testing.T) { run(t, testFileServerDirWithRootFile) }
|
||||
func testFileServerDirWithRootFile(t *testing.T, mode testMode) {
|
||||
ts := newClientServerTest(t, mode, FileServer(Dir("testdata/index.html"))).ts
|
||||
defer ts.Close()
|
||||
testDirFile := func(t *testing.T, h Handler) {
|
||||
ts := newClientServerTest(t, mode, h).ts
|
||||
defer ts.Close()
|
||||
|
||||
res, err := ts.Client().Get(ts.URL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
res, err := ts.Client().Get(ts.URL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if g, w := res.StatusCode, StatusInternalServerError; g != w {
|
||||
t.Errorf("StatusCode mismatch: got %d, want: %d", g, w)
|
||||
}
|
||||
res.Body.Close()
|
||||
}
|
||||
if g, w := res.StatusCode, StatusInternalServerError; g != w {
|
||||
t.Errorf("StatusCode mismatch: got %d, want: %d", g, w)
|
||||
}
|
||||
res.Body.Close()
|
||||
|
||||
t.Run("FileServer", func(t *testing.T) {
|
||||
testDirFile(t, FileServer(Dir("testdata/index.html")))
|
||||
})
|
||||
|
||||
t.Run("FileServerFS", func(t *testing.T) {
|
||||
testDirFile(t, FileServerFS(os.DirFS("testdata/index.html")))
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue