Bug 243312 - Safari does not respect Cache-Control: no-store, no-transform header when loading images
Summary: Safari does not respect Cache-Control: no-store, no-transform header when loa...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: Images (show other bugs)
Version: Safari 15
Hardware: Mac (Apple Silicon) macOS 12
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2022-07-28 13:43 PDT by boris.brudnoy
Modified: 2022-08-04 13:44 PDT (History)
6 users (show)

See Also:


Attachments
test patch (28.91 KB, patch)
2022-07-29 09:29 PDT, Alexey Proskuryakov
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description boris.brudnoy 2022-07-28 13:43:40 PDT
I create <img href="/data/sharing/qrcode"> elements dynamically in a web app and I have an HTTP service that receives GET requests like this:

GET /data/sharing/qrcode HTTP/1.1
Accept: image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15
Accept-Language: en-CA,en-US;q=0.9,en;q=0.8
Connection: keep-alive

and responds like this:

HTTP/1.1 200 OK
Content-Type: image/png
Date: Thu, 28 Jul 2022 20:08:54 GMT
Content-Length: 425
Expires: Thu, 28 Jul 2022 20:08:54 GMT
Cache-Control: no-store, no-transform

Despite the presence of Cache-Control: no-store, no-transform, subsequent dynamically created <img> elements don't trigger new network requests, instead evidently using a cached image. When running the same web app in Chrome (Version 103.0.5060.134) I'm observing the behavior that seems expected to me, i.e. each time an <img> element like the above is created, a new HTTP request is issued.
Comment 1 Alexey Proskuryakov 2022-07-29 09:29:06 PDT
Created attachment 461297 [details]
test patch

My understanding is that this is technically correct behavior. Will keep this open for consideration as a large difference with Chrome though.

From browser point of view, Cache-Control is irrelevant here, because it only affects behavior of HTTP cache. The browser is not obligated to make an HTTP request in this scenario, as it already has the image available at a much higher level than HTTP.

From web server point of view, it is a server bug to return different images for the same GET request, see <https://developer.mozilla.org/en-US/docs/Glossary/Idempotent>. Trying to do this will result in problems in more cases than just this.

Adding a test in the form of a patch to apply to WebKit tree, and to use with run-webkit-httpd.
Comment 2 boris.brudnoy 2022-07-29 11:33:02 PDT
I omitted mentioning that the aforementioned service sends back QR code images encoding the GET request's 'Referer' URL, and so images are different only for requests with differing Referer URLs.

Are two GET requests still considered the same if their request headers differ? I couldn't find a definitive answer on that.

Could you elaborate on levels of caching? If a DOM element relies on data it retrieves via HTTP, isn't this by definition either an HTTP cache hit or a network request going out? In this case I would expect cache-related response headers to be honored, which Chrome seems to be doing.

Thanks for looking into this.
Comment 3 Alexey Proskuryakov 2022-07-29 13:13:39 PDT
> Are two GET requests still considered the same if their request headers differ? I couldn't find a definitive answer on that.

In theory, HTTP caches are informed about which request header fields to care about using the response Vary header field, https://httpwg.org/specs/rfc7231.html#header.vary. Actual implementations may have various special cases added over the years as workarounds.
Comment 4 boris.brudnoy 2022-07-30 02:40:34 PDT
Since I control the image service I added a Vary: referer header to responses and confirmed that Safari then started issuing new GET requests for <img>s upon change in referrer URL. The responses now look like:

HTTP/1.1 200 OK
Content-Type: image/png
Cache-Control: no-store, no-transform
Vary: Referer
SameSite=Lax
Date: Sat, 30 Jul 2022 09:38:58 GMT
Expires: Sat, 30 Jul 2022 09:38:58 GMT
Content-Length: 425
Comment 5 Radar WebKit Bug Importer 2022-08-04 13:44:16 PDT
<rdar://problem/98145790>