diff --git a/router.go b/router.go index 6746e82..8d46b36 100644 --- a/router.go +++ b/router.go @@ -1,6 +1,7 @@ package atreugo import ( + "io/fs" "net/http" "sort" "strings" @@ -323,7 +324,7 @@ func (r *Router) NetHTTPPath(method, url string, handler http.Handler) *Path { return r.RequestHandlerPath(method, url, h) } -// Static serves static files from the given file system root +// Static serves static files from the given file system root path. // // Make sure your program has enough 'max open files' limit aka // 'ulimit -n' if root folder contains many files. @@ -336,6 +337,22 @@ func (r *Router) Static(url, rootPath string) *Path { }) } +// StaticFS serves static files from the given file system. +// +// Make sure your program has enough 'max open files' limit aka +// 'ulimit -n' if filesystem contains many files. +func (r *Router) StaticFS(url string, filesystem fs.FS) *Path { + return r.StaticCustom(url, &StaticFS{ + FS: filesystem, + Root: "", + AllowEmptyRoot: true, + GenerateIndexPages: true, + Compress: true, + CompressBrotli: true, + AcceptByteRange: true, + }) +} + // StaticCustom serves static files from the given file system settings // // Make sure your program has enough 'max open files' limit aka diff --git a/router_test.go b/router_test.go index c30d249..5c97f42 100644 --- a/router_test.go +++ b/router_test.go @@ -3,6 +3,7 @@ package atreugo import ( "bytes" "crypto/rand" + "embed" "errors" "fmt" "log" @@ -30,6 +31,9 @@ var httpMethods = []string{ fastrouter.MethodWild, } +//go:embed LICENSE +var fsTestFilesystem embed.FS + func testRouter() *Router { return newRouter(testConfig) } @@ -1049,6 +1053,56 @@ func TestRouter_Static(t *testing.T) { } } +func TestRouter_StaticFS(t *testing.T) { + type args struct { + url string + } + + type want struct { + routerPath string + } + + tests := []struct { + name string + args args + want + }{ + { + name: "WithoutTrailingSlash", + args: args{ + url: "/static", + }, + want: want{ + routerPath: "/static/{filepath:*}", + }, + }, + { + name: "WithTrailingSlash", + args: args{ + url: "/static/", + }, + want: want{ + routerPath: "/static/{filepath:*}", + }, + }, + } + + for _, test := range tests { + tt := test + t.Run(tt.name, func(t *testing.T) { + t.Helper() + + r := testRouter() + r.StaticFS(tt.args.url, fsTestFilesystem) + + handler, _ := r.router.Lookup("GET", tt.want.routerPath, &fasthttp.RequestCtx{}) + if handler == nil { + t.Error("Static FS is not configured") + } + }) + } +} + func TestRouter_StaticCustom(t *testing.T) { //nolint:funlen type args struct { url string