Bug 82672

Summary: [Mac] XHR range requests are broken; affects pdf.js (Test failure: http/tests/xmlhttprequest/range-test.html)
Product: WebKit Reporter: Enrica Casucci <enrica>
Component: XMLAssignee: Nobody <webkit-unassigned>
Severity: Normal CC: abarth, ap, barraclough, beidson, brion, ddkilzer, eoconnor, hughw, japhet, johan.poirier, koivisto, mrtnpaolo, silviapf, simon.fraser, webkit-bug-importer
Priority: P2 Keywords: InRadar, LayoutTestFailure
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   

Description Enrica Casucci 2012-03-29 15:48:39 PDT
Not sure when this started.
Adding to skip list. Please remove when this is fixed.
Comment 1 Radar WebKit Bug Importer 2012-03-29 15:49:23 PDT
Comment 2 Simon Fraser (smfr) 2012-09-19 16:07:54 PDT
Still fails.
Comment 3 Alexey Proskuryakov 2012-09-20 09:36:49 PDT
I suspect that CFNetwork is not giving us 206 responses when it already has complete ones cached.
Comment 4 Hugh Winkler 2012-12-22 10:48:14 PST
A workaround for this bug is to suppress caching for each XHR with a Range header, using:

xhr.setRequestHeader('Cache-control", "no-cache");
Comment 5 David Kilzer (:ddkilzer) 2013-06-12 10:20:52 PDT
When running the layout test (and deleting the line in LayoutTests/platform/mac/TestExpectations that expects a failure), this is how the test fails:

--- layout-test-results/http/tests/xmlhttprequest/range-test-expected.txt
+++ layout-test-results/http/tests/xmlhttprequest/range-test-actual.txt
@@ -1,9 +1,11 @@
 Test Range support in XMLHttpRequest
 getRange(resources/reply.xml, 34, 36, false)
-Length : expected 2 got 2
+Expected a 206 response, got 200
+Length : expected 2 got 68
 getRange(resources/reply.xml, 35, 38, false)
-Length : expected 3 got 3
+Expected a 206 response, got 200
+Length : expected 3 got 68
 getRange(resources/reply.xml, 34, 36, true)
 Length : expected 2 got 2
 getRange(resources/reply.xml, 35, 38, true)
Comment 6 David Kilzer (:ddkilzer) 2013-06-12 10:38:45 PDT
Yesterday at WWDC, a developer asked a question about pdf.js being broken for Mac Safari 6.0.x and Safari for iOS 6.x.  I believe this may be the bug that's causing that issue.

These are the relevant pdf.js bugs and commits that track the issue:

Pdf.js not working in safari browser on MAC OSX 10.8.2, safari version 6.0.1

Does not work on Safari mobile

Disable range request loading for safari.

Failing in Safari
Comment 7 Paolo Martini 2014-02-26 15:33:15 PST
I've just finished a long debugging session on a product that uses XHR range requests to fetch particular files from zip archives hosted on the server. I found a new work-around for the Safari bug. It has been tested and verified working on:

- OS X Mountain Lion - Safari Version 6.0.5 (8536.30.1)
- OS X Mavericks - Safari Version 7.0.1 (9537.73.11)
- iOS 7.0.6 (11B651)

The problem: the second request to the same file for a different range returns the same contents as the first one. Safari wrongly reports "Cached: no" in the relevant line of the network tab of the developer tools. It also ignores "pragma=no-cache" headers, if added.

The solution: I succeeded in making it throw away the old request by making each request unique. I accomplished this by generating a random string and adding the following header: If-None-Match: "<random string>".

After this change Safari began returning the right contents from the new specified range of the file.

This should let the web developers deploy a new and better work-around for their products instead of resorting to disabling range requests altogether. I also hope it can help the webkit developers in pin-pointing where this problem stems from.
Comment 8 Alexey Proskuryakov 2014-10-27 11:27:02 PDT
This tests passes on Yosemite with both WK1 and WK2. But it still fails in Safari.

This may mean that HTTP caching is somehow broken in regression tests on Yosemite, which hides the problem.
Comment 9 Silvia Pfeiffer 2014-11-09 15:55:52 PST
Note that https://github.com/gildas-lormeau/zip.js/pull/91/files uses the following header as a work-around:

xhr.setRequestHeader("If-None-Match", "webkit-no-cache");

which may be more interoperable with other browsers.
Comment 10 Silvia Pfeiffer 2014-11-09 16:00:36 PST
Note there is a similar issue with the Vary header:
Comment 11 Brion Vibber 2014-11-09 16:13:02 PST
I've found that this bug can at least be easily detected at runtime by checking the HTTP status code and Content-Range response header against the expected values. You can then issue a second request with caching disabled and continue on, without hardcoding assumptions about User-Agent strings.

In ogv.js <https://github.com/brion/ogv.js/commit/9ab5bce2f99f13a82a07ab83eeae77ede031e620> I'm using such a check to only apply cache-busting if the bug is actually encountered.

At least on OS X 10.10 I'm seeing the bug only after reaching the *end* of the file; so for the ogv.js media player case this doesn't hit until a second playthrough, unless the file is missing index information in which case a seek to the end is used to calculate the duration before playback begins.

(Note I'm using a query-string as cache-buster so that the request will still be cacheable on the server-side proxy cache; though not ideal it seems to be working.)
Comment 12 Brion Vibber 2015-07-02 06:21:49 PDT
I'm getting the same behavior in a native iOS app using NSURLConnection to download chunks with a Range: header, so this indeed seems to be a low-level CFNetwork caching issue...
Comment 13 David Kilzer (:ddkilzer) 2015-07-03 08:45:26 PDT
WebKit has a new network cache, and this bug is fixed in that implementation via:

Bug 144682: Network Cache: Layout Test http/tests/xmlhttprequest/range-test.html is failing

Please try WebKit Nightly build at <http://nightly.webkit.org/> to verify.

We're still tracking the NSURLCache issue via Radar (<rdar://problem/11150946>).
Comment 14 David Kilzer (:ddkilzer) 2015-07-03 08:46:14 PDT
Marking as forward dupe for tracking purposes.

*** This bug has been marked as a duplicate of bug 144682 ***
Comment 15 Brion Vibber 2015-07-03 10:01:51 PDT
(In reply to comment #13)
> WebKit has a new network cache, and this bug is fixed in that implementation
> via:
> Bug 144682: Network Cache: Layout Test
> http/tests/xmlhttprequest/range-test.html is failing
> <https://bugs.webkit.org/show_bug.cgi?id=144682>
> Please try WebKit Nightly build at <http://nightly.webkit.org/> to verify.

Looks good with a current nightly -- my workaround from comment 11 gracefully disables itself. Thanks!

> We're still tracking the NSURLCache issue via Radar
> (<rdar://problem/11150946>).