- Revision
- 285210
- Author
- [email protected]
- Date
- 2021-11-03 09:52:28 -0700 (Wed, 03 Nov 2021)
Log Message
[iOS] AVAssetResourceLoadingRequest.request does not include a Range: header on iOS 15.
https://bugs.webkit.org/show_bug.cgi?id=232195
<rdar://84574375>
Reviewed by Darin Adler.
Source/WebCore:
Explicitly add a Range: header for Blob requests which do not have one (but otherwise should).
Test: platform/mac/media/video-blob-request-contains-range-header.html
Drive-by fix: to allow this change to be testable, we must revert a change which calls all the
network delegate callbacks with empty data. This was necessary at the time because (at least for
Cocoa ports) media loading happened outside WebCore's loader path. Currently, all http(s), data,
blob, and custom protocol schemes are loaded through WebCore, leaving file:// URLs as the
remaining protocol type that needs custom handling, and only on Cocoa ports.
Further drive-by fix: WebKitLegacy's network delegate client operates synchronously during
requestResource(), so WebCoreNSURLSession must synthesize an error if that method returns a
nil resource.
* platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm:
(WebCore::WebCoreAVFResourceLoader::startLoading):
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::loadResource):
* platform/network/cocoa/WebCoreNSURLSession.mm:
(-[WebCoreNSURLSessionDataTask _restart]):
LayoutTests:
The existing media-blocked-by-willsendrequest.html test only verified that file:// URLs were blocked,
not http://, so this test is moved to the http/tests/ directory where media will use http:// for loading.
* http/tests/media/media-blocked-by-willsendrequest-expected.txt: Renamed from LayoutTests/media/media-blocked-by-willsendrequest-expected.txt.
* http/tests/media/media-blocked-by-willsendrequest.html: Renamed from LayoutTests/media/media-blocked-by-willsendrequest.html.
* platform/mac/media/video-blob-request-contains-range-header.html:
* platform/mac/media/video-blob-request-contains-range-header-expected.txt: Added.
* platform/mac/media/video-blob-request-contains-range-header.html: Added.
Modified Paths
Added Paths
Removed Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (285209 => 285210)
--- trunk/LayoutTests/ChangeLog 2021-11-03 16:40:39 UTC (rev 285209)
+++ trunk/LayoutTests/ChangeLog 2021-11-03 16:52:28 UTC (rev 285210)
@@ -1,3 +1,20 @@
+2021-11-03 Jer Noble <[email protected]>
+
+ [iOS] AVAssetResourceLoadingRequest.request does not include a Range: header on iOS 15.
+ https://bugs.webkit.org/show_bug.cgi?id=232195
+ <rdar://84574375>
+
+ Reviewed by Darin Adler.
+
+ The existing media-blocked-by-willsendrequest.html test only verified that file:// URLs were blocked,
+ not http://, so this test is moved to the http/tests/ directory where media will use http:// for loading.
+
+ * http/tests/media/media-blocked-by-willsendrequest-expected.txt: Renamed from LayoutTests/media/media-blocked-by-willsendrequest-expected.txt.
+ * http/tests/media/media-blocked-by-willsendrequest.html: Renamed from LayoutTests/media/media-blocked-by-willsendrequest.html.
+ * platform/mac/media/video-blob-request-contains-range-header.html:
+ * platform/mac/media/video-blob-request-contains-range-header-expected.txt: Added.
+ * platform/mac/media/video-blob-request-contains-range-header.html: Added.
+
2021-11-03 Tim Nguyen <[email protected]>
Make render-layer-rebuild-z-order-lists.html use an HTML reference
Copied: trunk/LayoutTests/http/tests/media/media-blocked-by-willsendrequest-expected.txt (from rev 285209, trunk/LayoutTests/media/media-blocked-by-willsendrequest-expected.txt) (0 => 285210)
--- trunk/LayoutTests/http/tests/media/media-blocked-by-willsendrequest-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/media/media-blocked-by-willsendrequest-expected.txt 2021-11-03 16:52:28 UTC (rev 285210)
@@ -0,0 +1,13 @@
+
+Test to ensure that a media file blocked by the resource load delegate generates an error and does not block the document's 'load' event.
+
+EXPECTED (video.networkState == '0') OK
+
+EVENT(loadstart)
+EVENT(error)
+EXPECTED (video.error != 'null') OK
+EXPECTED (video.error.code == '4') OK
+EXPECTED (video.networkState == '3') OK
+
+END OF TEST
+
Copied: trunk/LayoutTests/http/tests/media/media-blocked-by-willsendrequest.html (from rev 285209, trunk/LayoutTests/media/media-blocked-by-willsendrequest.html) (0 => 285210)
--- trunk/LayoutTests/http/tests/media/media-blocked-by-willsendrequest.html (rev 0)
+++ trunk/LayoutTests/http/tests/media/media-blocked-by-willsendrequest.html 2021-11-03 16:52:28 UTC (rev 285210)
@@ -0,0 +1,56 @@
+<!doctype html>
+<html>
+<head>
+ <script src=""
+ <script src=""
+</head>
+<body>
+ <video controls></video>
+ <p>Test to ensure that a media file blocked by the resource load delegate generates an error
+ and does not block the document's 'load' event.</p>
+
+ <script>
+ var events = [];
+
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.setWillSendRequestReturnsNull(true);
+ } else
+ consoleWrite("<b><em>This test can only be run in DumpRenderTree!</em></b><br><br>");
+
+ function finish()
+ {
+ consoleWrite("EVENT(loadstart)");
+ consoleWrite("EVENT(error)");
+ testExpected("video.error", null, "!=");
+ testExpected("video.error.code", MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED);
+ testExpected("video.networkState", HTMLMediaElement.NETWORK_NO_SOURCE);
+ consoleWrite("");
+ endTest();
+ };
+
+ function handleEvent(evt)
+ {
+ // Wait until all three events we listen for have been received before testing.
+ // Media events are dispatched asynchronously so we can't assume they will fire
+ // before window.onload.
+ if (events.indexOf(evt.type) == -1)
+ events.push(evt.type);
+ if (events.length == 3)
+ finish();
+ }
+
+ findMediaElement();
+
+ window.addEventListener('load', handleEvent);
+ video.addEventListener('loadstart', handleEvent);
+ video.addEventListener('error', handleEvent);
+
+ testExpected("video.networkState", HTMLMediaElement.NETWORK_EMPTY);
+ consoleWrite("");
+ var mediaFile = findMediaFile("video", "resources/test");
+ video.src = ""
+ </script>
+
+</body>
+</html>
Deleted: trunk/LayoutTests/media/media-blocked-by-willsendrequest-expected.txt (285209 => 285210)
--- trunk/LayoutTests/media/media-blocked-by-willsendrequest-expected.txt 2021-11-03 16:40:39 UTC (rev 285209)
+++ trunk/LayoutTests/media/media-blocked-by-willsendrequest-expected.txt 2021-11-03 16:52:28 UTC (rev 285210)
@@ -1,13 +0,0 @@
-
-Test to ensure that a media file blocked by the resource load delegate generates an error and does not block the document's 'load' event.
-
-EXPECTED (video.networkState == '0') OK
-
-EVENT(loadstart)
-EVENT(error)
-EXPECTED (video.error != 'null') OK
-EXPECTED (video.error.code == '4') OK
-EXPECTED (video.networkState == '3') OK
-
-END OF TEST
-
Deleted: trunk/LayoutTests/media/media-blocked-by-willsendrequest.html (285209 => 285210)
--- trunk/LayoutTests/media/media-blocked-by-willsendrequest.html 2021-11-03 16:40:39 UTC (rev 285209)
+++ trunk/LayoutTests/media/media-blocked-by-willsendrequest.html 2021-11-03 16:52:28 UTC (rev 285210)
@@ -1,56 +0,0 @@
-<!doctype html>
-<html>
-<head>
- <script src=""
- <script src=""
-</head>
-<body>
- <video controls></video>
- <p>Test to ensure that a media file blocked by the resource load delegate generates an error
- and does not block the document's 'load' event.</p>
-
- <script>
- var events = [];
-
- if (window.testRunner) {
- testRunner.dumpAsText();
- testRunner.setWillSendRequestReturnsNull(true);
- } else
- consoleWrite("<b><em>This test can only be run in DumpRenderTree!</em></b><br><br>");
-
- function finish()
- {
- consoleWrite("EVENT(loadstart)");
- consoleWrite("EVENT(error)");
- testExpected("video.error", null, "!=");
- testExpected("video.error.code", MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED);
- testExpected("video.networkState", HTMLMediaElement.NETWORK_NO_SOURCE);
- consoleWrite("");
- endTest();
- };
-
- function handleEvent(evt)
- {
- // Wait until all three events we listen for have been received before testing.
- // Media events are dispatched asynchronously so we can't assume they will fire
- // before window.onload.
- if (events.indexOf(evt.type) == -1)
- events.push(evt.type);
- if (events.length == 3)
- finish();
- }
-
- findMediaElement();
-
- window.addEventListener('load', handleEvent);
- video.addEventListener('loadstart', handleEvent);
- video.addEventListener('error', handleEvent);
-
- testExpected("video.networkState", HTMLMediaElement.NETWORK_EMPTY);
- consoleWrite("");
- var mediaFile = findMediaFile("video", "content/test");
- video.src = ""
- </script>
-
-</body>
-</html>
Added: trunk/LayoutTests/platform/mac/media/video-blob-request-contains-range-header-expected.txt (0 => 285210)
--- trunk/LayoutTests/platform/mac/media/video-blob-request-contains-range-header-expected.txt (rev 0)
+++ trunk/LayoutTests/platform/mac/media/video-blob-request-contains-range-header-expected.txt 2021-11-03 16:52:28 UTC (rev 285210)
@@ -0,0 +1,10 @@
+
+
+== Running test suite: Media.BlobRequest
+-- Running test case: Media.BlobRequest.RangeHeader
+Running setup...
+Triggering load...
+Load finished...
+PASS: Range request header should not be undefined.
+PASS: Range request header should not be null.
+
Added: trunk/LayoutTests/platform/mac/media/video-blob-request-contains-range-header.html (0 => 285210)
--- trunk/LayoutTests/platform/mac/media/video-blob-request-contains-range-header.html (rev 0)
+++ trunk/LayoutTests/platform/mac/media/video-blob-request-contains-range-header.html 2021-11-03 16:52:28 UTC (rev 285210)
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+
+async function setup()
+{
+ let response = await fetch('../../../media/content/test.mp4');
+ window.blob = await response.blob();
+ TestPage.dispatchEventToFrontend("SetupComplete");
+}
+
+function loadVideoSource() {
+ document.querySelector('video').src = ""
+}
+
+async function test() {
+ let suite = InspectorTest.createAsyncSuite("Media.BlobRequest");
+
+ suite.addTestCase({
+ name: "Media.BlobRequest.RangeHeader",
+ description: "Ensure an Media Request for a Blob URL contains a Range: header.",
+ async test() {
+ InspectorTest.log("Running setup...");
+ InspectorTest.evaluateInPage(`setup()`);
+ await InspectorTest.awaitEvent("SetupComplete");
+
+ InspectorTest.log("Triggering load...");
+ InspectorTest.evaluateInPage('loadVideoSource()');
+ let resource = (await WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded)).data.resource;
+
+ InspectorTest.log("Load finished...");
+ InspectorTest.expectNotEqual(resource.requestHeaders["Range"], undefined, "Range request header should not be undefined.");
+ InspectorTest.expectNotNull(resource.requestHeaders["Range"], "Range request header should not be null.");
+ },
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+ <video muted></video>
+</body>
\ No newline at end of file
Modified: trunk/Source/WebCore/ChangeLog (285209 => 285210)
--- trunk/Source/WebCore/ChangeLog 2021-11-03 16:40:39 UTC (rev 285209)
+++ trunk/Source/WebCore/ChangeLog 2021-11-03 16:52:28 UTC (rev 285210)
@@ -1,3 +1,32 @@
+2021-11-03 Jer Noble <[email protected]>
+
+ [iOS] AVAssetResourceLoadingRequest.request does not include a Range: header on iOS 15.
+ https://bugs.webkit.org/show_bug.cgi?id=232195
+ <rdar://84574375>
+
+ Reviewed by Darin Adler.
+
+ Explicitly add a Range: header for Blob requests which do not have one (but otherwise should).
+
+ Test: platform/mac/media/video-blob-request-contains-range-header.html
+
+ Drive-by fix: to allow this change to be testable, we must revert a change which calls all the
+ network delegate callbacks with empty data. This was necessary at the time because (at least for
+ Cocoa ports) media loading happened outside WebCore's loader path. Currently, all http(s), data,
+ blob, and custom protocol schemes are loaded through WebCore, leaving file:// URLs as the
+ remaining protocol type that needs custom handling, and only on Cocoa ports.
+
+ Further drive-by fix: WebKitLegacy's network delegate client operates synchronously during
+ requestResource(), so WebCoreNSURLSession must synthesize an error if that method returns a
+ nil resource.
+
+ * platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm:
+ (WebCore::WebCoreAVFResourceLoader::startLoading):
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::loadResource):
+ * platform/network/cocoa/WebCoreNSURLSession.mm:
+ (-[WebCoreNSURLSessionDataTask _restart]):
+
2021-11-03 Antti Koivisto <[email protected]>
::slotted shouldn't match an active <slot>
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (285209 => 285210)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2021-11-03 16:40:39 UTC (rev 285209)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2021-11-03 16:52:28 UTC (rev 285210)
@@ -1472,10 +1472,12 @@
}
URL url = ""
- if (!url.isEmpty() && !frame->loader().willLoadMediaElementURL(url, *this)) {
+#if PLATFORM(COCOA)
+ if (url.isLocalFile() && !frame->loader().willLoadMediaElementURL(url, *this)) {
mediaLoadingFailed(MediaPlayer::NetworkState::FormatError);
return;
}
+#endif
#if ENABLE(CONTENT_EXTENSIONS)
if (RefPtr documentLoader = frame->loader().documentLoader()) {
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm (285209 => 285210)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm 2021-11-03 16:40:39 UTC (rev 285209)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm 2021-11-03 16:52:28 UTC (rev 285210)
@@ -290,8 +290,7 @@
request.setPriority(ResourceLoadPriority::Low);
if (AVAssetResourceLoadingDataRequest *dataRequest = [m_avRequest dataRequest]; dataRequest.requestedLength
- && !request.hasHTTPHeaderField(HTTPHeaderName::Range)
- && !request.url().protocolIsBlob()) {
+ && !request.hasHTTPHeaderField(HTTPHeaderName::Range)) {
String rangeEnd = dataRequest.requestsAllDataToEndOfResource ? "*"_s : makeString(dataRequest.requestedOffset + dataRequest.requestedLength - 1);
request.addHTTPHeaderField(HTTPHeaderName::Range, makeString("bytes=", dataRequest.requestedOffset, '-', rangeEnd));
}
Modified: trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm (285209 => 285210)
--- trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm 2021-11-03 16:40:39 UTC (rev 285209)
+++ trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm 2021-11-03 16:52:28 UTC (rev 285210)
@@ -747,8 +747,13 @@
return;
_resource = self.session.loader.requestResource(self.originalRequest, PlatformMediaResourceLoader::LoadOption::DisallowCaching);
- if (_resource)
+ if (_resource) {
_resource->setClient(adoptRef(*new WebCoreNSURLSessionDataTaskClient(self)));
+ return;
+ }
+
+ // A nil return from requestResource means the load was cancelled by a delegate client
+ [self _resource:nil loadFinishedWithError:ResourceError(ResourceError::Type::Cancellation) metrics:{ }];
}
- (void)_cancel