diff --git a/app.go b/app.go index 9abd4e9dbf..9d5290640a 100644 --- a/app.go +++ b/app.go @@ -374,6 +374,10 @@ type Static struct { // Optional. Default value false. Browse bool `json:"browse"` + // When set to true, enables direct download. + // Optional. Default value false. + Download bool `json:"download"` + // The name of the index file for serving a directory. // Optional. Default value "index.html". Index string `json:"index"` diff --git a/app_test.go b/app_test.go index 8ab7594e0d..1efd374a8f 100644 --- a/app_test.go +++ b/app_test.go @@ -674,6 +674,22 @@ func Test_App_Static_MaxAge(t *testing.T) { utils.AssertEqual(t, "public, max-age=100", resp.Header.Get(HeaderCacheControl), "CacheControl Control") } +// go test -run Test_App_Static_Download +func Test_App_Static_Download(t *testing.T) { + app := New() + c := app.AcquireCtx(&fasthttp.RequestCtx{}) + defer app.ReleaseCtx(c) + + app.Static("/fiber.png", "./.github/testdata/fs/img/fiber.png", Static{Download: true}) + + resp, err := app.Test(httptest.NewRequest("GET", "/fiber.png", nil)) + utils.AssertEqual(t, nil, err, "app.Test(req)") + utils.AssertEqual(t, 200, resp.StatusCode, "Status code") + utils.AssertEqual(t, false, resp.Header.Get(HeaderContentLength) == "") + utils.AssertEqual(t, "image/png", resp.Header.Get(HeaderContentType)) + utils.AssertEqual(t, `attachment`, resp.Header.Get(HeaderContentDisposition)) +} + // go test -run Test_App_Static_Group func Test_App_Static_Group(t *testing.T) { app := New() diff --git a/router.go b/router.go index 687e8fd578..d80b9bab19 100644 --- a/router.go +++ b/router.go @@ -375,6 +375,10 @@ func (app *App) registerStatic(prefix, root string, config ...Static) Router { } // Serve file fileHandler(c.fasthttp) + // Sets the response Content-Disposition header to attachment if the Download option is true + if len(config) > 0 && config[0].Download { + c.Attachment() + } // Return request if found and not forbidden status := c.fasthttp.Response.StatusCode() if status != StatusNotFound && status != StatusForbidden {