diff --git a/fs.go b/fs.go new file mode 100644 index 00000000..6f09df74 --- /dev/null +++ b/fs.go @@ -0,0 +1,37 @@ +package gin + +import ( + "net/http" + "os" +) + +type ( + onlyfilesFS struct { + fs http.FileSystem + } + neuteredReaddirFile struct { + http.File + } +) + +func Dir(root string, listDirectory bool) http.FileSystem { + fs := http.Dir(root) + if listDirectory { + return fs + } else { + return &onlyfilesFS{fs} + } +} + +func (fs onlyfilesFS) Open(name string) (http.File, error) { + f, err := fs.fs.Open(name) + if err != nil { + return nil, err + } + return neuteredReaddirFile{f}, nil +} + +func (f neuteredReaddirFile) Readdir(count int) ([]os.FileInfo, error) { + // this disables directory listing + return nil, nil +} diff --git a/routergroup.go b/routergroup.go index 7d0a00fc..a81f1081 100644 --- a/routergroup.go +++ b/routergroup.go @@ -119,14 +119,14 @@ func (group *RouterGroup) StaticFile(relativePath, filepath string) { // use : // router.Static("/static", "/var/www") func (group *RouterGroup) Static(relativePath, root string) { - group.StaticFS(relativePath, http.Dir(root), false) + group.StaticFS(relativePath, Dir(root, false)) } -func (group *RouterGroup) StaticFS(relativePath string, fs http.FileSystem, listDirectory bool) { +func (group *RouterGroup) StaticFS(relativePath string, fs http.FileSystem) { if strings.Contains(relativePath, ":") || strings.Contains(relativePath, "*") { panic("URL parameters can not be used when serving a static folder") } - handler := group.createStaticHandler(relativePath, fs, listDirectory) + handler := group.createStaticHandler(relativePath, fs) relativePath = path.Join(relativePath, "/*filepath") // Register GET and HEAD handlers @@ -134,16 +134,10 @@ func (group *RouterGroup) StaticFS(relativePath string, fs http.FileSystem, list group.HEAD(relativePath, handler) } -func (group *RouterGroup) createStaticHandler(relativePath string, fs http.FileSystem, listDirectory bool) HandlerFunc { +func (group *RouterGroup) createStaticHandler(relativePath string, fs http.FileSystem) HandlerFunc { absolutePath := group.calculateAbsolutePath(relativePath) fileServer := http.StripPrefix(absolutePath, http.FileServer(fs)) - return func(c *Context) { - if !listDirectory && lastChar(c.Request.URL.Path) == '/' { - http.NotFound(c.Writer, c.Request) - return - } - fileServer.ServeHTTP(c.Writer, c.Request) - } + return WrapH(fileServer) } func (group *RouterGroup) combineHandlers(handlers HandlersChain) HandlersChain { diff --git a/routes_test.go b/routes_test.go index e547e181..1506a86a 100644 --- a/routes_test.go +++ b/routes_test.go @@ -179,7 +179,7 @@ func TestRouteStaticFile(t *testing.T) { // TestHandleStaticDir - ensure the root/sub dir handles properly func TestRouteStaticListingDir(t *testing.T) { router := New() - router.StaticFS("/", http.Dir("./"), true) + router.StaticFS("/", Dir("./", true)) w := performRequest(router, "GET", "/") @@ -195,7 +195,6 @@ func TestRouteStaticNoListing(t *testing.T) { w := performRequest(router, "GET", "/") - assert.Equal(t, w.Code, 404) assert.NotContains(t, w.Body.String(), "gin.go") }