From 12f2d48d30b45485c8d08701bca7352ef0762051 Mon Sep 17 00:00:00 2001 From: sl Date: Wed, 4 Mar 2020 18:18:47 +0100 Subject: [PATCH] added validuntil option --- .gitignore | 2 ++ cmd/imageproxy-sign/main_test.go | 3 +++ data.go | 17 +++++++++++++++++ imageproxy.go | 13 ++++++++++--- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 2b2d52b5f..8fc0b8ebd 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ vendor/**/CONTRIBUTORS vendor/**/Makefile vendor/**/*_ZH.md vendor/**/*.sh + +cmd/imageproxy*/imageproxy* diff --git a/cmd/imageproxy-sign/main_test.go b/cmd/imageproxy-sign/main_test.go index d9a6df662..f62d43794 100644 --- a/cmd/imageproxy-sign/main_test.go +++ b/cmd/imageproxy-sign/main_test.go @@ -131,6 +131,9 @@ func TestParseURL(t *testing.T) { // ensure signature values are stripped {"http://localhost:8080/sc0ffee/http://example.com/", "http://example.com/#0x0"}, {"http://example.com/#sc0ffee", "http://example.com/#0x0"}, + + // validuntil + {"http://localhost:8080/vu20200304/http://example.com/", "http://example.com/#0x0,vu20200304"}, } for _, tt := range tests { diff --git a/data.go b/data.go index 424f4acc3..8fb3b8733 100644 --- a/data.go +++ b/data.go @@ -41,6 +41,7 @@ const ( optCropWidth = "cw" optCropHeight = "ch" optSmartCrop = "sc" + optValidUntil = "vu" ) // URLError reports a malformed URL error. @@ -91,6 +92,9 @@ type Options struct { // Automatically find good crop points based on image content. SmartCrop bool + + // Check if the URL is still valid in conjunction with a signature you can not change validity of a request. + ValidUntil int } func (o Options) String() string { @@ -134,7 +138,12 @@ func (o Options) String() string { if o.SmartCrop { opts = append(opts, optSmartCrop) } + if o.ValidUntil > 0 { + opts = append(opts, fmt.Sprintf("%s%d", optValidUntil, o.ValidUntil)) + } + sort.Strings(opts) + return strings.Join(opts, ",") } @@ -230,6 +239,11 @@ func (o Options) transform() bool { // See https://github.com/willnorris/imageproxy/blob/master/docs/url-signing.md // for examples of generating signatures. // +// Validity +// +// The "vu{date}" option specifies a date until the request is valid. Please keep in mind +// to not harm your browser caching TTL settings. +// // Examples // // 0x0 - no resizing @@ -283,6 +297,9 @@ func ParseOptions(str string) Options { case strings.HasPrefix(opt, optCropHeight): value := strings.TrimPrefix(opt, optCropHeight) options.CropHeight, _ = strconv.ParseFloat(value, 64) + case strings.HasPrefix(opt, optValidUntil): + value := strings.TrimPrefix(opt, optValidUntil) + options.ValidUntil, _ = strconv.Atoi(value) case strings.Contains(opt, optSizeDelimiter): size := strings.SplitN(opt, optSizeDelimiter, 2) if w := size[0]; w != "" { diff --git a/imageproxy.go b/imageproxy.go index 6721056ea..265982371 100644 --- a/imageproxy.go +++ b/imageproxy.go @@ -186,7 +186,6 @@ func (p *Proxy) serveImage(w http.ResponseWriter, r *http.Request) { copyHeader(actualReq.Header, r.Header, "referer") } resp, err := p.Client.Do(actualReq) - if err != nil { msg := fmt.Sprintf("error fetching remote image: %v", err) p.log(msg) @@ -229,7 +228,7 @@ func (p *Proxy) serveImage(w http.ResponseWriter, r *http.Request) { copyHeader(w.Header(), resp.Header, "Content-Length") - //Enable CORS for 3rd party applications + // Enable CORS for 3rd party applications w.Header().Set("Access-Control-Allow-Origin", "*") w.WriteHeader(resp.StatusCode) @@ -267,14 +266,22 @@ var ( errReferrer = errors.New("request does not contain an allowed referrer") errDeniedHost = errors.New("request contains a denied host") errNotAllowed = errors.New("request does not contain an allowed host or valid signature") + errNotValid = errors.New("request is no longer valid") msgNotAllowed = "requested URL is not allowed" ) // allowed determines whether the specified request contains an allowed // referrer, host, and signature. It returns an error if the request is not -// allowed. +// allowed or not valid any longer. func (p *Proxy) allowed(r *Request) error { + if r.Options.ValidUntil > 0 { + y, m, d := time.Now().Date() + if r.Options.ValidUntil < y*10000+int(m)*100+d { + return errNotValid + } + } + if len(p.Referrers) > 0 && !referrerMatches(p.Referrers, r.Original) { return errReferrer }