Index: LayoutTests/http/tests/serviceworker/fetch-access-control.html |
diff --git a/LayoutTests/http/tests/serviceworker/fetch-access-control.html b/LayoutTests/http/tests/serviceworker/fetch-access-control.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..93598de2bc81ce8b41072d1195918d8b2ce1f9ca |
--- /dev/null |
+++ b/LayoutTests/http/tests/serviceworker/fetch-access-control.html |
@@ -0,0 +1,275 @@ |
+<!DOCTYPE html> |
+<title>Service Worker: fetch()</title> |
+<script src="../resources/testharness.js"></script> |
+<script src="../resources/testharnessreport.js"></script> |
+<script src="resources/test-helpers.js"></script> |
+<script> |
+var test = async_test('Verify access control of fetch() in a Service Worker'); |
+test.step(function() { |
+ window.addEventListener('message', onMessage, false); |
+ var scope = 'resources/fetch-access-control-iframe.html'; |
+ service_worker_unregister_and_register( |
+ test, 'resources/fetch-access-control-worker.js', scope).then(test.step_func(onRegister)); |
+ |
+ |
+ var kBaseUrl = 'http://127.0.0.1:8000/serviceworker/resources/fetch-access-control.php?'; |
+ var kCorsBaseUrl = 'http://localhost:8000/serviceworker/resources/fetch-access-control.php?'; |
+ var kIframeUrl = 'http://127.0.0.1:8000/serviceworker/resources/fetch-access-control-iframe.html'; |
+ |
+ var shouldBeResolved = function (url, data) { |
+ assert_true(data.event != 'rejected' && data.event != 'error', url + ' should be resolved'); |
+ }; |
+ var shouldBeRejected = function (url, data) { |
+ assert_true(data.event != 'resolved' && data.event != 'error', url + ' should be rejected'); |
+ }; |
+ var shouldThrowError = function (url, data) { |
+ assert_true(data.event != 'rejected' && data.event != 'resolved', url + ' should throw error'); |
+ }; |
+ var shouldHaveHeader = function (url, name, value, data) { |
+ if (data.event != 'report') { |
+ return; |
+ } |
+ assert_equals(data.headers[name], value, |
+ 'the request header to ' + url + ' should have ' + name + '/' + value); |
+ }; |
+ var shouldNotHaveHeader = function (url, name, data) { |
+ if (data.event != 'report') { |
+ return; |
+ } |
+ assert_equals(data.headers[name], undefined, |
+ 'the request header to ' + url + ' should not have ' + name); |
+ }; |
+ var methodCheck = function (url, method, data) { |
+ if (data.event != 'report') { |
+ return; |
+ } |
+ assert_equals(data.method, method, 'Method must match'); |
+ }; |
+ var headerCheck = function (url, hasContentLength, hasXServiceWorkerServerHeader, data) { |
+ if (data.event != 'resolved') { |
+ return; |
+ } |
+ var hasCL = false; |
+ var hasXSWSH = false; |
+ for (var i = 0; i < data.headers.length; ++i) { |
+ if (data.headers[i][0] == 'content-length') { |
+ hasCL = true; |
+ } else if (data.headers[i][0] == 'x-serviceworker-serverheader') { |
+ hasXSWSH = true; |
+ } |
+ } |
+ assert_equals(hasCL, hasContentLength, 'hasContentLength must match'); |
+ assert_equals(hasXSWSH, hasXServiceWorkerServerHeader, 'hasContentLength must match'); |
+ }; |
+ var testTargets = []; |
+ [kBaseUrl, kCorsBaseUrl].forEach(function(baseUrl) { |
+ ['same-origin', 'no-cors', 'cors'].forEach(function(mode) { |
+ var headersTestList = ['', '{}', 'HEADER_WITHOUT_ACA']; |
+ var ACAOriginTestList = ['']; |
+ if (mode == 'cors') { |
+ headersTestList.push('HEADER_WITH_ACA'); |
+ ACAOriginTestList.push('*'); |
+ ACAOriginTestList.push('http://127.0.0.1:8000'); |
+ ACAOriginTestList.push('http://127.0.0.1:8000,http://www.example.com'); |
+ ACAOriginTestList.push('http://localhost:8000'); |
+ } |
+ ['GET', 'POST', 'PUT', 'XXX'].forEach(function(method) { |
+ headersTestList.forEach(function(headers) { |
+ ACAOriginTestList.forEach(function(ACAOrigin) { |
+ var ACAMethodsTestList = ['']; |
+ if (mode == 'cors' && headers == '{}' && ACAOrigin == '*') { |
+ ACAMethodsTestList.push('*'); |
+ ACAMethodsTestList.push('XXX'); |
+ ACAMethodsTestList.push('PUT'); |
+ ACAMethodsTestList.push('PUT, XXX'); |
+ } |
+ ACAMethodsTestList.forEach(function(ACAMethods) { |
+ var ACEHeadersList = ['']; |
+ if (mode == 'cors' && headers == '{}' && ACAOrigin == '*') { |
+ ACEHeadersList.push('X-ServiceWorker-ServerHeader'); |
+ ACEHeadersList.push('Content-Length, X-ServiceWorker-ServerHeader'); |
+ } |
+ ACEHeadersList.forEach(function(ACEHeaders){ |
+ var url = baseUrl + |
+ 'mode=' + mode + |
+ '&method=' + method; |
+ if (headers == '{}') { |
+ url += '&headers=' + headers; |
+ } else if (headers == 'HEADER_WITHOUT_ACA') { |
+ url += '&headers={\"X-ServiceWorker-Test\":\ \"test\"}'; |
+ } else if (headers == 'HEADER_WITH_ACA') { |
+ url += '&headers={\"X-ServiceWorker-Test\":\ \"test\"}'; |
+ url += '&ACAHeaders=x-serviceworker-test'; |
+ } |
+ if (ACAOrigin) { |
+ url += '&ACAOrigin=' + ACAOrigin; |
+ } |
+ if (ACAMethods) { |
+ url += '&ACAMethods=' + ACAMethods; |
+ } |
+ if (ACEHeaders) { |
+ url += '&ACEHeaders=' + ACEHeaders; |
+ } |
+ var checkFunctions = []; |
+ var error = false; |
+ if (method != 'GET' && method != 'POST') { |
+ if (mode == 'no-cors') { |
+ error = true; |
+ } |
+ } |
+ var resolve = true; |
+ if (!error) { |
+ if (baseUrl == kCorsBaseUrl) { |
+ if (mode == 'same-origin') { |
+ resolve = false; |
+ } else if (mode == 'cors') { |
+ if (headers == '{}' || headers == 'HEADER_WITH_ACA') { |
+ if (ACAOrigin == '' || |
+ ACAOrigin == 'http://localhost:8000' || |
+ ACAOrigin == 'http://127.0.0.1:8000,http://www.example.com') { |
+ resolve = false; |
+ } |
+ } else { |
+ resolve = false; |
+ } |
+ if (method != 'GET' && method != 'POST') { |
+ if (ACAMethods.indexOf(method) == -1) { |
+ resolve = false; |
+ } |
+ } |
+ } |
+ } |
+ } |
+ if (error) { |
+ checkFunctions.push(shouldThrowError.bind(this, url)); |
+ } else if (resolve) { |
+ checkFunctions.push(shouldBeResolved.bind(this, url)); |
+ } else { |
+ checkFunctions.push(shouldBeRejected.bind(this, url)); |
+ } |
+ var haveHeader = false; |
+ if (resolve) { |
+ if (headers == 'HEADER_WITHOUT_ACA' || headers == 'HEADER_WITH_ACA') { |
+ if (mode == 'same-origin' || mode == 'cors') { |
+ haveHeader = true; |
+ } |
+ } |
+ } |
+ if (haveHeader) { |
+ checkFunctions.push(shouldHaveHeader.bind( |
+ this, url, 'x-serviceworker-test', 'test')); |
+ } else { |
+ checkFunctions.push(shouldNotHaveHeader.bind( |
+ this, url, 'x-serviceworker-test')); |
+ } |
+ if (resolve) { |
+ var expectedMethod = method; |
+ if (baseUrl == kBaseUrl) { |
+ if (mode == 'no-cors' && method != 'POST') { |
+ expectedMethod = 'GET'; |
+ } |
+ } else { |
+ if (mode == 'no-cors' && method != 'POST') { |
+ expectedMethod = 'GET'; |
+ } |
+ } |
+ checkFunctions.push(methodCheck.bind(this, url, expectedMethod)); |
+ var hasContentLength = false; |
+ var hasXServiceWorkerServerHeader = false; |
+ if (baseUrl == kBaseUrl) { |
+ if (mode == 'cors') { |
+ if (ACEHeaders.indexOf('Content-Length') != -1) { |
+ hasContentLength = true; |
+ } |
+ if (ACEHeaders.indexOf('X-ServiceWorker-ServerHeader') != -1) { |
+ hasXServiceWorkerServerHeader = true; |
+ } |
+ } else { |
+ hasContentLength = true; |
+ hasXServiceWorkerServerHeader = true; |
+ } |
+ } else { |
+ if (mode == 'cors') { |
+ if (ACEHeaders.indexOf('Content-Length') != -1) { |
+ hasContentLength = true; |
+ } |
+ if (ACEHeaders.indexOf('X-ServiceWorker-ServerHeader') != -1) { |
+ hasXServiceWorkerServerHeader = true; |
+ } |
+ } |
+ } |
+ checkFunctions.push(headerCheck.bind(this, url, hasContentLength, hasXServiceWorkerServerHeader)); |
+ } |
+ testTargets.push([url, checkFunctions]); |
+ }); |
+ }); |
+ }); |
+ }); |
+ }); |
+ }); |
+ }); |
+ |
+ function onRegister(worker) { |
+ worker.addEventListener('statechange', test.step_func(onStateChange)); |
+ var messageChannel = new MessageChannel(); |
+ messageChannel.port1.onmessage = onWorkerMessage; |
+ worker.postMessage({port: messageChannel.port2}, [messageChannel.port2]); |
+ } |
+ |
+ function onWorkerMessage(e) { |
+ var message = e.data; |
+ testTargets[message.id][1].forEach(function(checkFunc){ |
+ checkFunc.call(this, message); |
+ }); |
+ if (message.event == 'resolved') { |
+ var hasContentLength = false; |
+ var hasXServiceWorkerServerHeader = false; |
+ for (var i = 0; i < message.headers.length; ++i) { |
+ if (message.headers[i][0] == 'content-length') { |
+ hasContentLength = true; |
+ } else if (message.headers[i][0] == 'x-serviceworker-serverheader') { |
+ hasXServiceWorkerServerHeader = true; |
+ } |
+ } |
+ // console.log('resolved type:' + message.data.type + |
+ // ' hasContentLength:' + hasContentLength + |
+ // ' hasXServiceWorkerServerHeader:' + hasXServiceWorkerServerHeader); |
+ } else if (message.event == 'rejected') { |
+ // console.log('rejected'); |
+ } else if (message.event == 'error') { |
+ // console.log('error'); |
+ } |
+ } |
+ |
+ var jsonpResultCount = 0; |
+ function onMessage(e) { |
+ var message = e.data; |
+ testTargets[message.id][1].forEach(function(checkFunc){ |
+ checkFunc.call(this, message); |
+ }); |
+ ++jsonpResultCount; |
+ // console.log(message.event + ' ' + message.method + ' ' + message.headers['x-serviceworker-test']); |
+ if (jsonpResultCount == testTargets.length) { |
+ service_worker_unregister_and_done(test, scope); |
+ } else { |
+ loadNext(); |
+ } |
+ } |
+ var frameWindow = {}; |
+ function loadNext() { |
+ // console.log(testTargets[jsonpResultCount][0]); |
+ frameWindow.postMessage( |
+ {url: testTargets[jsonpResultCount][0] + '&id=' + jsonpResultCount}, |
+ kIframeUrl); |
+ } |
+ function onStateChange(event) { |
+ if (event.target.state != 'active') |
+ return; |
+ with_iframe('resources/fetch-access-control-iframe.html') |
+ .then(function(frame) { |
+ frameWindow = frame.contentWindow; |
+ loadNext(); |
+ }); |
+ } |
+}); |
+</script> |