From 64b1517faf9b536d0ec755887648c8bdf0f927ef Mon Sep 17 00:00:00 2001 From: deepakganesh78 Date: Sun, 2 Aug 2026 21:02:52 +0530 Subject: [PATCH] fix: serve index.html via FileFromFS without redirect Serve regular files from FileFromFS directly with http.ServeContent so file names ending in index.html are returned as requested instead of triggering net/http FileServer's directory redirect behavior. Directory paths continue to use FileServer. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- context.go | 18 ++++++++++++++++++ context_test.go | 16 ++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/context.go b/context.go index 1dc730e3..96f51e7e 100644 --- a/context.go +++ b/context.go @@ -1339,6 +1339,24 @@ func (c *Context) File(filepath string) { // FileFromFS writes the specified file from http.FileSystem into the body stream in an efficient way. func (c *Context) FileFromFS(filepath string, fs http.FileSystem) { + file, err := fs.Open(filepath) + if err != nil { + http.NotFound(c.Writer, c.Request) + return + } + defer file.Close() + + info, err := file.Stat() + if err != nil { + http.NotFound(c.Writer, c.Request) + return + } + + if !info.IsDir() { + http.ServeContent(c.Writer, c.Request, filepath, info.ModTime(), file) + return + } + defer func(old string) { c.Request.URL.Path = old }(c.Request.URL.Path) diff --git a/context_test.go b/context_test.go index e8d305e4..34f7032b 100644 --- a/context_test.go +++ b/context_test.go @@ -25,6 +25,7 @@ import ( "strings" "sync" "testing" + "testing/fstest" "time" "github.com/gin-contrib/sse" @@ -1558,6 +1559,21 @@ func TestContextRenderFileFromFS(t *testing.T) { assert.Equal(t, "/some/path", c.Request.URL.Path) } +func TestContextRenderFileFromFSIndexHTML(t *testing.T) { + w := httptest.NewRecorder() + c, _ := CreateTestContext(w) + + c.Request, _ = http.NewRequest(http.MethodGet, "/", nil) + c.FileFromFS("www/index.html", http.FS(fstest.MapFS{ + "www/index.html": {Data: []byte("index")}, + })) + + assert.Equal(t, http.StatusOK, w.Code) + assert.Equal(t, "index", w.Body.String()) + assert.Empty(t, w.Header().Get("Location")) + assert.Equal(t, "/", c.Request.URL.Path) +} + func TestContextRenderAttachment(t *testing.T) { w := httptest.NewRecorder() c, _ := CreateTestContext(w)