From b92de43cf3fd67d76b3b585a480f7273f9d96e90 Mon Sep 17 00:00:00 2001 From: DarthSim Date: Tue, 11 Apr 2023 21:08:39 +0300 Subject: [PATCH] Add support for client hints prefixed with Sec-CH-; Remove Viewport-Width header support --- CHANGELOG.md | 5 +++++ docs/configuration.md | 4 ++-- options/processing_options.go | 16 ++++++++------ options/processing_options_test.go | 34 ------------------------------ processing_handler.go | 2 +- 5 files changed, 18 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46e7c038..b40458f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ # Changelog ## [Unreleased] +### Add +- Add support for `Sec-CH-DPR` and `Sec-CH-Width` client hints. + +### Remove +- Remove suport for `Viewport-Width` client hint. ## [3.15.0] - 2023-04-10 ### Add diff --git a/docs/configuration.md b/docs/configuration.md index 46adb501..bca4e403 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -249,11 +249,11 @@ Check out the [Best format](best_format.md) guide to learn more. ## Client Hints support -imgproxy can use the `Width`, `Viewport-Width` or `DPR` HTTP headers to determine default width and DPR options using Client Hints. This feature is disabled by default and can be enabled by the following option: +imgproxy can use the `Width` and `DPR` HTTP headers to determine default width and DPR options using Client Hints. This feature is disabled by default and can be enabled by the following option: * `IMGPROXY_ENABLE_CLIENT_HINTS`: enables Client Hints support to determine default width and DPR options. Read more details [here](https://developers.google.com/web/updates/2015/09/automating-resource-selection-with-client-hints) about Client Hints. -**⚠️ Warning:** Headers cannot be signed. This means that an attacker can bypass your CDN cache by changing the `Width`, `Viewport-Width` or `DPR` HTTP headers. Keep this in mind when configuring your production caching setup. +**⚠️ Warning:** Headers cannot be signed. This means that an attacker can bypass your CDN cache by changing the `Width` or `DPR` HTTP headers. Keep this in mind when configuring your production caching setup. ## Video thumbnails diff --git a/options/processing_options.go b/options/processing_options.go index 2663f1c2..43363264 100644 --- a/options/processing_options.go +++ b/options/processing_options.go @@ -1087,17 +1087,21 @@ func defaultProcessingOptions(headers http.Header) (*ProcessingOptions, error) { } if config.EnableClientHints { - if headerDPR := headers.Get("DPR"); len(headerDPR) > 0 { + headerDPR := headers.Get("Sec-CH-DPR") + if len(headerDPR) == 0 { + headerDPR = headers.Get("DPR") + } + if len(headerDPR) > 0 { if dpr, err := strconv.ParseFloat(headerDPR, 64); err == nil && (dpr > 0 && dpr <= maxClientHintDPR) { po.Dpr = dpr } } - if headerViewportWidth := headers.Get("Viewport-Width"); len(headerViewportWidth) > 0 { - if vw, err := strconv.Atoi(headerViewportWidth); err == nil { - po.Width = vw - } + + headerWidth := headers.Get("Sec-CH-Width") + if len(headerWidth) == 0 { + headerWidth = headers.Get("Width") } - if headerWidth := headers.Get("Width"); len(headerWidth) > 0 { + if len(headerWidth) > 0 { if w, err := strconv.Atoi(headerWidth); err == nil { po.Width = imath.Scale(w, 1/po.Dpr) } diff --git a/options/processing_options_test.go b/options/processing_options_test.go index 181d29bb..4727c041 100644 --- a/options/processing_options_test.go +++ b/options/processing_options_test.go @@ -439,40 +439,6 @@ func (s *ProcessingOptionsTestSuite) TestParsePathWidthHeaderRedefine() { require.Equal(s.T(), 150, po.Width) } -func (s *ProcessingOptionsTestSuite) TestParsePathViewportWidthHeader() { - config.EnableClientHints = true - - path := "/plain/http://images.dev/lorem/ipsum.jpg@png" - headers := http.Header{"Viewport-Width": []string{"100"}} - po, _, err := ParsePath(path, headers) - - require.Nil(s.T(), err) - - require.Equal(s.T(), 100, po.Width) -} - -func (s *ProcessingOptionsTestSuite) TestParsePathViewportWidthHeaderDisabled() { - path := "/plain/http://images.dev/lorem/ipsum.jpg@png" - headers := http.Header{"Viewport-Width": []string{"100"}} - po, _, err := ParsePath(path, headers) - - require.Nil(s.T(), err) - - require.Equal(s.T(), 0, po.Width) -} - -func (s *ProcessingOptionsTestSuite) TestParsePathViewportWidthHeaderRedefine() { - config.EnableClientHints = true - - path := "/width:150/plain/http://images.dev/lorem/ipsum.jpg@png" - headers := http.Header{"Viewport-Width": []string{"100"}} - po, _, err := ParsePath(path, headers) - - require.Nil(s.T(), err) - - require.Equal(s.T(), 150, po.Width) -} - func (s *ProcessingOptionsTestSuite) TestParsePathDprHeader() { config.EnableClientHints = true diff --git a/processing_handler.go b/processing_handler.go index 8f31355b..f95bc32c 100644 --- a/processing_handler.go +++ b/processing_handler.go @@ -49,7 +49,7 @@ func initProcessingHandler() { } if config.EnableClientHints { - vary = append(vary, "DPR", "Viewport-Width", "Width") + vary = append(vary, "Sec-CH-DPR", "DPR", "Sec-CH-Width", "Width") } headerVaryValue = strings.Join(vary, ", ")