diff --git a/middleware/favicon/favicon.go b/middleware/favicon/favicon.go index 6584fa25..924f7e61 100644 --- a/middleware/favicon/favicon.go +++ b/middleware/favicon/favicon.go @@ -2,6 +2,7 @@ package favicon import ( "io/ioutil" + "net/http" "strconv" "github.com/gofiber/fiber/v2" @@ -17,12 +18,18 @@ type Config struct { // File holds the path to an actual favicon that will be cached // // Optional. Default: "" - File string + File string `json:"file"` + + // FileSystem is an optional alternate filesystem to search for the favicon in. + // An example of this could be an embedded or network filesystem + // + // Optional. Default: nil + FileSystem http.FileSystem `json:"-"` // CacheControl defines how the Cache-Control header in the response should be set // // Optional. Default: "public, max-age=31536000" - CacheControl string + CacheControl string `json:"cache_control"` } // ConfigDefault is the default config @@ -66,9 +73,21 @@ func New(config ...Config) fiber.Handler { iconLen string ) if cfg.File != "" { - if icon, err = ioutil.ReadFile(cfg.File); err != nil { - panic(err) + // read from configured filesystem if present + if cfg.FileSystem != nil { + f, err := cfg.FileSystem.Open(cfg.File) + if err != nil { + panic(err) + } + if icon, err = ioutil.ReadAll(f); err != nil { + panic(err) + } + } else { + if icon, err = ioutil.ReadFile(cfg.File); err != nil { + panic(err) + } } + iconLen = strconv.Itoa(len(icon)) } diff --git a/middleware/favicon/favicon_test.go b/middleware/favicon/favicon_test.go index 5f7465ca..9f181b65 100644 --- a/middleware/favicon/favicon_test.go +++ b/middleware/favicon/favicon_test.go @@ -1,7 +1,9 @@ package favicon import ( + "net/http" "net/http/httptest" + "os" "testing" "github.com/gofiber/fiber/v2" @@ -71,6 +73,22 @@ func Test_Middleware_Favicon_Found(t *testing.T) { utils.AssertEqual(t, "public, max-age=31536000", resp.Header.Get(fiber.HeaderCacheControl), "CacheControl Control") } +// go test -run Test_Middleware_Favicon_FileSystem +func Test_Middleware_Favicon_FileSystem(t *testing.T) { + app := fiber.New() + + app.Use(New(Config{ + File: "favicon.ico", + FileSystem: http.FS(os.DirFS("../../.github/testdata/")), + })) + + resp, err := app.Test(httptest.NewRequest("GET", "/favicon.ico", nil)) + utils.AssertEqual(t, nil, err, "app.Test(req)") + utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode, "Status code") + utils.AssertEqual(t, "image/x-icon", resp.Header.Get(fiber.HeaderContentType)) + utils.AssertEqual(t, "public, max-age=31536000", resp.Header.Get(fiber.HeaderCacheControl), "CacheControl Control") +} + // go test -run Test_Middleware_Favicon_CacheControl func Test_Middleware_Favicon_CacheControl(t *testing.T) { app := fiber.New() @@ -79,6 +97,7 @@ func Test_Middleware_Favicon_CacheControl(t *testing.T) { CacheControl: "public, max-age=100", File: "../../.github/testdata/favicon.ico", })) + resp, err := app.Test(httptest.NewRequest("GET", "/favicon.ico", nil)) utils.AssertEqual(t, nil, err, "app.Test(req)") utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode, "Status code")