From 49e5eb063c65721e62f9cae980b875e35dea6cb6 Mon Sep 17 00:00:00 2001 From: DarthSim Date: Mon, 10 Apr 2023 20:01:44 +0300 Subject: [PATCH] Refactor ETag checking in transports --- transport/azure/azure.go | 22 +++++++----------- transport/fs/fs.go | 28 ++++++++--------------- transport/gcs/gcs.go | 17 ++++---------- transport/notmodified/notmodified.go | 34 ++++++++++++++++++++++++++++ transport/swift/swift.go | 20 ++++------------ 5 files changed, 61 insertions(+), 60 deletions(-) create mode 100644 transport/notmodified/notmodified.go diff --git a/transport/azure/azure.go b/transport/azure/azure.go index 71c53a68..16183002 100644 --- a/transport/azure/azure.go +++ b/transport/azure/azure.go @@ -18,6 +18,7 @@ import ( "github.com/imgproxy/imgproxy/v3/config" "github.com/imgproxy/imgproxy/v3/ctxreader" "github.com/imgproxy/imgproxy/v3/httprange" + "github.com/imgproxy/imgproxy/v3/transport/notmodified" ) type transport struct { @@ -120,22 +121,15 @@ func (t transport) RoundTrip(req *http.Request) (*http.Response, error) { } if config.ETagEnabled && result.ETag != nil { - azETag := string(*result.ETag) - header.Set("ETag", azETag) + etag := string(*result.ETag) + header.Set("ETag", etag) + } - if etag := req.Header.Get("If-None-Match"); len(etag) > 0 && azETag == etag { - return &http.Response{ - StatusCode: http.StatusNotModified, - Proto: "HTTP/1.0", - ProtoMajor: 1, - ProtoMinor: 0, - Header: header, - ContentLength: 0, - Body: nil, - Close: false, - Request: req, - }, nil + if resp := notmodified.Response(req, header); resp != nil { + if result.Body != nil { + result.Body.Close() } + return resp, nil } header.Set("Accept-Ranges", "bytes") diff --git a/transport/fs/fs.go b/transport/fs/fs.go index 1797ba7c..c50677ef 100644 --- a/transport/fs/fs.go +++ b/transport/fs/fs.go @@ -16,6 +16,7 @@ import ( "github.com/imgproxy/imgproxy/v3/config" "github.com/imgproxy/imgproxy/v3/ctxreader" "github.com/imgproxy/imgproxy/v3/httprange" + "github.com/imgproxy/imgproxy/v3/transport/notmodified" ) type transport struct { @@ -73,27 +74,18 @@ func (t transport) RoundTrip(req *http.Request) (resp *http.Response, err error) body = &fileLimiter{f: f, left: int(size)} header.Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", start, end, fi.Size())) - case config.ETagEnabled: - etag := BuildEtag(req.URL.Path, fi) - header.Set("ETag", etag) - - if etag == req.Header.Get("If-None-Match") { - f.Close() - - return &http.Response{ - StatusCode: http.StatusNotModified, - Proto: "HTTP/1.0", - ProtoMajor: 1, - ProtoMinor: 0, - Header: header, - ContentLength: 0, - Body: nil, - Close: false, - Request: req, - }, nil + default: + if config.ETagEnabled { + etag := BuildEtag(req.URL.Path, fi) + header.Set("ETag", etag) } } + if resp := notmodified.Response(req, header); resp != nil { + f.Close() + return resp, nil + } + header.Set("Accept-Ranges", "bytes") header.Set("Content-Length", strconv.Itoa(int(size))) diff --git a/transport/gcs/gcs.go b/transport/gcs/gcs.go index e3f1f31d..9a0b589b 100644 --- a/transport/gcs/gcs.go +++ b/transport/gcs/gcs.go @@ -14,6 +14,7 @@ import ( "github.com/imgproxy/imgproxy/v3/config" "github.com/imgproxy/imgproxy/v3/ctxreader" "github.com/imgproxy/imgproxy/v3/httprange" + "github.com/imgproxy/imgproxy/v3/transport/notmodified" ) // For tests @@ -104,20 +105,10 @@ func (t transport) RoundTrip(req *http.Request) (*http.Response, error) { return handleError(req, err) } header.Set("ETag", attrs.Etag) + } - if etag := req.Header.Get("If-None-Match"); len(etag) > 0 && attrs.Etag == etag { - return &http.Response{ - StatusCode: http.StatusNotModified, - Proto: "HTTP/1.0", - ProtoMajor: 1, - ProtoMinor: 0, - Header: header, - ContentLength: 0, - Body: nil, - Close: false, - Request: req, - }, nil - } + if resp := notmodified.Response(req, header); resp != nil { + return resp, nil } var err error diff --git a/transport/notmodified/notmodified.go b/transport/notmodified/notmodified.go new file mode 100644 index 00000000..26e108cc --- /dev/null +++ b/transport/notmodified/notmodified.go @@ -0,0 +1,34 @@ +package notmodified + +import ( + "net/http" + + "github.com/imgproxy/imgproxy/v3/config" +) + +func Response(req *http.Request, header http.Header) *http.Response { + if config.ETagEnabled { + etag := header.Get("ETag") + ifNoneMatch := req.Header.Get("If-None-Match") + + if len(ifNoneMatch) > 0 && ifNoneMatch == etag { + return response(req, header) + } + } + + return nil +} + +func response(req *http.Request, header http.Header) *http.Response { + return &http.Response{ + StatusCode: http.StatusNotModified, + Proto: "HTTP/1.0", + ProtoMajor: 1, + ProtoMinor: 0, + Header: header, + ContentLength: 0, + Body: nil, + Close: false, + Request: req, + } +} diff --git a/transport/swift/swift.go b/transport/swift/swift.go index 79907b41..7a95dca6 100644 --- a/transport/swift/swift.go +++ b/transport/swift/swift.go @@ -13,6 +13,7 @@ import ( "github.com/imgproxy/imgproxy/v3/config" "github.com/imgproxy/imgproxy/v3/ctxreader" + "github.com/imgproxy/imgproxy/v3/transport/notmodified" ) type transport struct { @@ -76,22 +77,11 @@ func (t transport) RoundTrip(req *http.Request) (resp *http.Response, err error) if config.ETagEnabled { if etag, ok := objectHeaders["Etag"]; ok { header.Set("ETag", etag) + } - if len(etag) > 0 && etag == req.Header.Get("If-None-Match") { - object.Close() - - return &http.Response{ - StatusCode: http.StatusNotModified, - Proto: "HTTP/1.0", - ProtoMajor: 1, - ProtoMinor: 0, - Header: header, - ContentLength: 0, - Body: nil, - Close: false, - Request: req, - }, nil - } + if resp := notmodified.Response(req, header); resp != nil { + object.Close() + return resp, nil } }