gin-gonic / gin

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
https://gin-gonic.com/
MIT License
78.27k stars 7.99k forks source link

How do I set the cache time for static files #3675

Open hackersean opened 1 year ago

hackersean commented 1 year ago

Description

engine.Static("/static", staticPath)

I want to add a header to a static file,like c.Header("Cache-Control", "private, max-age=86400"),How to achieve。

thanks

OmarFaruk-0x01 commented 1 year ago

You can do this by using custom Middleware. Just check the url pathname manually if the pathname starts with /static then you can set a cache control header.


// Custom Middleware 
func staticCacheMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        // Apply the Cache-Control header to the static files
        if strings.HasPrefix(c.Request.URL.Path, "/static/") {
            c.Header("Cache-Control", "private, max-age=86400")
        }
        // Continue to the next middleware or handler
        c.Next()
    }
}

// Use this Middleware before serving the static files
engine.Use(staticCacheMiddleware())
engine.Static("/static", staticPath)

I hope this code snippet will help you. Thanks

hackersean commented 1 year ago

You can do this by using custom Middleware. Just check the url pathname manually if the pathname starts with /static then you can set a cache control header.

// Custom Middleware 
func staticCacheMiddleware() gin.HandlerFunc {
  return func(c *gin.Context) {
      // Apply the Cache-Control header to the static files
      if strings.HasPrefix(c.Request.URL.Path, "/static/") {
          c.Header("Cache-Control", "private, max-age=86400")
      }
      // Continue to the next middleware or handler
      c.Next()
  }
}

// Use this Middleware before serving the static files
engine.Use(staticCacheMiddleware())
engine.Static("/static", staticPath)

I hope this code snippet will help you. Thanks

I tried it. It didn't work

kaylee595 commented 1 year ago

@hackersean OmarFaruk-0x01's code works!

func setupRouter() *gin.Engine {
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.String(http.StatusOK, "pong")
    })
    r.Use(func(c *gin.Context) {
        // Apply the Cache-Control header to the static files
        fmt.Println(c.Request.URL.Path)
        if strings.HasPrefix(c.Request.URL.Path, "/static/") {
            c.Header("Cache-Control", "private, max-age=86400")
        }
        // Continue to the next middleware or handler
        c.Next()
    })
    r.Static("/static", "./static")
    return r
}

testing

var engine = setupRouter()

func TestHttp(t *testing.T) {
    want := "private, max-age=86400"
    resp := request(must(http.NewRequest("GET", "/static/test", nil)))
    assert.Equal(t, http.StatusOK, resp.StatusCode)
    assert.Equal(t, resp.Header.Get("Cache-Control"), want)
}

func request(req *http.Request) *http.Response {
    recorder := httptest.NewRecorder()
    engine.ServeHTTP(recorder, req)
    return recorder.Result()
}

out

=== RUN   TestHttp
/static/test
[GIN] 2023/08/15 - 22:59:59 | 200 |     25.7869ms |                 | GET      "/static/test"
--- PASS: TestHttp (0.03s)
PASS