Can't cache and serve redirected response |
||||||
Issue descriptionChrome Version : 63.0.3239.132 OS: linux and mac Repro attached as zip file. What steps will reproduce the problem? (1) extract repro into directory (2) start both servers (see next 2 steps for commands) (3) python server.py (3) python server2.py (4) use chrome to open http://localhost:8084 (5) click button "Fetch with 302" (should verify that response is in CacheStorage after this) (6) click button "Download with form button" You can click "Clear cache" button to clean up cache if you want. What is the expected result? - I would expect that the file gets served properly as a download out of CacheStorage via service-worker intercept. What happens instead? - File response is not served properly. There is an error about fetch not being able to follow redirects Its possible that this is according to spec and my code is wrong. If so I just need to know how to make this work with 302. Our current workaround is to serve a 200 with a redirectURL as text response instead of a 302. You can see how this works in the demo by using the button "Fetch without 302" instead (which ends up working)
,
Jan 8 2018
,
Jan 9 2018
,
Jan 9 2018
Thanks for the report. This doesn't look confidential: can I open this bug to the public? +horo: can you help investigate this? This is possibly WAI but there is a compat issue compared to Firefox. The response being cached has the `redirected` flag set, so it can't be used to respond to the request for "Download" which has redirect mode "manual". This is an intentional security restriction: some background is at issue 658249 and https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/ZPaAeG3N0tw But in Firefox's case, the cached response has redirected == false, so the response works there. The cached response comes by way of: 1. page: calls fetch('/file') 2. sw: calls fetch(e.request) 3. server: returns 302 to cross-origin url 4. sw: returns the response 5. page: caches the response It seems to make sense that the Response that arrives at the page should have redirected == true set. Assuming that Chrome's behavior is WAI, and you want to get this to work with 302 instead of 200, I think you'd need to avoid caching the response directly from a redirect, and instead use fetch with redirect: 'manual' to get a redirect response that you then manually call fetch() on again: e.g., sw or page does fetch('/file', { mode: 'cors', redirect: 'manual' }), then gets a Response from which it can get the destination and then call fetch(destination). However this doesn't seem to work, the Response comes back as 'opaqueredirect'.
,
Jan 9 2018
I think this is working as intended.
If you add "Access-Control-Expose-Headers" header in server2.py:
> self.send_header('Access-Control-Expose-Headers', 'Content-Disposition')
and create a new Response in sw.js using the cached redirected response:
> if (response.redirected) {
> response = new Response(response.body, { headers: response.headers });
> }
you can download the woohoo.pdf from CacheStorage.
,
Jan 9 2018
Confirmed that this is the case. (regarding #5)
,
Jan 9 2018
Regarding #4 yes you can open it.
,
Jan 10 2018
#7: thanks, opening it up. bkelly: See the original bug report and comment #4. It seems like a Firefox bug that Response.redirected is true in Chrome and false in Firefox.
,
Jan 10 2018
Based on c#5, I think this is working as intended, so closing the bug. It'd be good to have WPT test coverage, if it doesn't already exist.
,
Jan 10 2018
Thanks for the report. I investigated and its something we recently fixed in firefox 59: https://bugzilla.mozilla.org/show_bug.cgi?id=1222008 The issue here is that the site is using Cache API in the window. So the `Response.redirected` must be passed from the inner service worker fetch through the network synthesize step to the outer page fetch(). Since we previously did expose the final Response.url through service worker interception we also did not expose the redirected flag. A workaround is to store the Response in the Cache API in the service worker. This avoids the above issue since the Response does not need to go through the interception step to propagate the .redirected property. Anyway, we should be aligned in FF59 shipping mid-March. Note, there is a WPT test for exposing Response.redirected through a service worker interception here: https://github.com/w3c/web-platform-tests/blob/025b987042e4ecbb4db438299d649df8c575b375/service-workers/service-worker/redirected-response.https.html#L169 FF57 and FF58 fail that test, but we pass it now in FF59.
,
Jan 11 2018
bkelly: Thanks for confirming! I usually test against Firefox Nightly. I must have accidentally used a release version. |
||||||
►
Sign in to add a comment |
||||||
Comment 1 by rjfioravanti@google.com
, Jan 8 2018247 KB
247 KB Download