summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/blink/buffered_data_source.cc7
-rw-r--r--media/blink/buffered_data_source_unittest.cc33
-rw-r--r--third_party/WebKit/LayoutTests/http/tests/media/mixed-range-response.html97
-rw-r--r--third_party/WebKit/LayoutTests/http/tests/media/resources/load-video.php2
-rw-r--r--third_party/WebKit/LayoutTests/http/tests/media/resources/mixed-range-response.php6
-rw-r--r--third_party/WebKit/LayoutTests/http/tests/media/resources/serve-video.php3
-rw-r--r--third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp7
7 files changed, 142 insertions, 13 deletions
diff --git a/media/blink/buffered_data_source.cc b/media/blink/buffered_data_source.cc
index eb4c984..0fc1617 100644
--- a/media/blink/buffered_data_source.cc
+++ b/media/blink/buffered_data_source.cc
@@ -431,9 +431,10 @@ bool BufferedDataSource::CheckPartialResponseURL(
// generated bytes and the target response. See http://crbug.com/489060#c32
// for details.
// If the origin of the new response is different from the first response we
- // deny the redirected response.
- return response_original_url_.GetOrigin() ==
- partial_response_original_url.GetOrigin();
+ // deny the redirected response unless the crossorigin attribute has been set.
+ return (response_original_url_.GetOrigin() ==
+ partial_response_original_url.GetOrigin()) ||
+ DidPassCORSAccessCheck();
}
void BufferedDataSource::ReadCallback(
diff --git a/media/blink/buffered_data_source_unittest.cc b/media/blink/buffered_data_source_unittest.cc
index 878d5f7..aed8453 100644
--- a/media/blink/buffered_data_source_unittest.cc
+++ b/media/blink/buffered_data_source_unittest.cc
@@ -51,11 +51,12 @@ class MockBufferedDataSource : public BufferedDataSource {
public:
MockBufferedDataSource(
const GURL& url,
+ BufferedResourceLoader::CORSMode cors_mode,
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
WebLocalFrame* frame,
BufferedDataSourceHost* host)
: BufferedDataSource(url,
- BufferedResourceLoader::kUnspecified,
+ cors_mode,
task_runner,
frame,
new media::MediaLog(),
@@ -128,13 +129,13 @@ class BufferedDataSourceTest : public testing::Test {
MOCK_METHOD1(OnInitialize, void(bool));
- void Initialize(const char* url, bool expected) {
+ void InitializeWithCORS(const char* url,
+ bool expected,
+ BufferedResourceLoader::CORSMode cors_mode) {
GURL gurl(url);
- data_source_.reset(
- new MockBufferedDataSource(gurl,
- message_loop_.task_runner(),
- view_->mainFrame()->toWebLocalFrame(),
- &host_));
+ data_source_.reset(new MockBufferedDataSource(
+ gurl, cors_mode, message_loop_.task_runner(),
+ view_->mainFrame()->toWebLocalFrame(), &host_));
data_source_->SetPreload(preload_);
response_generator_.reset(new TestResponseGenerator(gurl, kFileSize));
@@ -148,6 +149,10 @@ class BufferedDataSourceTest : public testing::Test {
EXPECT_EQ(data_source_->downloading(), is_http);
}
+ void Initialize(const char* url, bool expected) {
+ InitializeWithCORS(url, expected, BufferedResourceLoader::kUnspecified);
+ }
+
// Helper to initialize tests with a valid 200 response.
void InitializeWith200Response() {
Initialize(kHttpUrl, true);
@@ -577,6 +582,20 @@ TEST_F(BufferedDataSourceTest,
ExecuteMixedResponseFailureTest(response1, response2);
}
+TEST_F(BufferedDataSourceTest,
+ Http_MixedResponse_ServiceWorkerProxiedAndDifferentOriginResponseCORS) {
+ InitializeWithCORS(kHttpUrl, true, BufferedResourceLoader::kAnonymous);
+ WebURLResponse response1 =
+ response_generator_->GeneratePartial206(0, kDataSize - 1);
+ response1.setWasFetchedViaServiceWorker(true);
+ response1.setOriginalURLViaServiceWorker(GURL(kHttpDifferentOriginUrl));
+ WebURLResponse response2 =
+ response_generator_->GeneratePartial206(kDataSize, kDataSize * 2 - 1);
+ // The origin URL of response1 and response2 are different, but a CORS check
+ // has been passed for each request, so expect success.
+ ExecuteMixedResponseSuccessTest(response1, response2);
+}
+
TEST_F(BufferedDataSourceTest, File_Retry) {
InitializeWithFileResponse();
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/mixed-range-response.html b/third_party/WebKit/LayoutTests/http/tests/media/mixed-range-response.html
index e4fec36..f3a8c88 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/mixed-range-response.html
+++ b/third_party/WebKit/LayoutTests/http/tests/media/mixed-range-response.html
@@ -16,9 +16,11 @@
// If the origin of 2. (mixed-range-response.php) and 6. (load-video.php) are
// different, an error should occur.
-function create_failure_audio_test(url) {
+function create_failure_audio_test(url, crossOrigin) {
return new Promise(function(resolve, reject) {
var audio = document.createElement('audio');
+ if (crossOrigin)
+ audio.crossOrigin = crossOrigin;
audio.oncanplay = function() {
reject('canplay event should not be fired. url: ' + url);
};
@@ -28,9 +30,11 @@ function create_failure_audio_test(url) {
});
}
-function create_success_audio_test(url) {
+function create_success_audio_test(url, crossOrigin) {
return new Promise(function(resolve, reject) {
var audio = document.createElement('audio');
+ if (crossOrigin)
+ audio.crossOrigin = crossOrigin;
audio.oncanplay = resolve;
audio.onerror = function(e) {
reject('error event should not be fired. url: ' + url);
@@ -42,10 +46,75 @@ function create_success_audio_test(url) {
var HOST_INFO = get_host_info();
var MIX_RESPONSE_PHP_PATH = '/media/resources/mixed-range-response.php';
+var REDIRECT_PHP_PATH = '/resources/redirect.php'
var AUDIO_PATH = '/media/resources/load-video.php?' +
'name=../../../../media/content/silence.oga&type=audio/ogg';
promise_test(function(t) {
+ return create_success_audio_test(
+ HOST_INFO['HTTP_ORIGIN'] + REDIRECT_PHP_PATH + '?url=' +
+ encodeURIComponent(HOST_INFO['HTTP_ORIGIN'] + AUDIO_PATH));
+ }, 'Redirect from same-origin to same-origin must succeed.');
+
+promise_test(function(t) {
+ return create_success_audio_test(
+ HOST_INFO['HTTP_ORIGIN'] + REDIRECT_PHP_PATH + '?url=' +
+ encodeURIComponent(HOST_INFO['HTTP_REMOTE_ORIGIN'] + AUDIO_PATH));
+ }, 'Redirect from same-origin to remote-origin must succeed.');
+
+promise_test(function(t) {
+ return create_failure_audio_test(
+ HOST_INFO['HTTP_REMOTE_ORIGIN'] + AUDIO_PATH ,
+ 'anonymous');
+ }, 'CORS-disallowed remote-origin with crossOrigin=anonymous must fail.');
+
+
+promise_test(function(t) {
+ return create_success_audio_test(
+ HOST_INFO['HTTP_REMOTE_ORIGIN'] + AUDIO_PATH + '&cors_allow_origin=' + HOST_INFO['HTTP_ORIGIN'],
+ 'anonymous');
+ }, 'CORS-allowed remote-origin with crossOrigin=anonymous must succeed.');
+
+promise_test(function(t) {
+ return create_success_audio_test(
+ HOST_INFO['HTTP_ORIGIN'] + REDIRECT_PHP_PATH + '?url=' +
+ encodeURIComponent(HOST_INFO['HTTP_ORIGIN'] + AUDIO_PATH),
+ 'anonymous');
+ }, 'Redirect from same-origin to same-origin with crossOrigin=anonymous must succeed.');
+
+promise_test(function(t) {
+ return create_failure_audio_test(
+ HOST_INFO['HTTP_ORIGIN'] + REDIRECT_PHP_PATH + '?url=' +
+ encodeURIComponent(HOST_INFO['HTTP_REMOTE_ORIGIN'] + AUDIO_PATH),
+ 'anonymous');
+ }, 'Redirect from same-origin to CORS-disallowed remote-origin with crossOrigin=anonymous must fail.');
+
+promise_test(function(t) {
+ return create_success_audio_test(
+ HOST_INFO['HTTP_ORIGIN'] + REDIRECT_PHP_PATH + '?url=' +
+ encodeURIComponent(HOST_INFO['HTTP_REMOTE_ORIGIN'] + AUDIO_PATH +
+ '&cors_allow_origin=' + HOST_INFO['HTTP_ORIGIN']),
+ 'anonymous');
+ }, 'Redirect from same-origin to CORS-allowed remote-origin with crossOrigin=anonymous must succeed.');
+
+promise_test(function(t) {
+ return create_failure_audio_test(
+ HOST_INFO['HTTP_REMOTE_ORIGIN'] + REDIRECT_PHP_PATH + '?url=' +
+ encodeURIComponent(HOST_INFO['HTTP_REMOTE_ORIGIN'] + AUDIO_PATH +
+ '&cors_allow_origin=' + HOST_INFO['HTTP_ORIGIN']),
+ 'anonymous');
+ }, 'Redirect from CORS-disallowed remote-origin to CORS-allowed remote-origin with crossOrigin=anonymous must fail.');
+
+promise_test(function(t) {
+ return create_success_audio_test(
+ HOST_INFO['HTTP_REMOTE_ORIGIN'] + REDIRECT_PHP_PATH + '?url=' +
+ encodeURIComponent(HOST_INFO['HTTP_REMOTE_ORIGIN'] + AUDIO_PATH +
+ '&cors_allow_origin=' + HOST_INFO['HTTP_ORIGIN']) +
+ '&cors_allow_origin=' + HOST_INFO['HTTP_ORIGIN'],
+ 'anonymous');
+ }, 'Redirect from CORS-allowed remote-origin to CORS-allowed remote-origin with crossOrigin=anonymous must succeed.');
+
+promise_test(function(t) {
return create_success_audio_test(
HOST_INFO['HTTP_ORIGIN'] + MIX_RESPONSE_PHP_PATH + '?location=' +
encodeURIComponent(HOST_INFO['HTTP_ORIGIN'] + AUDIO_PATH));
@@ -69,5 +138,29 @@ promise_test(function(t) {
encodeURIComponent(HOST_INFO['HTTP_REMOTE_ORIGIN'] + AUDIO_PATH));
}, 'Mixing same remote-origin responses must succeed.');
+promise_test(function(t) {
+ return create_success_audio_test(
+ HOST_INFO['HTTP_REMOTE_ORIGIN'] + MIX_RESPONSE_PHP_PATH + '?location=' +
+ encodeURIComponent(HOST_INFO['HTTP_REMOTE_ORIGIN'] + AUDIO_PATH +
+ '&cors_allow_origin=' + HOST_INFO['HTTP_ORIGIN']) +
+ '&cors_allow_origin=' + HOST_INFO['HTTP_ORIGIN'],
+ 'anonymous');
+ }, 'Mixing same CORS-allowed remote-origin responses with crossOrigin=anonymous must succeed.');
+
+promise_test(function(t) {
+ return create_success_audio_test(
+ HOST_INFO['HTTP_ORIGIN'] + MIX_RESPONSE_PHP_PATH + '?location=' +
+ encodeURIComponent(HOST_INFO['HTTP_REMOTE_ORIGIN'] + AUDIO_PATH +
+ '&cors_allow_origin=' + HOST_INFO['HTTP_ORIGIN']),
+ 'anonymous');
+ }, 'Mixing same-origin response and CORS-allowed remote-origin response with crossOrigin=anonymous must succeed.');
+
+promise_test(function(t) {
+ return create_success_audio_test(
+ HOST_INFO['HTTP_REMOTE_ORIGIN'] + MIX_RESPONSE_PHP_PATH + '?location=' +
+ encodeURIComponent(HOST_INFO['HTTP_ORIGIN'] + AUDIO_PATH + '&cors_allow_origin=*') +
+ '&cors_allow_origin=' + HOST_INFO['HTTP_ORIGIN'],
+ 'anonymous');
+ }, 'Mixing CORS-allowed remote-origin response and same-origin response with crossOrigin=anonymous must succeed.');
</script>
</body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/resources/load-video.php b/third_party/WebKit/LayoutTests/http/tests/media/resources/load-video.php
index 8f0e8eb..8e0bbb9 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/resources/load-video.php
+++ b/third_party/WebKit/LayoutTests/http/tests/media/resources/load-video.php
@@ -3,11 +3,13 @@
$fileName = $_GET["name"];
$type = $_GET["type"];
$norange = $_GET["norange"];
+ $cors_allow_origin = $_GET["cors_allow_origin"];
$_GET = array();
$_GET['name'] = $fileName;
$_GET['type'] = $type;
$_GET['norange'] = $norange;
+ $_GET['cors_allow_origin'] = $cors_allow_origin;
@include("./serve-video.php");
?>
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/resources/mixed-range-response.php b/third_party/WebKit/LayoutTests/http/tests/media/resources/mixed-range-response.php
index 6d6dbd9..a6581d7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/resources/mixed-range-response.php
+++ b/third_party/WebKit/LayoutTests/http/tests/media/resources/mixed-range-response.php
@@ -1,6 +1,9 @@
<?php
if (isset($_SERVER['HTTP_RANGE']) && ($_SERVER['HTTP_RANGE'] == 'bytes=0-')) {
header('HTTP/1.0 206 Partial Content');
+ if (isset($_GET['cors_allow_origin'])) {
+ header("Access-Control-Allow-Origin: " . $_GET['cors_allow_origin']);
+ }
header('Content-Type: audio/ogg');
# 12983 is the file size of media/content/silence.oga.
header('Content-Range: bytes 0-2/12983');
@@ -9,4 +12,7 @@ if (isset($_SERVER['HTTP_RANGE']) && ($_SERVER['HTTP_RANGE'] == 'bytes=0-')) {
}
header('HTTP/1.1 307 Temporary Redirect');
header('Location: ' . $_GET["location"]);
+if (isset($_GET['cors_allow_origin'])) {
+ header("Access-Control-Allow-Origin: " . $_GET['cors_allow_origin']);
+}
?>
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/resources/serve-video.php b/third_party/WebKit/LayoutTests/http/tests/media/resources/serve-video.php
index 9bfcf02..a13edf0 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/resources/serve-video.php
+++ b/third_party/WebKit/LayoutTests/http/tests/media/resources/serve-video.php
@@ -27,6 +27,9 @@
header("Accept-Ranges: bytes");
header("Content-Range: bytes " . $start . "-" . $end . "/" . $fileSize);
}
+ if (isset($_GET['cors_allow_origin'])) {
+ header("Access-Control-Allow-Origin: " . $_GET['cors_allow_origin']);
+ }
header("Connection: close");
$chunkSize = 1024 * 256;
diff --git a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
index adb2523..c1276fe 100644
--- a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
@@ -160,8 +160,13 @@ DocumentThreadableLoader::DocumentThreadableLoader(Document& document, Threadabl
// create a new one, and copy these headers.
const HTTPHeaderMap& headerMap = request.httpHeaderFields();
for (const auto& header : headerMap) {
- if (FetchUtils::isSimpleHeader(header.key, header.value))
+ if (FetchUtils::isSimpleHeader(header.key, header.value)) {
m_simpleRequestHeaders.add(header.key, header.value);
+ } else if (equalIgnoringCase(header.key, "range") && m_options.crossOriginRequestPolicy == UseAccessControl && m_options.preflightPolicy == PreventPreflight) {
+ // Allow an exception for the "range" header for when CORS callers request no preflight, this ensures cross-origin
+ // redirects work correctly for crossOrigin enabled WebURLRequest::RequestContextVideo type requests.
+ m_simpleRequestHeaders.add(header.key, header.value);
+ }
}
// DocumentThreadableLoader is used by all javascript initiated fetch, so