feat(cache): set `max-age` for public accessible static resources

pull/1561/head
HFO4 2 years ago
parent 8c5ba89f7d
commit 50a3917a65

@ -1,6 +1,7 @@
package middleware package middleware
import ( import (
"fmt"
model "github.com/cloudreve/Cloudreve/v3/models" model "github.com/cloudreve/Cloudreve/v3/models"
"github.com/cloudreve/Cloudreve/v3/pkg/hashid" "github.com/cloudreve/Cloudreve/v3/pkg/hashid"
"github.com/cloudreve/Cloudreve/v3/pkg/serializer" "github.com/cloudreve/Cloudreve/v3/pkg/serializer"
@ -51,3 +52,11 @@ func Sandbox() gin.HandlerFunc {
c.Header("Content-Security-Policy", "sandbox") c.Header("Content-Security-Policy", "sandbox")
} }
} }
// StaticResourceCache 使用静态资源缓存策略
func StaticResourceCache() gin.HandlerFunc {
return func(c *gin.Context) {
c.Header("Cache-Control", fmt.Sprintf("public, max-age=%d", model.GetIntSetting("public_resource_maxage", 86400)))
}
}

@ -85,3 +85,21 @@ func TestCacheControl(t *testing.T) {
TestFunc(c) TestFunc(c)
a.Contains(c.Writer.Header().Get("Cache-Control"), "no-cache") a.Contains(c.Writer.Header().Get("Cache-Control"), "no-cache")
} }
func TestSandbox(t *testing.T) {
a := assert.New(t)
TestFunc := Sandbox()
rec := httptest.NewRecorder()
c, _ := gin.CreateTestContext(rec)
TestFunc(c)
a.Contains(c.Writer.Header().Get("Content-Security-Policy"), "sandbox")
}
func TestStaticResourceCache(t *testing.T) {
a := assert.New(t)
TestFunc := StaticResourceCache()
rec := httptest.NewRecorder()
c, _ := gin.CreateTestContext(rec)
TestFunc(c)
a.Contains(c.Writer.Header().Get("Cache-Control"), "public, max-age")
}

@ -114,4 +114,5 @@ Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; verti
{Name: "pwa_background_color", Value: "#ffffff", Type: "pwa"}, {Name: "pwa_background_color", Value: "#ffffff", Type: "pwa"},
{Name: "office_preview_service", Value: "https://view.officeapps.live.com/op/view.aspx?src={$src}", Type: "preview"}, {Name: "office_preview_service", Value: "https://view.officeapps.live.com/op/view.aspx?src={$src}", Type: "preview"},
{Name: "show_app_promotion", Value: "1", Type: "mobile"}, {Name: "show_app_promotion", Value: "1", Type: "mobile"},
{Name: "public_resource_maxage", Value: "86400", Type: "timeout"},
} }

@ -206,6 +206,7 @@ func InitMasterRouter() *gin.Engine {
// 获取用户头像 // 获取用户头像
user.GET("avatar/:id/:size", user.GET("avatar/:id/:size",
middleware.HashID(hashid.UserID), middleware.HashID(hashid.UserID),
middleware.StaticResourceCache(),
controllers.GetUserAvatar, controllers.GetUserAvatar,
) )
} }
@ -217,11 +218,18 @@ func InitMasterRouter() *gin.Engine {
file := sign.Group("file") file := sign.Group("file")
{ {
// 文件外链(直接输出文件数据) // 文件外链(直接输出文件数据)
file.GET("get/:id/:name", middleware.Sandbox(), controllers.AnonymousGetContent) file.GET("get/:id/:name",
middleware.Sandbox(),
middleware.StaticResourceCache(),
controllers.AnonymousGetContent,
)
// 文件外链(301跳转) // 文件外链(301跳转)
file.GET("source/:id/:name", controllers.AnonymousPermLinkDeprecated) file.GET("source/:id/:name", controllers.AnonymousPermLinkDeprecated)
// 下载文件 // 下载文件
file.GET("download/:id", controllers.Download) file.GET("download/:id",
middleware.StaticResourceCache(),
controllers.Download,
)
// 打包并下载文件 // 打包并下载文件
file.GET("archive/:sessionID/archive.zip", controllers.DownloadArchive) file.GET("archive/:sessionID/archive.zip", controllers.DownloadArchive)
} }

@ -76,8 +76,6 @@ type ThemeChose struct {
Theme string `json:"theme" binding:"required,hexcolor|rgb|rgba|hsl"` Theme string `json:"theme" binding:"required,hexcolor|rgb|rgba|hsl"`
} }
const avatarMaxAge = 3600
// Update 更新主题设定 // Update 更新主题设定
func (service *ThemeChose) Update(c *gin.Context, user *model.User) serializer.Response { func (service *ThemeChose) Update(c *gin.Context, user *model.User) serializer.Response {
user.OptionsSerialized.PreferredTheme = service.Theme user.OptionsSerialized.PreferredTheme = service.Theme
@ -196,8 +194,6 @@ func (service *AvatarService) Get(c *gin.Context) serializer.Response {
"l": model.GetSettingByName("avatar_size_l"), "l": model.GetSettingByName("avatar_size_l"),
} }
c.Header("Cache-Control", fmt.Sprintf("max-age=%d", avatarMaxAge))
// Gravatar 头像重定向 // Gravatar 头像重定向
if user.Avatar == "gravatar" { if user.Avatar == "gravatar" {
server := model.GetSettingByName("gravatar_server") server := model.GetSettingByName("gravatar_server")

Loading…
Cancel
Save