aboutsummaryrefslogtreecommitdiffstats
path: root/modules/httpcache
diff options
context:
space:
mode:
authorzeripath <art27@cantab.net>2022-05-09 16:54:51 +0100
committerGitHub <noreply@github.com>2022-05-09 17:54:51 +0200
commit9f5ddca57c38f566fb18c9add339fc9f5aeb25de (patch)
treee9cba2540901589f98410b7d3ad23078a7dff11b /modules/httpcache
parente435283c0ffe437f35898f92dc5572c8df83163e (diff)
downloadgitea-9f5ddca57c38f566fb18c9add339fc9f5aeb25de.tar.gz
gitea-9f5ddca57c38f566fb18c9add339fc9f5aeb25de.zip
Set the LastModified header for raw files (#18356)
Although the use of LastModified dates for caching of git objects should be discouraged (as it is not native to git - and there are a LOT of ways this could be incorrect) - LastModified dates can be a helpful somewhat more human way of caching for simple cases. This PR adds this header and handles the If-Modified-Since header to the /raw/ routes. Fix #18354 Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: 6543 <6543@obermui.de>
Diffstat (limited to 'modules/httpcache')
-rw-r--r--modules/httpcache/httpcache.go39
1 files changed, 37 insertions, 2 deletions
diff --git a/modules/httpcache/httpcache.go b/modules/httpcache/httpcache.go
index 11b63148d9..5797e981cf 100644
--- a/modules/httpcache/httpcache.go
+++ b/modules/httpcache/httpcache.go
@@ -37,18 +37,23 @@ func generateETag(fi os.FileInfo) string {
// HandleTimeCache handles time-based caching for a HTTP request
func HandleTimeCache(req *http.Request, w http.ResponseWriter, fi os.FileInfo) (handled bool) {
+ return HandleGenericTimeCache(req, w, fi.ModTime())
+}
+
+// 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)
ifModifiedSince := req.Header.Get("If-Modified-Since")
if ifModifiedSince != "" {
t, err := time.Parse(http.TimeFormat, ifModifiedSince)
- if err == nil && fi.ModTime().Unix() <= t.Unix() {
+ if err == nil && lastModified.Unix() <= t.Unix() {
w.WriteHeader(http.StatusNotModified)
return true
}
}
- w.Header().Set("Last-Modified", fi.ModTime().Format(http.TimeFormat))
+ w.Header().Set("Last-Modified", lastModified.Format(http.TimeFormat))
return false
}
@@ -85,3 +90,33 @@ func checkIfNoneMatchIsValid(req *http.Request, etag string) bool {
}
return false
}
+
+// HandleGenericETagTimeCache handles ETag-based caching with Last-Modified caching for a HTTP request.
+// It returns true if the request was handled.
+func HandleGenericETagTimeCache(req *http.Request, w http.ResponseWriter, etag string, lastModified time.Time) (handled bool) {
+ if len(etag) > 0 {
+ w.Header().Set("Etag", etag)
+ }
+ if !lastModified.IsZero() {
+ w.Header().Set("Last-Modified", lastModified.Format(http.TimeFormat))
+ }
+
+ if len(etag) > 0 {
+ if checkIfNoneMatchIsValid(req, etag) {
+ w.WriteHeader(http.StatusNotModified)
+ return true
+ }
+ }
+ if !lastModified.IsZero() {
+ ifModifiedSince := req.Header.Get("If-Modified-Since")
+ if ifModifiedSince != "" {
+ t, err := time.Parse(http.TimeFormat, ifModifiedSince)
+ if err == nil && lastModified.Unix() <= t.Unix() {
+ w.WriteHeader(http.StatusNotModified)
+ return true
+ }
+ }
+ }
+ AddCacheControlToHeader(w.Header(), setting.StaticCacheTime)
+ return false
+}