Skip to content

Commit 3745716

Browse files
committed
http: let FileServer work when path doesn't begin with a slash
... as when it's over-stripped with StripPrefix. R=golang-dev, andybalholm, rsc CC=golang-dev https://golang.org/cl/4759052
1 parent caa5647 commit 3745716

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

src/pkg/http/fs.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,12 @@ func FileServer(root FileSystem) Handler {
242242
}
243243

244244
func (f *fileHandler) ServeHTTP(w ResponseWriter, r *Request) {
245-
serveFile(w, r, f.root, path.Clean(r.URL.Path), true)
245+
upath := r.URL.Path
246+
if !strings.HasPrefix(upath, "/") {
247+
upath = "/" + upath
248+
r.URL.Path = upath
249+
}
250+
serveFile(w, r, f.root, path.Clean(upath), true)
246251
}
247252

248253
// httpRange specifies the byte range to be sent to the client.

src/pkg/http/fs_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"http/httptest"
1111
"io/ioutil"
1212
"os"
13+
"path/filepath"
14+
"strings"
1315
"testing"
1416
)
1517

@@ -117,6 +119,36 @@ func TestFileServerCleans(t *testing.T) {
117119
}
118120
}
119121

122+
func TestFileServerImplicitLeadingSlash(t *testing.T) {
123+
tempDir, err := ioutil.TempDir("", "")
124+
if err != nil {
125+
t.Fatalf("TempDir: %v", err)
126+
}
127+
defer os.RemoveAll(tempDir)
128+
if err := ioutil.WriteFile(filepath.Join(tempDir, "foo.txt"), []byte("Hello world"), 0644); err != nil {
129+
t.Fatalf("WriteFile: %v", err)
130+
}
131+
ts := httptest.NewServer(StripPrefix("/bar/", FileServer(Dir(tempDir))))
132+
defer ts.Close()
133+
get := func(suffix string) string {
134+
res, err := Get(ts.URL + suffix)
135+
if err != nil {
136+
t.Fatalf("Get %s: %v", suffix, err)
137+
}
138+
b, err := ioutil.ReadAll(res.Body)
139+
if err != nil {
140+
t.Fatalf("ReadAll %s: %v", suffix, err)
141+
}
142+
return string(b)
143+
}
144+
if s := get("/bar/"); !strings.Contains(s, ">foo.txt<") {
145+
t.Logf("expected a directory listing with foo.txt, got %q", s)
146+
}
147+
if s := get("/bar/foo.txt"); s != "Hello world" {
148+
t.Logf("expected %q, got %q", "Hello world", s)
149+
}
150+
}
151+
120152
func TestDirJoin(t *testing.T) {
121153
wfi, err := os.Stat("/etc/hosts")
122154
if err != nil {

0 commit comments

Comments
 (0)