diff --git a/cmd/proxy/main.go b/cmd/proxy/main.go index 947c9f7..5f1e37f 100644 --- a/cmd/proxy/main.go +++ b/cmd/proxy/main.go @@ -10,6 +10,7 @@ import ( "os" "path/filepath" "regexp" + "slices" "strings" "sync" "time" @@ -60,8 +61,14 @@ type Storage struct { Accel Accel `yaml:"accel"` } +type CachePolicyOnPath struct { + Match string `yaml:"match"` + RefreshAfter string `yaml:"refresh-after"` +} + type Cache struct { - Timeout time.Duration `yaml:"timeout"` + RefreshAfter time.Duration `yaml:"refresh-after"` + Policies []CachePolicyOnPath `yaml:"policies"` } type MiscConfig struct { @@ -162,7 +169,7 @@ func configFromFile(path string) (*Config, error) { ChunkBytes: 1024 * 1024, }, Cache: Cache{ - Timeout: time.Hour, + RefreshAfter: time.Hour, }, } @@ -249,7 +256,26 @@ const ( func (server *Server) checkLocal(w http.ResponseWriter, _ *http.Request, key string) (exists localStatus, mtime time.Time, err error) { if stat, err := os.Stat(key); err == nil { - if mtime := stat.ModTime(); mtime.Add(server.Cache.Timeout).Before(time.Now()) { + refreshAfter := server.Cache.RefreshAfter + refresh := "" + + for _, policy := range server.Cache.Policies { + if match, err := regexp.MatchString(policy.Match, key); err != nil { + return 0, zeroTime, err + } else if match { + if dur, err := time.ParseDuration(policy.RefreshAfter); err != nil { + if slices.Contains([]string{"always", "never"}, policy.RefreshAfter) { + refresh = policy.RefreshAfter + } else { + return 0, zeroTime, err + } + } else { + refreshAfter = dur + } + break + } + } + if mtime := stat.ModTime(); mtime.Add(refreshAfter).Before(time.Now()) || refresh == "always" && refresh != "never" { return localExistsButNeedHead, mtime.In(time.UTC), nil } return localExists, mtime.In(time.UTC), nil diff --git a/config.yaml b/config.yaml index b314238..4ea39d6 100644 --- a/config.yaml +++ b/config.yaml @@ -40,6 +40,12 @@ misc: first-chunk-bytes: 31457280 # 1024*1024*30, all upstreams with 200 response will wait for the first chunks to select a upstream by bandwidth, instead of by latency. defaults to 50M # chunk-bytes: 1048576 # 1024*1024 +cache: + timeout: 1h + policies: + - match: '.*\.(rpm|deb)$' + fresh-after: never + storage: type: local # ignored local: