diff --git a/middleware/common.go b/middleware/common.go index 839dba6..cfc6747 100644 --- a/middleware/common.go +++ b/middleware/common.go @@ -1,6 +1,7 @@ package middleware import ( + "fmt" model "github.com/cloudreve/Cloudreve/v3/models" "github.com/cloudreve/Cloudreve/v3/pkg/hashid" "github.com/cloudreve/Cloudreve/v3/pkg/serializer" @@ -51,3 +52,11 @@ func Sandbox() gin.HandlerFunc { 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))) + + } +} diff --git a/middleware/common_test.go b/middleware/common_test.go index 000687b..1ab839a 100644 --- a/middleware/common_test.go +++ b/middleware/common_test.go @@ -85,3 +85,21 @@ func TestCacheControl(t *testing.T) { TestFunc(c) 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") +} diff --git a/models/defaults.go b/models/defaults.go index 8c43b71..3090016 100644 --- a/models/defaults.go +++ b/models/defaults.go @@ -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: "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: "public_resource_maxage", Value: "86400", Type: "timeout"}, } diff --git a/routers/router.go b/routers/router.go index 9340bba..e6d9ba1 100644 --- a/routers/router.go +++ b/routers/router.go @@ -206,6 +206,7 @@ func InitMasterRouter() *gin.Engine { // 获取用户头像 user.GET("avatar/:id/:size", middleware.HashID(hashid.UserID), + middleware.StaticResourceCache(), controllers.GetUserAvatar, ) } @@ -217,11 +218,18 @@ func InitMasterRouter() *gin.Engine { 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跳转) 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) } diff --git a/service/user/setting.go b/service/user/setting.go index 4387df2..8d7f619 100644 --- a/service/user/setting.go +++ b/service/user/setting.go @@ -76,8 +76,6 @@ type ThemeChose struct { Theme string `json:"theme" binding:"required,hexcolor|rgb|rgba|hsl"` } -const avatarMaxAge = 3600 - // Update 更新主题设定 func (service *ThemeChose) Update(c *gin.Context, user *model.User) serializer.Response { user.OptionsSerialized.PreferredTheme = service.Theme @@ -196,8 +194,6 @@ func (service *AvatarService) Get(c *gin.Context) serializer.Response { "l": model.GetSettingByName("avatar_size_l"), } - c.Header("Cache-Control", fmt.Sprintf("max-age=%d", avatarMaxAge)) - // Gravatar 头像重定向 if user.Avatar == "gravatar" { server := model.GetSettingByName("gravatar_server")