diff --git a/app.go b/app.go index 93cec556..387a475b 100644 --- a/app.go +++ b/app.go @@ -304,6 +304,11 @@ type Static struct { // // Optional. Default value 0. MaxAge int `json:"max_age"` + + // Next defines a function to skip this middleware when returned true. + // + // Optional. Default: nil + Next func(c *Ctx) bool } // Default Config values diff --git a/app_test.go b/app_test.go index e82798d4..51153348 100644 --- a/app_test.go +++ b/app_test.go @@ -758,6 +758,48 @@ func Test_App_Static_Trailing_Slash(t *testing.T) { utils.AssertEqual(t, MIMETextPlainCharsetUTF8, resp.Header.Get(HeaderContentType)) } +func Test_App_Static_Next(t *testing.T) { + app := New() + app.Static("/", ".github", Static{ + Next: func(c *Ctx) bool { + // If value of the header is any other from "skip" + // c.Next() will be invoked + return c.Get("X-Custom-Header") == "skip" + }, + }) + app.Get("/", func(c *Ctx) error { + return c.SendString("You've skipped app.Static") + }) + + t.Run("app.Static is skipped: invoking Get handler", func(t *testing.T) { + req := httptest.NewRequest("GET", "/", nil) + req.Header.Set("X-Custom-Header", "skip") + resp, err := app.Test(req) + utils.AssertEqual(t, nil, err) + utils.AssertEqual(t, 200, resp.StatusCode) + utils.AssertEqual(t, false, resp.Header.Get(HeaderContentLength) == "") + utils.AssertEqual(t, MIMETextPlainCharsetUTF8, resp.Header.Get(HeaderContentType)) + + body, err := ioutil.ReadAll(resp.Body) + utils.AssertEqual(t, nil, err) + utils.AssertEqual(t, true, strings.Contains(string(body), "You've skipped app.Static")) + }) + + t.Run("app.Static is not skipped: serving index.html", func(t *testing.T) { + req := httptest.NewRequest("GET", "/", nil) + req.Header.Set("X-Custom-Header", "don't skip") + resp, err := app.Test(req) + utils.AssertEqual(t, nil, err) + utils.AssertEqual(t, 200, resp.StatusCode) + utils.AssertEqual(t, false, resp.Header.Get(HeaderContentLength) == "") + utils.AssertEqual(t, MIMETextHTMLCharsetUTF8, resp.Header.Get(HeaderContentType)) + + body, err := ioutil.ReadAll(resp.Body) + utils.AssertEqual(t, nil, err) + utils.AssertEqual(t, true, strings.Contains(string(body), "Hello, World!")) + }) +} + // go test -run Test_App_Mixed_Routes_WithSameLen func Test_App_Mixed_Routes_WithSameLen(t *testing.T) { app := New() diff --git a/router.go b/router.go index b8fd98b6..f8c76b4e 100644 --- a/router.go +++ b/router.go @@ -359,6 +359,10 @@ func (app *App) registerStatic(prefix, root string, config ...Static) Router { } fileHandler := fs.NewRequestHandler() handler := func(c *Ctx) error { + // Don't execute middleware if Next returns true + if config != nil && config[0].Next != nil && config[0].Next(c) { + return c.Next() + } // Serve file fileHandler(c.fasthttp) // Return request if found and not forbidden