Skip to content

Commit

Permalink
fs: fix GenerateIndexPages when DirFS or embed.FS is used (#1778)
Browse files Browse the repository at this point in the history
  • Loading branch information
efectn authored May 18, 2024
1 parent 8f5b927 commit aadadb9
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 2 deletions.
15 changes: 13 additions & 2 deletions fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,8 @@ func (h *fsHandler) handleRequest(ctx *RequestCtx) {
mustCompress = false
ff, err = h.openFSFile(filePath, mustCompress, fileEncoding)
}
if err == errDirIndexRequired {

if errors.Is(err, errDirIndexRequired) {
if !hasTrailingSlash {
ctx.RedirectBytes(append(path, '/'), StatusFound)
return
Expand Down Expand Up @@ -1261,6 +1262,11 @@ func (h *fsHandler) createDirIndex(ctx *RequestCtx, dirPath string, mustCompress

base := ctx.URI()

// io/fs doesn't support ReadDir with empty path.
if dirPath == "" {
dirPath = "."
}

basePathEscaped := html.EscapeString(string(base.Path()))
_, _ = fmt.Fprintf(w, "<html><head><title>%s</title><style>.dir { font-weight: bold }</style></head><body>", basePathEscaped)
_, _ = fmt.Fprintf(w, "<h1>%s</h1>", basePathEscaped)
Expand Down Expand Up @@ -1556,12 +1562,17 @@ func (h *fsHandler) openFSFile(filePath string, mustCompress bool, fileEncoding
if mustCompress {
filePath += h.compressedFileSuffixes[fileEncoding]
}

f, err := h.filesystem.Open(filePath)
if err != nil {
if mustCompress && errors.Is(err, fs.ErrNotExist) {
return h.compressAndOpenFSFile(filePathOriginal, fileEncoding)
}

// If the file is not found and the path is empty, let's return errDirIndexRequired error.
if filePath == "" && (errors.Is(err, fs.ErrNotExist) || errors.Is(err, fs.ErrInvalid)) {
return nil, errDirIndexRequired
}

return nil, err
}

Expand Down
82 changes: 82 additions & 0 deletions fs_fs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -636,3 +636,85 @@ func TestDirFSServeFileDirectoryRedirect(t *testing.T) {
t.Fatalf("Unexpected status code %d for file '/fs.go'. Expecting %d.", ctx.Response.StatusCode(), StatusOK)
}
}

func TestFSFSGenerateIndexOsDirFS(t *testing.T) {
t.Parallel()

t.Run("dirFS", func(t *testing.T) {
t.Parallel()

fs := &FS{
FS: dirTestFilesystem,
Root: ".",
GenerateIndexPages: true,
}
h := fs.NewRequestHandler()

var ctx RequestCtx
var req Request
ctx.Init(&req, nil, nil)

h(&ctx)

cases := []string{"/", "//", ""}
for _, c := range cases {
ctx.Request.Reset()
ctx.Response.Reset()

req.Header.SetMethod(MethodGet)
req.SetRequestURI("http://foobar.com" + c)
h(&ctx)

if ctx.Response.StatusCode() != StatusOK {
t.Fatalf("unexpected status code %d for path %q. Expecting %d", ctx.Response.StatusCode(), ctx.Response.StatusCode(), StatusOK)
}

if !bytes.Contains(ctx.Response.Body(), []byte("fasthttputil")) {
t.Fatalf("unexpected body %q. Expecting to contain %q", ctx.Response.Body(), "fasthttputil")
}

if !bytes.Contains(ctx.Response.Body(), []byte("fs.go")) {
t.Fatalf("unexpected body %q. Expecting to contain %q", ctx.Response.Body(), "fs.go")
}
}
})

t.Run("embedFS", func(t *testing.T) {
t.Parallel()

fs := &FS{
FS: fsTestFilesystem,
Root: ".",
GenerateIndexPages: true,
}
h := fs.NewRequestHandler()

var ctx RequestCtx
var req Request
ctx.Init(&req, nil, nil)

h(&ctx)

cases := []string{"/", "//", ""}
for _, c := range cases {
ctx.Request.Reset()
ctx.Response.Reset()

req.Header.SetMethod(MethodGet)
req.SetRequestURI("http://foobar.com" + c)
h(&ctx)

if ctx.Response.StatusCode() != StatusOK {
t.Fatalf("unexpected status code %d for path %q. Expecting %d", ctx.Response.StatusCode(), ctx.Response.StatusCode(), StatusOK)
}

if !bytes.Contains(ctx.Response.Body(), []byte("fasthttputil")) {
t.Fatalf("unexpected body %q. Expecting to contain %q", ctx.Response.Body(), "fasthttputil")
}

if !bytes.Contains(ctx.Response.Body(), []byte("fs.go")) {
t.Fatalf("unexpected body %q. Expecting to contain %q", ctx.Response.Body(), "fs.go")
}
}
})
}

0 comments on commit aadadb9

Please sign in to comment.