From 66eb3ffe4a4ed43b0f80eb4f8561fb83e615d25d Mon Sep 17 00:00:00 2001 From: Umputun Date: Tue, 27 Apr 2021 01:40:46 -0500 Subject: [PATCH] support d units in cache duration --- README.md | 2 +- app/proxy/cache_control.go | 18 ++++++++++++++++-- app/proxy/cache_control_test.go | 5 +++-- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5160725..d89aab1 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ In addition to the common assets server, multiple custom static servers are supp 2. file provider - setting optional field `assets: true` 3. docker provider - `reproxy.assets=web-root:location`, i.e. `reproxy.assets=/web:/var/www`. -Assets server supports caching control with the `--assets.cache=` parameter. `0s` duration (default) turns caching control off. A duration is a sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". +Assets server supports caching control with the `--assets.cache=` parameter. `0s` duration (default) turns caching control off. A duration is a sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h" and "d". There are two ways to set cache duration: 1. A single value for all static assets. This is as simple as `--assets.cache=48h`. diff --git a/app/proxy/cache_control.go b/app/proxy/cache_control.go index 3337be1..b91c3f4 100644 --- a/app/proxy/cache_control.go +++ b/app/proxy/cache_control.go @@ -67,6 +67,18 @@ func (c *CacheControl) Middleware(next http.Handler) http.Handler { // the first param represents default age and can be just a duration string (i.e. 60h) or "default:60h" // all other params are mime:duration pairs, i.e. "text/html:30s" func MakeCacheControl(cacheOpts []string) (*CacheControl, error) { + + parseDuration := func(s string) (time.Duration, error) { + if strings.HasSuffix(s, "d") { // add parsing 123d as days + days, err := strconv.Atoi(strings.TrimSuffix(s, "d")) + if err != nil { + return 0, fmt.Errorf("can't parse %q as duration: %w", s, err) + } + return time.Hour * 24 * time.Duration(days), nil + } + return time.ParseDuration(s) + } + if len(cacheOpts) == 0 { return NewCacheControl(0), nil } @@ -74,7 +86,7 @@ func MakeCacheControl(cacheOpts []string) (*CacheControl, error) { // first elements may define default in both "10s" and "default:10s" forms if !strings.Contains(cacheOpts[0], ":") { // single element, i.e 10s - dur, err := time.ParseDuration(cacheOpts[0]) + dur, err := parseDuration(cacheOpts[0]) if err != nil { return nil, fmt.Errorf("can't parse default cache duration: %w", err) } @@ -86,10 +98,12 @@ func MakeCacheControl(cacheOpts []string) (*CacheControl, error) { if elems[0] != "default" { return nil, fmt.Errorf("first cache duration has to be for the default mime") } - dur, err := time.ParseDuration(elems[1]) + + dur, err := parseDuration(elems[1]) if err != nil { return nil, fmt.Errorf("can't parse default cache duration: %w", err) } + res = NewCacheControl(dur) } diff --git a/app/proxy/cache_control_test.go b/app/proxy/cache_control_test.go index a3dfe14..0eef42d 100644 --- a/app/proxy/cache_control_test.go +++ b/app/proxy/cache_control_test.go @@ -93,11 +93,12 @@ func TestMakeCacheControl(t *testing.T) { err error }{ {nil, time.Duration(0), nil, nil}, + {[]string{"12d"}, 12 * 24 * time.Hour, nil, nil}, {[]string{"12h"}, 12 * time.Hour, nil, nil}, {[]string{"default:12h"}, 12 * time.Hour, nil, nil}, {[]string{"blah:12h"}, 0, nil, errors.New("first cache duration has to be for the default mime")}, - {[]string{"a12bad"}, 0, nil, errors.New(`can't parse default cache duration: time: invalid duration "a12bad"`)}, - {[]string{"default:a12bad"}, 0, nil, errors.New(`can't parse default cache duration: time: invalid duration "a12bad"`)}, + {[]string{"a12nop"}, 0, nil, errors.New(`can't parse default cache duration: time: invalid duration "a12nop"`)}, + {[]string{"default:a12badone"}, 0, nil, errors.New(`can't parse default cache duration: time: invalid duration "a12badone"`)}, {[]string{"12h", "text/html:10h", "image/png:6h"}, 12 * time.Hour, map[string]time.Duration{"text/html": 10 * time.Hour, "image/png": 6 * time.Hour}, nil},