From b62c51a24dc874868a04f98533cb6e04f9ff5f77 Mon Sep 17 00:00:00 2001 From: silverwind Date: Thu, 21 Jul 2022 06:16:44 +0200 Subject: [PATCH 01/13] Add Cache-Control header to html/api responses, add no-transform `no-transform` allegedly disables CloudFlare auto-minify and we did not set caching headers on html or api requests, which seems good to have regardless. --- modules/context/api.go | 3 +++ modules/context/context.go | 2 ++ modules/httpcache/httpcache.go | 6 +++--- routers/install/routes.go | 3 +++ routers/web/base.go | 2 ++ 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/modules/context/api.go b/modules/context/api.go index 558a9f51ee34f..67274c42b71a2 100644 --- a/modules/context/api.go +++ b/modules/context/api.go @@ -11,11 +11,13 @@ import ( "net/http" "net/url" "strings" + "time" "code.gitea.io/gitea/models/auth" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web/middleware" @@ -268,6 +270,7 @@ func APIContexter() func(http.Handler) http.Handler { } } + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0*time.Second) ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) ctx.Data["Context"] = &ctx diff --git a/modules/context/context.go b/modules/context/context.go index 68f8a1b408c1f..151403af16157 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -28,6 +28,7 @@ import ( "code.gitea.io/gitea/modules/base" mc "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -767,6 +768,7 @@ func Contexter() func(next http.Handler) http.Handler { } } + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0*time.Second) ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) ctx.Data["CsrfToken"] = ctx.csrf.GetToken() diff --git a/modules/httpcache/httpcache.go b/modules/httpcache/httpcache.go index 5797e981cf80f..aca884723b21c 100644 --- a/modules/httpcache/httpcache.go +++ b/modules/httpcache/httpcache.go @@ -19,13 +19,13 @@ import ( // AddCacheControlToHeader adds suitable cache-control headers to response func AddCacheControlToHeader(h http.Header, d time.Duration) { if setting.IsProd { - h.Set("Cache-Control", "private, max-age="+strconv.Itoa(int(d.Seconds()))) + h.Set("Cache-Control", "private, no-transform, max-age="+strconv.Itoa(int(d.Seconds()))) } else { - h.Set("Cache-Control", "no-store") + h.Set("Cache-Control", "no-store, no-transform") // to remind users they are using non-prod setting. // some users may be confused by "Cache-Control: no-store" in their setup if they did wrong to `RUN_MODE` in `app.ini`. h.Add("X-Gitea-Debug", "RUN_MODE="+setting.RunMode) - h.Add("X-Gitea-Debug", "CacheControl=no-store") + h.Add("X-Gitea-Debug", "CacheControl=no-store, no-transform") } } diff --git a/routers/install/routes.go b/routers/install/routes.go index 32829ede9e26f..546065c79ec2f 100644 --- a/routers/install/routes.go +++ b/routers/install/routes.go @@ -8,7 +8,9 @@ import ( "fmt" "net/http" "path" + "time" + "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/public" "code.gitea.io/gitea/modules/setting" @@ -62,6 +64,7 @@ func installRecovery() func(next http.Handler) http.Handler { "SignedUserName": "", } + httpcache.AddCacheControlToHeader(w.Header(), 0*time.Second) w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) if !setting.IsProd { diff --git a/routers/web/base.go b/routers/web/base.go index c7ade55a61f6f..40eeb489c971f 100644 --- a/routers/web/base.go +++ b/routers/web/base.go @@ -12,6 +12,7 @@ import ( "os" "path" "strings" + "time" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/httpcache" @@ -158,6 +159,7 @@ func Recovery() func(next http.Handler) http.Handler { store["SignedUserName"] = "" } + httpcache.AddCacheControlToHeader(w.Header(), 0*time.Second) w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) if !setting.IsProd { From 7224410d673de3524eb5128f8417f226a699f8be Mon Sep 17 00:00:00 2001 From: silverwind Date: Thu, 21 Jul 2022 06:49:49 +0200 Subject: [PATCH 02/13] Add noTranform argument to function --- modules/context/api.go | 2 +- modules/context/context.go | 2 +- modules/httpcache/httpcache.go | 26 ++++++++++++++++++-------- routers/install/routes.go | 2 +- routers/web/base.go | 2 +- routers/web/user/avatar.go | 2 +- 6 files changed, 23 insertions(+), 13 deletions(-) diff --git a/modules/context/api.go b/modules/context/api.go index 67274c42b71a2..206516e2ae4b5 100644 --- a/modules/context/api.go +++ b/modules/context/api.go @@ -270,7 +270,7 @@ func APIContexter() func(http.Handler) http.Handler { } } - httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0*time.Second) + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0*time.Second, true) ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) ctx.Data["Context"] = &ctx diff --git a/modules/context/context.go b/modules/context/context.go index 151403af16157..7f4ae3fc58ef6 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -768,7 +768,7 @@ func Contexter() func(next http.Handler) http.Handler { } } - httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0*time.Second) + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0*time.Second, true) ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) ctx.Data["CsrfToken"] = ctx.csrf.GetToken() diff --git a/modules/httpcache/httpcache.go b/modules/httpcache/httpcache.go index aca884723b21c..b579cabf36f18 100644 --- a/modules/httpcache/httpcache.go +++ b/modules/httpcache/httpcache.go @@ -17,16 +17,26 @@ import ( ) // AddCacheControlToHeader adds suitable cache-control headers to response -func AddCacheControlToHeader(h http.Header, d time.Duration) { +func AddCacheControlToHeader(h http.Header, d time.Duration, noTranform bool) { + directives := []string{} + if setting.IsProd { - h.Set("Cache-Control", "private, no-transform, max-age="+strconv.Itoa(int(d.Seconds()))) + directives = append(directives, "private") + if noTranform { + directives = append(directives, "no-transform") + } + directives = append(directives, "max-age="+strconv.Itoa(int(d.Seconds()))) } else { - h.Set("Cache-Control", "no-store, no-transform") + directives = append(directives, "no-store") + if noTranform { + directives = append(directives, "no-transform") + } + // to remind users they are using non-prod setting. - // some users may be confused by "Cache-Control: no-store" in their setup if they did wrong to `RUN_MODE` in `app.ini`. h.Add("X-Gitea-Debug", "RUN_MODE="+setting.RunMode) - h.Add("X-Gitea-Debug", "CacheControl=no-store, no-transform") } + + h.Set("Cache-Control", strings.Join(directives, ", ")) } // generateETag generates an ETag based on size, filename and file modification time @@ -42,7 +52,7 @@ func HandleTimeCache(req *http.Request, w http.ResponseWriter, fi os.FileInfo) ( // HandleGenericTimeCache handles time-based caching for a HTTP request func HandleGenericTimeCache(req *http.Request, w http.ResponseWriter, lastModified time.Time) (handled bool) { - AddCacheControlToHeader(w.Header(), setting.StaticCacheTime) + AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, false) ifModifiedSince := req.Header.Get("If-Modified-Since") if ifModifiedSince != "" { @@ -73,7 +83,7 @@ func HandleGenericETagCache(req *http.Request, w http.ResponseWriter, etag strin return true } } - AddCacheControlToHeader(w.Header(), setting.StaticCacheTime) + AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, false) return false } @@ -117,6 +127,6 @@ func HandleGenericETagTimeCache(req *http.Request, w http.ResponseWriter, etag s } } } - AddCacheControlToHeader(w.Header(), setting.StaticCacheTime) + AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, false) return false } diff --git a/routers/install/routes.go b/routers/install/routes.go index 546065c79ec2f..0691ed7458d6f 100644 --- a/routers/install/routes.go +++ b/routers/install/routes.go @@ -64,7 +64,7 @@ func installRecovery() func(next http.Handler) http.Handler { "SignedUserName": "", } - httpcache.AddCacheControlToHeader(w.Header(), 0*time.Second) + httpcache.AddCacheControlToHeader(w.Header(), 0*time.Second, true) w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) if !setting.IsProd { diff --git a/routers/web/base.go b/routers/web/base.go index 40eeb489c971f..e30763d973c57 100644 --- a/routers/web/base.go +++ b/routers/web/base.go @@ -159,7 +159,7 @@ func Recovery() func(next http.Handler) http.Handler { store["SignedUserName"] = "" } - httpcache.AddCacheControlToHeader(w.Header(), 0*time.Second) + httpcache.AddCacheControlToHeader(w.Header(), 0*time.Second, true) w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) if !setting.IsProd { diff --git a/routers/web/user/avatar.go b/routers/web/user/avatar.go index 53a603fab094d..5bdfed7ca050e 100644 --- a/routers/web/user/avatar.go +++ b/routers/web/user/avatar.go @@ -18,7 +18,7 @@ func cacheableRedirect(ctx *context.Context, location string) { // here we should not use `setting.StaticCacheTime`, it is pretty long (default: 6 hours) // we must make sure the redirection cache time is short enough, otherwise a user won't see the updated avatar in 6 hours // it's OK to make the cache time short, it is only a redirection, and doesn't cost much to make a new request - httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 5*time.Minute) + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 5*time.Minute, false) ctx.Redirect(location) } From 08313cab3579e6b1d9ab302e97a2b6cd21940118 Mon Sep 17 00:00:00 2001 From: silverwind Date: Thu, 21 Jul 2022 06:55:43 +0200 Subject: [PATCH 03/13] use 0 --- modules/context/api.go | 3 +-- modules/context/context.go | 2 +- routers/install/routes.go | 3 +-- routers/web/base.go | 3 +-- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/modules/context/api.go b/modules/context/api.go index 206516e2ae4b5..2ec1772d9eeb7 100644 --- a/modules/context/api.go +++ b/modules/context/api.go @@ -11,7 +11,6 @@ import ( "net/http" "net/url" "strings" - "time" "code.gitea.io/gitea/models/auth" repo_model "code.gitea.io/gitea/models/repo" @@ -270,7 +269,7 @@ func APIContexter() func(http.Handler) http.Handler { } } - httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0*time.Second, true) + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, true) ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) ctx.Data["Context"] = &ctx diff --git a/modules/context/context.go b/modules/context/context.go index 7f4ae3fc58ef6..015262917c420 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -768,7 +768,7 @@ func Contexter() func(next http.Handler) http.Handler { } } - httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0*time.Second, true) + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, true) ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) ctx.Data["CsrfToken"] = ctx.csrf.GetToken() diff --git a/routers/install/routes.go b/routers/install/routes.go index 0691ed7458d6f..6741fb155b590 100644 --- a/routers/install/routes.go +++ b/routers/install/routes.go @@ -8,7 +8,6 @@ import ( "fmt" "net/http" "path" - "time" "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/log" @@ -64,7 +63,7 @@ func installRecovery() func(next http.Handler) http.Handler { "SignedUserName": "", } - httpcache.AddCacheControlToHeader(w.Header(), 0*time.Second, true) + httpcache.AddCacheControlToHeader(w.Header(), 0, true) w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) if !setting.IsProd { diff --git a/routers/web/base.go b/routers/web/base.go index e30763d973c57..c06cd98477dfe 100644 --- a/routers/web/base.go +++ b/routers/web/base.go @@ -12,7 +12,6 @@ import ( "os" "path" "strings" - "time" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/httpcache" @@ -159,7 +158,7 @@ func Recovery() func(next http.Handler) http.Handler { store["SignedUserName"] = "" } - httpcache.AddCacheControlToHeader(w.Header(), 0*time.Second, true) + httpcache.AddCacheControlToHeader(w.Header(), 0, true) w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) if !setting.IsProd { From 61094dadeee710d115ba703798ef1c43aa97ced6 Mon Sep 17 00:00:00 2001 From: silverwind Date: Thu, 21 Jul 2022 19:13:21 +0200 Subject: [PATCH 04/13] accept slice of string --- modules/context/api.go | 2 +- modules/context/context.go | 2 +- modules/httpcache/httpcache.go | 15 +++++---------- routers/install/routes.go | 2 +- routers/web/base.go | 2 +- routers/web/user/avatar.go | 2 +- 6 files changed, 10 insertions(+), 15 deletions(-) diff --git a/modules/context/api.go b/modules/context/api.go index 2ec1772d9eeb7..0958cbe6de1ad 100644 --- a/modules/context/api.go +++ b/modules/context/api.go @@ -269,7 +269,7 @@ func APIContexter() func(http.Handler) http.Handler { } } - httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, true) + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, []string{"no-tranform"}) ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) ctx.Data["Context"] = &ctx diff --git a/modules/context/context.go b/modules/context/context.go index 015262917c420..eaca92f5902e2 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -768,7 +768,7 @@ func Contexter() func(next http.Handler) http.Handler { } } - httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, true) + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, []string{"no-tranform"}) ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) ctx.Data["CsrfToken"] = ctx.csrf.GetToken() diff --git a/modules/httpcache/httpcache.go b/modules/httpcache/httpcache.go index b579cabf36f18..bbcd08303a6cd 100644 --- a/modules/httpcache/httpcache.go +++ b/modules/httpcache/httpcache.go @@ -17,25 +17,20 @@ import ( ) // AddCacheControlToHeader adds suitable cache-control headers to response -func AddCacheControlToHeader(h http.Header, d time.Duration, noTranform bool) { +func AddCacheControlToHeader(h http.Header, d time.Duration, additionalDirectives []string) { directives := []string{} if setting.IsProd { directives = append(directives, "private") - if noTranform { - directives = append(directives, "no-transform") - } directives = append(directives, "max-age="+strconv.Itoa(int(d.Seconds()))) } else { directives = append(directives, "no-store") - if noTranform { - directives = append(directives, "no-transform") - } // to remind users they are using non-prod setting. h.Add("X-Gitea-Debug", "RUN_MODE="+setting.RunMode) } + directives = append(directives, additionalDirectives...) h.Set("Cache-Control", strings.Join(directives, ", ")) } @@ -52,7 +47,7 @@ func HandleTimeCache(req *http.Request, w http.ResponseWriter, fi os.FileInfo) ( // HandleGenericTimeCache handles time-based caching for a HTTP request func HandleGenericTimeCache(req *http.Request, w http.ResponseWriter, lastModified time.Time) (handled bool) { - AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, false) + AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, []string{}) ifModifiedSince := req.Header.Get("If-Modified-Since") if ifModifiedSince != "" { @@ -83,7 +78,7 @@ func HandleGenericETagCache(req *http.Request, w http.ResponseWriter, etag strin return true } } - AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, false) + AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, []string{}) return false } @@ -127,6 +122,6 @@ func HandleGenericETagTimeCache(req *http.Request, w http.ResponseWriter, etag s } } } - AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, false) + AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, []string{}) return false } diff --git a/routers/install/routes.go b/routers/install/routes.go index 6741fb155b590..afbb78e36741b 100644 --- a/routers/install/routes.go +++ b/routers/install/routes.go @@ -63,7 +63,7 @@ func installRecovery() func(next http.Handler) http.Handler { "SignedUserName": "", } - httpcache.AddCacheControlToHeader(w.Header(), 0, true) + httpcache.AddCacheControlToHeader(w.Header(), 0, []string{"no-tranform"}) w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) if !setting.IsProd { diff --git a/routers/web/base.go b/routers/web/base.go index c06cd98477dfe..c281b672c91f0 100644 --- a/routers/web/base.go +++ b/routers/web/base.go @@ -158,7 +158,7 @@ func Recovery() func(next http.Handler) http.Handler { store["SignedUserName"] = "" } - httpcache.AddCacheControlToHeader(w.Header(), 0, true) + httpcache.AddCacheControlToHeader(w.Header(), 0, []string{"no-tranform"}) w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) if !setting.IsProd { diff --git a/routers/web/user/avatar.go b/routers/web/user/avatar.go index 5bdfed7ca050e..6b4ccc973fd60 100644 --- a/routers/web/user/avatar.go +++ b/routers/web/user/avatar.go @@ -18,7 +18,7 @@ func cacheableRedirect(ctx *context.Context, location string) { // here we should not use `setting.StaticCacheTime`, it is pretty long (default: 6 hours) // we must make sure the redirection cache time is short enough, otherwise a user won't see the updated avatar in 6 hours // it's OK to make the cache time short, it is only a redirection, and doesn't cost much to make a new request - httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 5*time.Minute, false) + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 5*time.Minute, []string{}) ctx.Redirect(location) } From e15ddcacf5019ca249677ca1f34bfc96cd470ec0 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 22 Jul 2022 01:35:00 +0800 Subject: [PATCH 05/13] Apply suggestions from code review --- modules/httpcache/httpcache.go | 8 ++++---- routers/web/user/avatar.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/httpcache/httpcache.go b/modules/httpcache/httpcache.go index bbcd08303a6cd..c3efea304dbd5 100644 --- a/modules/httpcache/httpcache.go +++ b/modules/httpcache/httpcache.go @@ -18,7 +18,7 @@ import ( // AddCacheControlToHeader adds suitable cache-control headers to response func AddCacheControlToHeader(h http.Header, d time.Duration, additionalDirectives []string) { - directives := []string{} + directives := make([]string, 0, 2+len(additionalDirectives)) if setting.IsProd { directives = append(directives, "private") @@ -47,7 +47,7 @@ func HandleTimeCache(req *http.Request, w http.ResponseWriter, fi os.FileInfo) ( // HandleGenericTimeCache handles time-based caching for a HTTP request func HandleGenericTimeCache(req *http.Request, w http.ResponseWriter, lastModified time.Time) (handled bool) { - AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, []string{}) + AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, nil) ifModifiedSince := req.Header.Get("If-Modified-Since") if ifModifiedSince != "" { @@ -78,7 +78,7 @@ func HandleGenericETagCache(req *http.Request, w http.ResponseWriter, etag strin return true } } - AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, []string{}) + AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, nil) return false } @@ -122,6 +122,6 @@ func HandleGenericETagTimeCache(req *http.Request, w http.ResponseWriter, etag s } } } - AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, []string{}) + AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, nil) return false } diff --git a/routers/web/user/avatar.go b/routers/web/user/avatar.go index 6b4ccc973fd60..f140faf36e48c 100644 --- a/routers/web/user/avatar.go +++ b/routers/web/user/avatar.go @@ -18,7 +18,7 @@ func cacheableRedirect(ctx *context.Context, location string) { // here we should not use `setting.StaticCacheTime`, it is pretty long (default: 6 hours) // we must make sure the redirection cache time is short enough, otherwise a user won't see the updated avatar in 6 hours // it's OK to make the cache time short, it is only a redirection, and doesn't cost much to make a new request - httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 5*time.Minute, []string{}) + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 5*time.Minute, nil) ctx.Redirect(location) } From f47846b72541593098022d41dfdd3c05c0149635 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 22 Jul 2022 02:03:57 +0800 Subject: [PATCH 06/13] Apply suggestions from code review --- modules/context/context.go | 2 +- routers/install/routes.go | 2 +- routers/web/base.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/context/context.go b/modules/context/context.go index eaca92f5902e2..4f17d758006dc 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -768,7 +768,7 @@ func Contexter() func(next http.Handler) http.Handler { } } - httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, []string{"no-tranform"}) + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, []string{"no-transform"}) ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) ctx.Data["CsrfToken"] = ctx.csrf.GetToken() diff --git a/routers/install/routes.go b/routers/install/routes.go index afbb78e36741b..37975247dbfa6 100644 --- a/routers/install/routes.go +++ b/routers/install/routes.go @@ -63,7 +63,7 @@ func installRecovery() func(next http.Handler) http.Handler { "SignedUserName": "", } - httpcache.AddCacheControlToHeader(w.Header(), 0, []string{"no-tranform"}) + httpcache.AddCacheControlToHeader(w.Header(), 0, []string{"no-transform"}) w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) if !setting.IsProd { diff --git a/routers/web/base.go b/routers/web/base.go index c281b672c91f0..bddf5495c7def 100644 --- a/routers/web/base.go +++ b/routers/web/base.go @@ -158,7 +158,7 @@ func Recovery() func(next http.Handler) http.Handler { store["SignedUserName"] = "" } - httpcache.AddCacheControlToHeader(w.Header(), 0, []string{"no-tranform"}) + httpcache.AddCacheControlToHeader(w.Header(), 0, []string{"no-transform"}) w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) if !setting.IsProd { From 4e79cb38d95ffc393d6ee1af1879ee889e25a9b5 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 22 Jul 2022 02:04:27 +0800 Subject: [PATCH 07/13] Update modules/context/api.go --- modules/context/api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/context/api.go b/modules/context/api.go index 0958cbe6de1ad..edb6ce897c585 100644 --- a/modules/context/api.go +++ b/modules/context/api.go @@ -269,7 +269,7 @@ func APIContexter() func(http.Handler) http.Handler { } } - httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, []string{"no-tranform"}) + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, []string{"no-transform"}) ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) ctx.Data["Context"] = &ctx From 0e6e80d56c0a050c32defdb6c8d5b484e91e67a2 Mon Sep 17 00:00:00 2001 From: silverwind Date: Fri, 22 Jul 2022 17:54:53 +0200 Subject: [PATCH 08/13] use no-store instead of max-age=0 --- modules/httpcache/httpcache.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/httpcache/httpcache.go b/modules/httpcache/httpcache.go index c3efea304dbd5..ac05cd2f0a82f 100644 --- a/modules/httpcache/httpcache.go +++ b/modules/httpcache/httpcache.go @@ -22,7 +22,12 @@ func AddCacheControlToHeader(h http.Header, d time.Duration, additionalDirective if setting.IsProd { directives = append(directives, "private") - directives = append(directives, "max-age="+strconv.Itoa(int(d.Seconds()))) + if d == 0 { + // prefer no-store in place of max-age=0 + directives = append(directives, "no-store") + } else { + directives = append(directives, "max-age="+strconv.Itoa(int(d.Seconds()))) + } } else { directives = append(directives, "no-store") From 31b4f8fcb96fd6c81fc63e8921ab04d334cd2d6a Mon Sep 17 00:00:00 2001 From: silverwind Date: Fri, 22 Jul 2022 19:18:21 +0200 Subject: [PATCH 09/13] add private directive only when actually allowing storage --- modules/httpcache/httpcache.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/httpcache/httpcache.go b/modules/httpcache/httpcache.go index ac05cd2f0a82f..e48e21f6f8884 100644 --- a/modules/httpcache/httpcache.go +++ b/modules/httpcache/httpcache.go @@ -21,11 +21,11 @@ func AddCacheControlToHeader(h http.Header, d time.Duration, additionalDirective directives := make([]string, 0, 2+len(additionalDirectives)) if setting.IsProd { - directives = append(directives, "private") if d == 0 { // prefer no-store in place of max-age=0 directives = append(directives, "no-store") } else { + directives = append(directives, "private") directives = append(directives, "max-age="+strconv.Itoa(int(d.Seconds()))) } } else { From 588b0bb9c461a1ce3804534be550cfc379adbc65 Mon Sep 17 00:00:00 2001 From: silverwind Date: Fri, 22 Jul 2022 19:18:48 +0200 Subject: [PATCH 10/13] remove comment --- modules/httpcache/httpcache.go | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/httpcache/httpcache.go b/modules/httpcache/httpcache.go index e48e21f6f8884..6adc6d0aa45f9 100644 --- a/modules/httpcache/httpcache.go +++ b/modules/httpcache/httpcache.go @@ -22,7 +22,6 @@ func AddCacheControlToHeader(h http.Header, d time.Duration, additionalDirective if setting.IsProd { if d == 0 { - // prefer no-store in place of max-age=0 directives = append(directives, "no-store") } else { directives = append(directives, "private") From 6a7fcff3b33431a686ab80765a2ed0343575abed Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Fri, 22 Jul 2022 20:14:40 +0100 Subject: [PATCH 11/13] use varargs notation Signed-off-by: Andrew Thornton --- modules/context/api.go | 2 +- modules/context/context.go | 2 +- modules/httpcache/httpcache.go | 8 ++++---- routers/install/routes.go | 2 +- routers/web/base.go | 2 +- routers/web/user/avatar.go | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/context/api.go b/modules/context/api.go index edb6ce897c585..b9d130e2a8ac0 100644 --- a/modules/context/api.go +++ b/modules/context/api.go @@ -269,7 +269,7 @@ func APIContexter() func(http.Handler) http.Handler { } } - httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, []string{"no-transform"}) + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, "no-transform") ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) ctx.Data["Context"] = &ctx diff --git a/modules/context/context.go b/modules/context/context.go index 4f17d758006dc..8824911619921 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -768,7 +768,7 @@ func Contexter() func(next http.Handler) http.Handler { } } - httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, []string{"no-transform"}) + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, "no-transform") ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) ctx.Data["CsrfToken"] = ctx.csrf.GetToken() diff --git a/modules/httpcache/httpcache.go b/modules/httpcache/httpcache.go index 6adc6d0aa45f9..9e7e04b6e15c3 100644 --- a/modules/httpcache/httpcache.go +++ b/modules/httpcache/httpcache.go @@ -17,7 +17,7 @@ import ( ) // AddCacheControlToHeader adds suitable cache-control headers to response -func AddCacheControlToHeader(h http.Header, d time.Duration, additionalDirectives []string) { +func AddCacheControlToHeader(h http.Header, d time.Duration, additionalDirectives ...string) { directives := make([]string, 0, 2+len(additionalDirectives)) if setting.IsProd { @@ -51,7 +51,7 @@ func HandleTimeCache(req *http.Request, w http.ResponseWriter, fi os.FileInfo) ( // HandleGenericTimeCache handles time-based caching for a HTTP request func HandleGenericTimeCache(req *http.Request, w http.ResponseWriter, lastModified time.Time) (handled bool) { - AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, nil) + AddCacheControlToHeader(w.Header(), setting.StaticCacheTime) ifModifiedSince := req.Header.Get("If-Modified-Since") if ifModifiedSince != "" { @@ -82,7 +82,7 @@ func HandleGenericETagCache(req *http.Request, w http.ResponseWriter, etag strin return true } } - AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, nil) + AddCacheControlToHeader(w.Header(), setting.StaticCacheTime) return false } @@ -126,6 +126,6 @@ func HandleGenericETagTimeCache(req *http.Request, w http.ResponseWriter, etag s } } } - AddCacheControlToHeader(w.Header(), setting.StaticCacheTime, nil) + AddCacheControlToHeader(w.Header(), setting.StaticCacheTime) return false } diff --git a/routers/install/routes.go b/routers/install/routes.go index 37975247dbfa6..fdabcb9dc22c1 100644 --- a/routers/install/routes.go +++ b/routers/install/routes.go @@ -63,7 +63,7 @@ func installRecovery() func(next http.Handler) http.Handler { "SignedUserName": "", } - httpcache.AddCacheControlToHeader(w.Header(), 0, []string{"no-transform"}) + httpcache.AddCacheControlToHeader(w.Header(), 0, "no-transform") w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) if !setting.IsProd { diff --git a/routers/web/base.go b/routers/web/base.go index bddf5495c7def..30a24a1275432 100644 --- a/routers/web/base.go +++ b/routers/web/base.go @@ -158,7 +158,7 @@ func Recovery() func(next http.Handler) http.Handler { store["SignedUserName"] = "" } - httpcache.AddCacheControlToHeader(w.Header(), 0, []string{"no-transform"}) + httpcache.AddCacheControlToHeader(w.Header(), 0, "no-transform") w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) if !setting.IsProd { diff --git a/routers/web/user/avatar.go b/routers/web/user/avatar.go index f140faf36e48c..53a603fab094d 100644 --- a/routers/web/user/avatar.go +++ b/routers/web/user/avatar.go @@ -18,7 +18,7 @@ func cacheableRedirect(ctx *context.Context, location string) { // here we should not use `setting.StaticCacheTime`, it is pretty long (default: 6 hours) // we must make sure the redirection cache time is short enough, otherwise a user won't see the updated avatar in 6 hours // it's OK to make the cache time short, it is only a redirection, and doesn't cost much to make a new request - httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 5*time.Minute, nil) + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 5*time.Minute) ctx.Redirect(location) } From 78cedac7b8ac44971c20762bc539b252b05af140 Mon Sep 17 00:00:00 2001 From: silverwind Date: Fri, 22 Jul 2022 21:54:41 +0200 Subject: [PATCH 12/13] minor refactor --- modules/httpcache/httpcache.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/httpcache/httpcache.go b/modules/httpcache/httpcache.go index 9e7e04b6e15c3..50d30565f67e1 100644 --- a/modules/httpcache/httpcache.go +++ b/modules/httpcache/httpcache.go @@ -17,15 +17,14 @@ import ( ) // AddCacheControlToHeader adds suitable cache-control headers to response -func AddCacheControlToHeader(h http.Header, d time.Duration, additionalDirectives ...string) { +func AddCacheControlToHeader(h http.Header, maxAge time.Duration, additionalDirectives ...string) { directives := make([]string, 0, 2+len(additionalDirectives)) if setting.IsProd { if d == 0 { directives = append(directives, "no-store") } else { - directives = append(directives, "private") - directives = append(directives, "max-age="+strconv.Itoa(int(d.Seconds()))) + directives = append(directives, "private", "max-age="+strconv.Itoa(int(maxAge.Seconds()))) } } else { directives = append(directives, "no-store") @@ -34,8 +33,7 @@ func AddCacheControlToHeader(h http.Header, d time.Duration, additionalDirective h.Add("X-Gitea-Debug", "RUN_MODE="+setting.RunMode) } - directives = append(directives, additionalDirectives...) - h.Set("Cache-Control", strings.Join(directives, ", ")) + h.Set("Cache-Control", strings.Join(append(directives, additionalDirectives...), ", ")) } // generateETag generates an ETag based on size, filename and file modification time From 171294c4e2e842ac92bbcf32a9b1ef45f97c3656 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Fri, 22 Jul 2022 21:17:33 +0100 Subject: [PATCH 13/13] fix misnamed variable Signed-off-by: Andrew Thornton --- modules/httpcache/httpcache.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/httpcache/httpcache.go b/modules/httpcache/httpcache.go index 50d30565f67e1..750233d4a71c2 100644 --- a/modules/httpcache/httpcache.go +++ b/modules/httpcache/httpcache.go @@ -21,7 +21,7 @@ func AddCacheControlToHeader(h http.Header, maxAge time.Duration, additionalDire directives := make([]string, 0, 2+len(additionalDirectives)) if setting.IsProd { - if d == 0 { + if maxAge == 0 { directives = append(directives, "no-store") } else { directives = append(directives, "private", "max-age="+strconv.Itoa(int(maxAge.Seconds())))