Diff
Modified: trunk/LayoutTests/ChangeLog (220441 => 220442)
--- trunk/LayoutTests/ChangeLog 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/LayoutTests/ChangeLog 2017-08-09 05:15:47 UTC (rev 220442)
@@ -1,3 +1,32 @@
+2017-08-08 Chris Dumez <cdu...@apple.com>
+
+ [Beacon] Add support for CORS-preflighting for WK2 / NETWORK_SESSION
+ https://bugs.webkit.org/show_bug.cgi?id=175264
+ <rdar://problem/33547793>
+
+ Reviewed by Youenn Fablet.
+
+ Add layout test coverage.
+
+ * http/wpt/beacon/cors/cors-preflight-arraybufferview-failure-expected.txt: Added.
+ * http/wpt/beacon/cors/cors-preflight-arraybufferview-failure.html: Added.
+ * http/wpt/beacon/cors/cors-preflight-arraybufferview-success-expected.txt: Added.
+ * http/wpt/beacon/cors/cors-preflight-arraybufferview-success.html: Added.
+ * http/wpt/beacon/cors/cors-preflight-blob-failure-expected.txt: Added.
+ * http/wpt/beacon/cors/cors-preflight-blob-failure.html: Added.
+ * http/wpt/beacon/cors/cors-preflight-blob-success-expected.txt: Added.
+ * http/wpt/beacon/cors/cors-preflight-blob-success.html: Added.
+ * http/wpt/beacon/cors/cors-preflight-cookie-expected.txt: Added.
+ * http/wpt/beacon/cors/cors-preflight-cookie.html: Added.
+ * http/wpt/beacon/resources/beacon-preflight.py: Added.
+ (respondToCORSPreflight):
+ (main):
+ * http/wpt/beacon/resources/set-cookie.py: Added.
+ (main):
+ * platform/mac-wk1/TestExpectations:
+ * platform/mac-wk2/TestExpectations:
+ * platform/win/TestExpectations:
+
2017-08-08 Devin Rousso <drou...@apple.com>
Web Inspector: Canvas: support editing WebGL shaders
Added: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-failure-expected.txt (0 => 220442)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-failure-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-failure-expected.txt 2017-08-09 05:15:47 UTC (rev 220442)
@@ -0,0 +1,3 @@
+
+PASS CORS preflight failure test
+
Added: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-failure.html (0 => 220442)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-failure.html (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-failure.html 2017-08-09 05:15:47 UTC (rev 220442)
@@ -0,0 +1,64 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>SendBeacon CORS preflight test</title>
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <script src=""
+ <script src=""
+ <script>
+var RESOURCES_DIR = "/WebKit/beacon/resources/";
+
+function pollResult(test, id) {
+ var checkUrl = RESOURCES_DIR + "beacon-preflight.py?cmd=get&id=" + id;
+
+ return new Promise(resolve => {
+ step_timeout(test.step_func(() => {
+ fetch(checkUrl).then(response => {
+ response.text().then(body => {
+ resolve(body);
+ });
+ });
+ }), 1000);
+ });
+}
+
+function testCORSPreflightFailure(what) {
+ var testBase = get_host_info().HTTP_REMOTE_ORIGIN + RESOURCES_DIR;
+ var id = self.token();
+ var testUrl = testBase + "beacon-preflight.py?allowCors=0&cmd=put&id=" + id;
+
+ promise_test(function(test) {
+ assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
+ return pollResult(test, id) .then(json => {
+ result = JSON.parse(json);
+ assert_equals(result['preflight'], 1, "Received preflight")
+ assert_equals(result['preflight_referer'], document.URL, "Preflight referer header")
+ assert_equals(result['preflight_requested_method'], "POST", "Preflight requested method")
+ let requested_headers = result['preflight_requested_headers'].toLowerCase()
+ assert_false(requested_headers.includes("content-type"), "Content-Type header is not requested")
+ assert_true(requested_headers.includes("referer"), "Referer header is requested")
+ assert_true(requested_headers.includes("origin"), "Origin header is requested")
+ assert_equals(result['beacon'], 0, "Did not receive beacon")
+ });
+ }, "CORS preflight failure test");
+}
+
+function stringToArrayBufferView(input) {
+ var buffer = new ArrayBuffer(input.length * 2);
+ var view = new Uint16Array(buffer);
+
+ // dumbly copy over the bytes
+ for (var i = 0, len = input.length; i < len; i++) {
+ view[i] = input.charCodeAt(i);
+ }
+ return view;
+}
+
+testCORSPreflightFailure(stringToArrayBufferView("123"));
+ </script>
+ </body>
+</html>
Added: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-success-expected.txt (0 => 220442)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-success-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-success-expected.txt 2017-08-09 05:15:47 UTC (rev 220442)
@@ -0,0 +1,3 @@
+
+PASS CORS preflight success test
+
Added: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-success.html (0 => 220442)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-success.html (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-success.html 2017-08-09 05:15:47 UTC (rev 220442)
@@ -0,0 +1,64 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>SendBeacon CORS preflight test</title>
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <script src=""
+ <script src=""
+ <script>
+var RESOURCES_DIR = "/WebKit/beacon/resources/";
+
+function pollResult(test, id) {
+ var checkUrl = RESOURCES_DIR + "beacon-preflight.py?cmd=get&id=" + id;
+
+ return new Promise(resolve => {
+ step_timeout(test.step_func(() => {
+ fetch(checkUrl).then(response => {
+ response.text().then(body => {
+ resolve(body);
+ });
+ });
+ }), 1000);
+ });
+}
+
+function testCORSPreflightSuccess(what) {
+ var testBase = get_host_info().HTTP_REMOTE_ORIGIN + RESOURCES_DIR;
+ var id = self.token();
+ var testUrl = testBase + "beacon-preflight.py?allowCors=1&cmd=put&id=" + id;
+
+ promise_test(function(test) {
+ assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
+ return pollResult(test, id) .then(json => {
+ result = JSON.parse(json);
+ assert_equals(result['preflight'], 1, "Received preflight")
+ assert_equals(result['preflight_referer'], document.URL, "Preflight referer header")
+ assert_equals(result['preflight_requested_method'], "POST", "Preflight requested method")
+ let requested_headers = result['preflight_requested_headers'].toLowerCase()
+ assert_false(requested_headers.includes("content-type"), "Content-Type header is not requested")
+ assert_true(requested_headers.includes("referer"), "Referer header is requested")
+ assert_true(requested_headers.includes("origin"), "Origin header is requested")
+ assert_equals(result['beacon'], 1, "Received beacon")
+ });
+ }, "CORS preflight success test");
+}
+
+function stringToArrayBufferView(input) {
+ var buffer = new ArrayBuffer(input.length * 2);
+ var view = new Uint16Array(buffer);
+
+ // dumbly copy over the bytes
+ for (var i = 0, len = input.length; i < len; i++) {
+ view[i] = input.charCodeAt(i);
+ }
+ return view;
+}
+
+testCORSPreflightSuccess(stringToArrayBufferView("123"));
+ </script>
+ </body>
+</html>
Added: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-failure-expected.txt (0 => 220442)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-failure-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-failure-expected.txt 2017-08-09 05:15:47 UTC (rev 220442)
@@ -0,0 +1,3 @@
+
+PASS CORS preflight failure test
+
Added: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-failure.html (0 => 220442)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-failure.html (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-failure.html 2017-08-09 05:15:47 UTC (rev 220442)
@@ -0,0 +1,54 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>SendBeacon CORS preflight test</title>
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <script src=""
+ <script src=""
+ <script>
+var RESOURCES_DIR = "/WebKit/beacon/resources/";
+
+function pollResult(test, id) {
+ var checkUrl = RESOURCES_DIR + "beacon-preflight.py?cmd=get&id=" + id;
+
+ return new Promise(resolve => {
+ step_timeout(test.step_func(() => {
+ fetch(checkUrl).then(response => {
+ response.text().then(body => {
+ resolve(body);
+ });
+ });
+ }), 1000);
+ });
+}
+
+function testCORSPreflightFailure(what) {
+ var testBase = get_host_info().HTTP_REMOTE_ORIGIN + RESOURCES_DIR;
+ var id = self.token();
+ var testUrl = testBase + "beacon-preflight.py?allowCors=0&cmd=put&id=" + id;
+
+ promise_test(function(test) {
+ assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
+ return pollResult(test, id) .then(json => {
+ result = JSON.parse(json);
+ assert_equals(result['preflight'], 1, "Received preflight")
+ assert_equals(result['preflight_referer'], document.URL, "Preflight referer header")
+ assert_equals(result['preflight_requested_method'], "POST", "Preflight requested method")
+ let requested_headers = result['preflight_requested_headers'].toLowerCase()
+ assert_true(requested_headers.includes("content-type"), "Content-Type header is requested")
+ assert_true(requested_headers.includes("referer"), "Referer header is requested")
+ assert_true(requested_headers.includes("origin"), "Origin header is requested")
+ assert_equals(result['beacon'], 0, "Did not receive beacon")
+ });
+ }, "CORS preflight failure test");
+}
+
+let blob = new Blob(["123"], {type: "application/octet-stream"});
+testCORSPreflightFailure(blob);
+ </script>
+ </body>
+</html>
Added: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-success-expected.txt (0 => 220442)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-success-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-success-expected.txt 2017-08-09 05:15:47 UTC (rev 220442)
@@ -0,0 +1,3 @@
+
+PASS CORS preflight success test
+
Added: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-success.html (0 => 220442)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-success.html (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-success.html 2017-08-09 05:15:47 UTC (rev 220442)
@@ -0,0 +1,54 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>SendBeacon CORS preflight test</title>
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <script src=""
+ <script src=""
+ <script>
+var RESOURCES_DIR = "/WebKit/beacon/resources/";
+
+function pollResult(test, id) {
+ var checkUrl = RESOURCES_DIR + "beacon-preflight.py?cmd=get&id=" + id;
+
+ return new Promise(resolve => {
+ step_timeout(test.step_func(() => {
+ fetch(checkUrl).then(response => {
+ response.text().then(body => {
+ resolve(body);
+ });
+ });
+ }), 1000);
+ });
+}
+
+function testCORSPreflightSuccess(what) {
+ var testBase = get_host_info().HTTP_REMOTE_ORIGIN + RESOURCES_DIR;
+ var id = self.token();
+ var testUrl = testBase + "beacon-preflight.py?allowCors=1&cmd=put&id=" + id;
+
+ promise_test(function(test) {
+ assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
+ return pollResult(test, id) .then(json => {
+ result = JSON.parse(json);
+ assert_equals(result['preflight'], 1, "Received preflight")
+ assert_equals(result['preflight_referer'], document.URL, "Preflight referer header")
+ assert_equals(result['preflight_requested_method'], "POST", "Preflight requested method")
+ let requested_headers = result['preflight_requested_headers'].toLowerCase()
+ assert_true(requested_headers.includes("content-type"), "Content-Type header is requested")
+ assert_true(requested_headers.includes("referer"), "Referer header is requested")
+ assert_true(requested_headers.includes("origin"), "Origin header is requested")
+ assert_equals(result['beacon'], 1, "Received beacon")
+ });
+ }, "CORS preflight success test");
+}
+
+let blob = new Blob(["123"], {type: "application/octet-stream"});
+testCORSPreflightSuccess(blob);
+ </script>
+ </body>
+</html>
Added: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-cookie-expected.txt (0 => 220442)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-cookie-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-cookie-expected.txt 2017-08-09 05:15:47 UTC (rev 220442)
@@ -0,0 +1,4 @@
+
+
+PASS CORS preflight success test
+
Added: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-cookie.html (0 => 220442)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-cookie.html (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-cookie.html 2017-08-09 05:15:47 UTC (rev 220442)
@@ -0,0 +1,64 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>SendBeacon CORS preflight test with cookie</title>
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <script src=""
+ <script src=""
+ <script>
+var RESOURCES_DIR = "/WebKit/beacon/resources/";
+
+if (window.testRunner)
+ testRunner.setAlwaysAcceptCookies(true);
+
+function pollResult(test, id) {
+ var checkUrl = RESOURCES_DIR + "beacon-preflight.py?cmd=get&id=" + id;
+
+ return new Promise(resolve => {
+ step_timeout(test.step_func(() => {
+ fetch(checkUrl).then(response => {
+ response.text().then(body => {
+ resolve(body);
+ });
+ });
+ }), 1000);
+ });
+}
+
+function fetchCORSCookie(testBase, name, path) {
+ return new Promise(resolve => {
+ let frame = document.createElement("iframe");
+ frame.src = "" + "set-cookie.py?name=" + encodeURIComponent(name) + "&path=" + encodeURIComponent(path);
+ frame._onload_ = function() { resolve(); };
+ document.body.append(frame);
+ });
+}
+
+function testCORSPreflightSuccessWithCookie(what) {
+ var testBase = get_host_info().HTTP_REMOTE_ORIGIN + RESOURCES_DIR;
+ var id = self.token();
+ var testUrl = testBase + "beacon-preflight.py?allowCors=1&cmd=put&id=" + id;
+
+ promise_test(function(test) {
+ return fetchCORSCookie(testBase, "testCookie", "/").then(() => {
+ assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
+ return pollResult(test, id).then(json => {
+ result = JSON.parse(json);
+ assert_equals(result['preflight'], 1, "Received preflight")
+ assert_equals(result['preflight_cookie_header'], "", "Preflight cookie header")
+ assert_equals(result['beacon'], 1, "Received beacon")
+ assert_equals(result['beacon_cookie_header'], "testCookie=1", "Beacon Cookie header")
+ });
+ });
+ }, "CORS preflight success test");
+}
+
+let blob = new Blob(["123"], {type: "application/octet-stream"});
+testCORSPreflightSuccessWithCookie(blob);
+ </script>
+ </body>
+</html>
Added: trunk/LayoutTests/http/wpt/beacon/resources/beacon-preflight.py (0 => 220442)
--- trunk/LayoutTests/http/wpt/beacon/resources/beacon-preflight.py (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/resources/beacon-preflight.py 2017-08-09 05:15:47 UTC (rev 220442)
@@ -0,0 +1,52 @@
+import json
+
+def respondToCORSPreflight(request, response):
+ allow_cors = int(request.GET.first("allowCors", 0)) != 0;
+
+ if not allow_cors:
+ response.set_error(400, "Not allowed")
+ return "ERROR: Not allowed"
+
+ if not "Access-Control-Request-Method" in request.headers:
+ response.set_error(400, "No Access-Control-Request-Method header")
+ return "ERROR: No access-control-request-method in preflight!"
+
+ headers = [("Content-Type", "text/plain")]
+ headers.append(("Access-Control-Allow-Origin", request.headers.get("Origin", "*")))
+ headers.append(("Access-Control-Allow-Credentials", "true"))
+ requested_method = request.headers.get("Access-Control-Request-Method", None)
+ headers.append(("Access-Control-Allow-Methods", requested_method))
+ requested_headers = request.headers.get("Access-Control-Request-Headers", None)
+ headers.append(("Access-Control-Allow-Headers", requested_headers))
+ headers.append(("Access-Control-Max-Age", "60"))
+ return headers, ""
+
+def main(request, response):
+ command = request.GET.first("cmd").lower();
+ test_id = request.GET.first("id")
+ stashed_data = request.server.stash.take(test_id)
+ if stashed_data is None:
+ stashed_data = { 'preflight': 0, 'beacon': 0, 'preflight_requested_method': '', 'preflight_requested_headers': '', 'preflight_referrer': '', 'preflight_cookie_header': '', 'beacon_cookie_header': '' }
+
+ if command == "put":
+ if request.method == "OPTIONS":
+ stashed_data['preflight'] = 1;
+ stashed_data['preflight_requested_method'] = request.headers.get("Access-Control-Request-Method", "")
+ stashed_data['preflight_requested_headers'] = request.headers.get("Access-Control-Request-Headers", "")
+ stashed_data['preflight_cookie_header'] = request.headers.get("Cookie", "");
+ stashed_data['preflight_referer'] = request.headers.get("Referer", "")
+ request.server.stash.put(test_id, stashed_data)
+ return respondToCORSPreflight(request, response)
+ elif request.method == "POST":
+ stashed_data['beacon'] = 1;
+ stashed_data['beacon_cookie_header'] = request.headers.get("Cookie", "")
+ request.server.stash.put(test_id, stashed_data)
+ return [("Content-Type", "text/plain")], ""
+
+ if command == "get":
+ if stashed_data is not None:
+ return [("Content-Type", "text/plain")], json.dumps(stashed_data)
+ return [("Content-Type", "text/plain")], ""
+
+ response.set_error(400, "Bad Command")
+ return "ERROR: Bad Command!"
Added: trunk/LayoutTests/http/wpt/beacon/resources/set-cookie.py (0 => 220442)
--- trunk/LayoutTests/http/wpt/beacon/resources/set-cookie.py (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/resources/set-cookie.py 2017-08-09 05:15:47 UTC (rev 220442)
@@ -0,0 +1,14 @@
+
+import sys
+import urlparse
+
+def main(request, response):
+ params = urlparse.parse_qs(request.url_parts.query)
+ headers = [
+ ("Content-Type", "application/json"),
+ ("Cache-Control", "no-store"),
+ ("Access-Control-Allow-Origin", "*"),
+ ("Set-Cookie", "{name[0]}=1; Path={path[0]}; Expires=Wed, 09 Jun 2021 10:18:14 GMT".format(**params))
+ ]
+ body = "{}"
+ return headers, body
Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (220441 => 220442)
--- trunk/LayoutTests/platform/mac-wk1/TestExpectations 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations 2017-08-09 05:15:47 UTC (rev 220442)
@@ -360,6 +360,9 @@
webkit.org/b/170877 [ Debug ] webgl/1.0.2/conformance/glsl/misc/shader-with-reserved-words.html [ Pass Timeout ]
+# CORS-preflighting for Beacon is not supported on WK1.
+webkit.org/b/175330 http/wpt/beacon/cors/ [ Skip ]
+
# This was a WK2-only fix.
http/tests/css/filters-on-iframes.html [ Skip ]
Modified: trunk/LayoutTests/platform/mac-wk2/TestExpectations (220441 => 220442)
--- trunk/LayoutTests/platform/mac-wk2/TestExpectations 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/LayoutTests/platform/mac-wk2/TestExpectations 2017-08-09 05:15:47 UTC (rev 220442)
@@ -722,6 +722,10 @@
webkit.org/b/172834 [ ElCapitan ] imported/w3c/web-platform-tests/IndexedDB/idbobjectstore_getAllKeys.html [ Pass Failure ]
+
+# CORS-preflighting for Beacon is not supported on WK2 for non NETWORK_SESSION code path.
+webkit.org/b/175330 [ ElCapitan ] http/wpt/beacon/cors/ [ Skip ]
+
webkit.org/b/172201 webaudio/silent-audio-interrupted-in-background.html [ Pass Timeout ]
webkit.org/b/167757 workers/bomb.html [ Pass Timeout ]
Modified: trunk/LayoutTests/platform/win/TestExpectations (220441 => 220442)
--- trunk/LayoutTests/platform/win/TestExpectations 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/LayoutTests/platform/win/TestExpectations 2017-08-09 05:15:47 UTC (rev 220442)
@@ -4047,6 +4047,9 @@
# This test requires Skia, which isn't available on Windows.
webkit.org/b/174079 fast/text/variations/skia-postscript-name.html [ ImageOnlyFailure ]
+# CORS-preflighting for Beacon is not supported on WK1.
+webkit.org/b/175330 http/wpt/beacon/cors/ [ Skip ]
+
# Async image tests are currently failing on Windows.
webkit.org/b/174653 fast/images/async-image-background-image-repeated.html [ Timeout ]
webkit.org/b/174653 fast/images/async-image-background-image.html [ Timeout ]
Modified: trunk/Source/WebCore/ChangeLog (220441 => 220442)
--- trunk/Source/WebCore/ChangeLog 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebCore/ChangeLog 2017-08-09 05:15:47 UTC (rev 220442)
@@ -1,3 +1,38 @@
+2017-08-08 Chris Dumez <cdu...@apple.com>
+
+ [Beacon] Add support for CORS-preflighting for WK2 / NETWORK_SESSION
+ https://bugs.webkit.org/show_bug.cgi?id=175264
+ <rdar://problem/33547793>
+
+ Reviewed by Youenn Fablet.
+
+ Pass additional information when creating a PingHandle so that the PingLoad
+ can deal with CORS-preflighting on Network process side.
+
+ Tests: http/wpt/beacon/cors/cors-preflight-arraybufferview-failure.html
+ http/wpt/beacon/cors/cors-preflight-arraybufferview-success.html
+ http/wpt/beacon/cors/cors-preflight-blob-failure.html
+ http/wpt/beacon/cors/cors-preflight-blob-success.html
+ http/wpt/beacon/cors/cors-preflight-cookie.html
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * loader/CrossOriginAccessControl.cpp:
+ (WebCore::validatePreflightResponse):
+ * loader/CrossOriginAccessControl.h:
+ * loader/CrossOriginPreflightChecker.cpp:
+ (WebCore::CrossOriginPreflightChecker::validatePreflightResponse):
+ * loader/CrossOriginPreflightResultCache.h:
+ * loader/LoaderStrategy.h:
+ * loader/PingLoader.cpp:
+ (WebCore::PingLoader::loadImage):
+ (WebCore::PingLoader::sendPing):
+ (WebCore::PingLoader::sendViolationReport):
+ (WebCore::PingLoader::startPingLoad):
+ * loader/PingLoader.h:
+ * loader/cache/CachedResource.cpp:
+ (WebCore::CachedResource::load):
+ * page/SecurityOrigin.h:
+
2017-08-08 Sam Weinig <s...@webkit.org>
Address review feedback from https://bugs.webkit.org/show_bug.cgi?id=175246.
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (220441 => 220442)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-08-09 05:15:47 UTC (rev 220442)
@@ -6642,7 +6642,7 @@
E1C36D350EB0A094007410BC /* JSWorkerGlobalScopeBase.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C36D330EB0A094007410BC /* JSWorkerGlobalScopeBase.h */; };
E1C415DA0F655D6F0092D2FB /* CrossOriginPreflightResultCache.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C415D90F655D6F0092D2FB /* CrossOriginPreflightResultCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
E1C415DE0F655D7C0092D2FB /* CrossOriginPreflightResultCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C415DD0F655D7C0092D2FB /* CrossOriginPreflightResultCache.cpp */; };
- E1C416120F6562FD0092D2FB /* CrossOriginAccessControl.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C416110F6562FD0092D2FB /* CrossOriginAccessControl.h */; };
+ E1C416120F6562FD0092D2FB /* CrossOriginAccessControl.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C416110F6562FD0092D2FB /* CrossOriginAccessControl.h */; settings = {ATTRIBUTES = (Private, ); }; };
E1C416170F6563180092D2FB /* CrossOriginAccessControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C416160F6563180092D2FB /* CrossOriginAccessControl.cpp */; };
E1C4DE690EA75C1E0023CCD6 /* ActiveDOMObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C4DE680EA75C1E0023CCD6 /* ActiveDOMObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
E1C4DE6E0EA75C650023CCD6 /* ActiveDOMObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C4DE6D0EA75C650023CCD6 /* ActiveDOMObject.cpp */; };
Modified: trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp (220441 => 220442)
--- trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp 2017-08-09 05:15:47 UTC (rev 220442)
@@ -27,6 +27,7 @@
#include "config.h"
#include "CrossOriginAccessControl.h"
+#include "CrossOriginPreflightResultCache.h"
#include "HTTPHeaderNames.h"
#include "HTTPParsers.h"
#include "ResourceRequest.h"
@@ -156,4 +157,25 @@
return true;
}
+bool validatePreflightResponse(const ResourceRequest& request, const ResourceResponse& response, StoredCredentials includeCredentials, SecurityOrigin& securityOrigin, String& errorDescription)
+{
+ if (!response.isSuccessful()) {
+ errorDescription = ASCIILiteral("Preflight response is not successful");
+ return false;
+ }
+
+ if (!passesAccessControlCheck(response, includeCredentials, securityOrigin, errorDescription))
+ return false;
+
+ auto result = std::make_unique<CrossOriginPreflightResultCacheItem>(includeCredentials);
+ if (!result->parse(response, errorDescription)
+ || !result->allowsCrossOriginMethod(request.httpMethod(), errorDescription)
+ || !result->allowsCrossOriginHeaders(request.httpHeaderFields(), errorDescription)) {
+ return false;
+ }
+
+ CrossOriginPreflightResultCache::singleton().appendEntry(securityOrigin.toString(), request.url(), WTFMove(result));
+ return true;
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/loader/CrossOriginAccessControl.h (220441 => 220442)
--- trunk/Source/WebCore/loader/CrossOriginAccessControl.h 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebCore/loader/CrossOriginAccessControl.h 2017-08-09 05:15:47 UTC (rev 220442)
@@ -41,11 +41,12 @@
bool isOnAccessControlSimpleRequestMethodWhitelist(const String&);
void updateRequestForAccessControl(ResourceRequest&, SecurityOrigin&, StoredCredentials);
-ResourceRequest createAccessControlPreflightRequest(const ResourceRequest&, SecurityOrigin&, const String&);
+WEBCORE_EXPORT ResourceRequest createAccessControlPreflightRequest(const ResourceRequest&, SecurityOrigin&, const String&);
bool isValidCrossOriginRedirectionURL(const URL&);
void cleanRedirectedRequestForAccessControl(ResourceRequest&);
-bool passesAccessControlCheck(const ResourceResponse&, StoredCredentials, SecurityOrigin&, String& errorDescription);
+WEBCORE_EXPORT bool passesAccessControlCheck(const ResourceResponse&, StoredCredentials, SecurityOrigin&, String& errorDescription);
+WEBCORE_EXPORT bool validatePreflightResponse(const ResourceRequest&, const ResourceResponse&, StoredCredentials, SecurityOrigin&, String& errorDescription);
} // namespace WebCore
Modified: trunk/Source/WebCore/loader/CrossOriginPreflightChecker.cpp (220441 => 220442)
--- trunk/Source/WebCore/loader/CrossOriginPreflightChecker.cpp 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebCore/loader/CrossOriginPreflightChecker.cpp 2017-08-09 05:15:47 UTC (rev 220442)
@@ -60,28 +60,15 @@
void CrossOriginPreflightChecker::validatePreflightResponse(DocumentThreadableLoader& loader, ResourceRequest&& request, unsigned long identifier, const ResourceResponse& response)
{
- Frame* frame = loader.document().frame();
- ASSERT(frame);
-
- if (!response.isSuccessful()) {
- loader.preflightFailure(identifier, ResourceError(errorDomainWebKitInternal, 0, request.url(), ASCIILiteral("Preflight response is not successful"), ResourceError::Type::AccessControl));
+ String errorDescription;
+ if (!WebCore::validatePreflightResponse(request, response, loader.options().allowCredentials, loader.securityOrigin(), errorDescription)) {
+ loader.preflightFailure(identifier, ResourceError(errorDomainWebKitInternal, 0, request.url(), errorDescription, ResourceError::Type::AccessControl));
return;
}
- String description;
- if (!passesAccessControlCheck(response, loader.options().allowCredentials, loader.securityOrigin(), description)) {
- loader.preflightFailure(identifier, ResourceError(errorDomainWebKitInternal, 0, request.url(), description, ResourceError::Type::AccessControl));
- return;
- }
+ Frame* frame = loader.document().frame();
+ ASSERT(frame);
- auto result = std::make_unique<CrossOriginPreflightResultCacheItem>(loader.options().allowCredentials);
- if (!result->parse(response, description)
- || !result->allowsCrossOriginMethod(request.httpMethod(), description)
- || !result->allowsCrossOriginHeaders(request.httpHeaderFields(), description)) {
- loader.preflightFailure(identifier, ResourceError(errorDomainWebKitInternal, 0, request.url(), description, ResourceError::Type::AccessControl));
- return;
- }
-
// FIXME: <https://webkit.org/b/164889> Web Inspector: Show Preflight Request information in inspector
// This is only showing success preflight requests and responses but we should show network events
// for preflight failures and distinguish them better from non-preflight requests.
@@ -89,7 +76,6 @@
InspectorInstrumentation::didReceiveResourceResponse(*frame, identifier, frame->loader().documentLoader(), response, nullptr);
InspectorInstrumentation::didFinishLoading(frame, frame->loader().documentLoader(), identifier, emptyMetrics, nullptr);
- CrossOriginPreflightResultCache::singleton().appendEntry(loader.securityOrigin().toString(), request.url(), WTFMove(result));
loader.preflightSuccess(WTFMove(request));
}
Modified: trunk/Source/WebCore/loader/CrossOriginPreflightResultCache.h (220441 => 220442)
--- trunk/Source/WebCore/loader/CrossOriginPreflightResultCache.h 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebCore/loader/CrossOriginPreflightResultCache.h 2017-08-09 05:15:47 UTC (rev 220442)
@@ -46,9 +46,9 @@
{
}
- bool parse(const ResourceResponse&, String& errorDescription);
- bool allowsCrossOriginMethod(const String&, String& errorDescription) const;
- bool allowsCrossOriginHeaders(const HTTPHeaderMap&, String& errorDescription) const;
+ WEBCORE_EXPORT bool parse(const ResourceResponse&, String& errorDescription);
+ WEBCORE_EXPORT bool allowsCrossOriginMethod(const String&, String& errorDescription) const;
+ WEBCORE_EXPORT bool allowsCrossOriginHeaders(const HTTPHeaderMap&, String& errorDescription) const;
bool allowsRequest(StoredCredentials, const String& method, const HTTPHeaderMap& requestHeaders) const;
private:
@@ -67,8 +67,8 @@
public:
WEBCORE_EXPORT static CrossOriginPreflightResultCache& singleton();
- void appendEntry(const String& origin, const URL&, std::unique_ptr<CrossOriginPreflightResultCacheItem>);
- bool canSkipPreflight(const String& origin, const URL&, StoredCredentials, const String& method, const HTTPHeaderMap& requestHeaders);
+ WEBCORE_EXPORT void appendEntry(const String& origin, const URL&, std::unique_ptr<CrossOriginPreflightResultCacheItem>);
+ WEBCORE_EXPORT bool canSkipPreflight(const String& origin, const URL&, StoredCredentials, const String& method, const HTTPHeaderMap& requestHeaders);
WEBCORE_EXPORT void empty();
Modified: trunk/Source/WebCore/loader/LoaderStrategy.h (220441 => 220442)
--- trunk/Source/WebCore/loader/LoaderStrategy.h 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebCore/loader/LoaderStrategy.h 2017-08-09 05:15:47 UTC (rev 220442)
@@ -42,10 +42,13 @@
class ResourceLoader;
class ResourceRequest;
class ResourceResponse;
+class SecurityOrigin;
class SharedBuffer;
class SubresourceLoader;
class URL;
+struct FetchOptions;
+
class WEBCORE_EXPORT LoaderStrategy {
public:
virtual RefPtr<SubresourceLoader> loadResource(Frame&, CachedResource&, const ResourceRequest&, const ResourceLoaderOptions&) = 0;
@@ -59,7 +62,7 @@
virtual void suspendPendingRequests() = 0;
virtual void resumePendingRequests() = 0;
- virtual void createPingHandle(NetworkingContext*, ResourceRequest&, bool shouldUseCredentialStorage, bool shouldFollowRedirects) = 0;
+ virtual void createPingHandle(NetworkingContext*, ResourceRequest&, Ref<SecurityOrigin>&& sourceOrigin, const FetchOptions&) = 0;
virtual void storeDerivedDataToCache(const SHA1::Digest& bodyKey, const String& type, const String& partition, WebCore::SharedBuffer&) = 0;
Modified: trunk/Source/WebCore/loader/PingLoader.cpp (220441 => 220442)
--- trunk/Source/WebCore/loader/PingLoader.cpp 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebCore/loader/PingLoader.cpp 2017-08-09 05:15:47 UTC (rev 220442)
@@ -103,7 +103,7 @@
request.setHTTPReferrer(referrer);
frame.loader().addExtraFieldsToSubresourceRequest(request);
- startPingLoad(frame, request, ShouldFollowRedirects::Yes);
+ startPingLoad(frame, request, document.securityOrigin(), ShouldFollowRedirects::Yes);
}
// http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#hyperlink-auditing
@@ -139,7 +139,7 @@
}
}
- startPingLoad(frame, request, ShouldFollowRedirects::Yes);
+ startPingLoad(frame, request, sourceOrigin, ShouldFollowRedirects::Yes);
}
void PingLoader::sendViolationReport(Frame& frame, const URL& reportURL, Ref<FormData>&& report, ViolationReportType reportType)
@@ -176,10 +176,10 @@
if (!referrer.isEmpty())
request.setHTTPReferrer(referrer);
- startPingLoad(frame, request, ShouldFollowRedirects::No);
+ startPingLoad(frame, request, document.securityOrigin(), ShouldFollowRedirects::No);
}
-void PingLoader::startPingLoad(Frame& frame, ResourceRequest& request, ShouldFollowRedirects shouldFollowRedirects)
+void PingLoader::startPingLoad(Frame& frame, ResourceRequest& request, SecurityOrigin& sourceOrigin, ShouldFollowRedirects shouldFollowRedirects)
{
unsigned long identifier = frame.page()->progress().createUniqueIdentifier();
// FIXME: Why activeDocumentLoader? I would have expected documentLoader().
@@ -188,10 +188,13 @@
// with the provisional DocumentLoader if there is a provisional
// DocumentLoader.
bool shouldUseCredentialStorage = frame.loader().client().shouldUseCredentialStorage(frame.loader().activeDocumentLoader(), identifier);
+ FetchOptions options;
+ options.credentials = shouldUseCredentialStorage ? FetchOptions::Credentials::Include : FetchOptions::Credentials::Omit;
+ options.redirect = shouldFollowRedirects == ShouldFollowRedirects::Yes ? FetchOptions::Redirect::Follow : FetchOptions::Redirect::Error;
InspectorInstrumentation::continueAfterPingLoader(frame, identifier, frame.loader().activeDocumentLoader(), request, ResourceResponse());
- platformStrategies()->loaderStrategy()->createPingHandle(frame.loader().networkingContext(), request, shouldUseCredentialStorage, shouldFollowRedirects == ShouldFollowRedirects::Yes);
+ platformStrategies()->loaderStrategy()->createPingHandle(frame.loader().networkingContext(), request, sourceOrigin, options);
}
}
Modified: trunk/Source/WebCore/loader/PingLoader.h (220441 => 220442)
--- trunk/Source/WebCore/loader/PingLoader.h 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebCore/loader/PingLoader.h 2017-08-09 05:15:47 UTC (rev 220442)
@@ -41,6 +41,7 @@
class Frame;
class URL;
class ResourceRequest;
+class SecurityOrigin;
enum class ViolationReportType {
ContentSecurityPolicy,
@@ -55,7 +56,7 @@
private:
enum class ShouldFollowRedirects { No, Yes };
- static void startPingLoad(Frame&, ResourceRequest&, ShouldFollowRedirects);
+ static void startPingLoad(Frame&, ResourceRequest&, SecurityOrigin& sourceOrigin, ShouldFollowRedirects);
};
} // namespace WebCore
Modified: trunk/Source/WebCore/loader/cache/CachedResource.cpp (220441 => 220442)
--- trunk/Source/WebCore/loader/cache/CachedResource.cpp 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebCore/loader/cache/CachedResource.cpp 2017-08-09 05:15:47 UTC (rev 220442)
@@ -261,7 +261,8 @@
// FIXME: We should not special-case Beacon here.
if (m_options.keepAlive && type() == CachedResource::Beacon) {
- platformStrategies()->loaderStrategy()->createPingHandle(frame.loader().networkingContext(), request, m_options.credentials == FetchOptions::Credentials::Include, m_options.redirect == FetchOptions::Redirect::Follow);
+ ASSERT(m_origin);
+ platformStrategies()->loaderStrategy()->createPingHandle(frame.loader().networkingContext(), request, *m_origin, m_options);
return;
}
Modified: trunk/Source/WebCore/page/SecurityOrigin.h (220441 => 220442)
--- trunk/Source/WebCore/page/SecurityOrigin.h 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebCore/page/SecurityOrigin.h 2017-08-09 05:15:47 UTC (rev 220442)
@@ -97,7 +97,7 @@
// Returns true if this SecurityOrigin can read content retrieved from
// the given URL. For example, call this function before issuing
// XMLHttpRequests.
- bool canRequest(const URL&) const;
+ WEBCORE_EXPORT bool canRequest(const URL&) const;
// Returns true if this SecurityOrigin can receive drag content from the
// initiator. For example, call this function before allowing content to be
Modified: trunk/Source/WebKit/CMakeLists.txt (220441 => 220442)
--- trunk/Source/WebKit/CMakeLists.txt 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebKit/CMakeLists.txt 2017-08-09 05:15:47 UTC (rev 220442)
@@ -100,6 +100,7 @@
NetworkProcess/FileAPI/NetworkBlobRegistry.cpp
+ NetworkProcess/NetworkCORSPreflightChecker.cpp
NetworkProcess/NetworkConnectionToWebProcess.cpp
NetworkProcess/NetworkDataTask.cpp
NetworkProcess/NetworkDataTaskBlob.cpp
@@ -111,6 +112,7 @@
NetworkProcess/NetworkResourceLoader.cpp
NetworkProcess/NetworkSession.cpp
NetworkProcess/NetworkSocketStream.cpp
+ NetworkProcess/PingLoad.cpp
NetworkProcess/cache/NetworkCache.cpp
NetworkProcess/cache/NetworkCacheBlobStorage.cpp
Modified: trunk/Source/WebKit/ChangeLog (220441 => 220442)
--- trunk/Source/WebKit/ChangeLog 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebKit/ChangeLog 2017-08-09 05:15:47 UTC (rev 220442)
@@ -1,3 +1,66 @@
+2017-08-08 Chris Dumez <cdu...@apple.com>
+
+ [Beacon] Add support for CORS-preflighting for WK2 / NETWORK_SESSION
+ https://bugs.webkit.org/show_bug.cgi?id=175264
+ <rdar://problem/33547793>
+
+ Reviewed by Youenn Fablet.
+
+ Implement CORS-preflighting for beacons with a payload that has a non
+ safelisted MIME type, as per:
+ - https://w3c.github.io/beacon/#privacy
+ - https://www.w3.org/TR/beacon/#sec-processing-model
+
+ CORS-preflighting is completely handled on Network Process side because
+ a beacon request can outlive its page and therefore its WebContent
+ process. This requires us to pass a little more information to the
+ Network process, in particular the source origin and the corsMode.
+
+ The current implementation does not currently deal with CORS preflights
+ needed upon a redirect. This will be added in a follow-up.
+
+ * CMakeLists.txt:
+ * NetworkProcess/NetworkCORSPreflightChecker.cpp: Added.
+ (WebKit::NetworkCORSPreflightChecker::NetworkCORSPreflightChecker):
+ (WebKit::NetworkCORSPreflightChecker::~NetworkCORSPreflightChecker):
+ (WebKit::NetworkCORSPreflightChecker::startPreflight):
+ (WebKit::NetworkCORSPreflightChecker::willPerformHTTPRedirection):
+ (WebKit::NetworkCORSPreflightChecker::didReceiveChallenge):
+ (WebKit::NetworkCORSPreflightChecker::didReceiveResponseNetworkSession):
+ (WebKit::NetworkCORSPreflightChecker::didReceiveData):
+ (WebKit::NetworkCORSPreflightChecker::didCompleteWithError):
+ (WebKit::NetworkCORSPreflightChecker::didSendData):
+ (WebKit::NetworkCORSPreflightChecker::wasBlocked):
+ (WebKit::NetworkCORSPreflightChecker::cannotShowURL):
+ * NetworkProcess/NetworkCORSPreflightChecker.h: Added.
+ * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+ (WebKit::NetworkConnectionToWebProcess::loadPing):
+ * NetworkProcess/NetworkConnectionToWebProcess.h:
+ * NetworkProcess/NetworkResourceLoadParameters.cpp:
+ (WebKit::NetworkResourceLoadParameters::encode const):
+ (WebKit::NetworkResourceLoadParameters::decode):
+ * NetworkProcess/NetworkResourceLoadParameters.h:
+ * NetworkProcess/PingLoad.cpp: Added.
+ (WebKit::PingLoad::PingLoad):
+ (WebKit::PingLoad::~PingLoad):
+ (WebKit::PingLoad::startNetworkLoad):
+ (WebKit::PingLoad::willPerformHTTPRedirection):
+ (WebKit::PingLoad::didReceiveChallenge):
+ (WebKit::PingLoad::didReceiveResponseNetworkSession):
+ (WebKit::PingLoad::didReceiveData):
+ (WebKit::PingLoad::didCompleteWithError):
+ (WebKit::PingLoad::didSendData):
+ (WebKit::PingLoad::wasBlocked):
+ (WebKit::PingLoad::cannotShowURL):
+ (WebKit::PingLoad::timeoutTimerFired):
+ (WebKit::PingLoad::needsCORSPreflight const):
+ (WebKit::PingLoad::doCORSPreflight):
+ * NetworkProcess/PingLoad.h:
+ * WebKit.xcodeproj/project.pbxproj:
+ * WebProcess/Network/WebLoaderStrategy.cpp:
+ (WebKit::WebLoaderStrategy::createPingHandle):
+ * WebProcess/Network/WebLoaderStrategy.h:
+
2017-08-08 Megan Gardner <megan_gard...@apple.com>
Remove old and unused pointIsInAssistedNode definition
Added: trunk/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.cpp (0 => 220442)
--- trunk/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.cpp (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.cpp 2017-08-09 05:15:47 UTC (rev 220442)
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NetworkCORSPreflightChecker.h"
+
+#if USE(NETWORK_SESSION)
+
+#include "AuthenticationManager.h"
+#include "Logging.h"
+#include "NetworkLoadParameters.h"
+#include "SessionTracker.h"
+#include <WebCore/CrossOriginAccessControl.h>
+#include <WebCore/CrossOriginPreflightResultCache.h>
+#include <WebCore/SecurityOrigin.h>
+
+#define RELEASE_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(m_parameters.sessionID.isAlwaysOnLoggingAllowed(), Network, "%p - NetworkCORSPreflightChecker::" fmt, this, ##__VA_ARGS__)
+
+namespace WebKit {
+
+using namespace WebCore;
+
+NetworkCORSPreflightChecker::NetworkCORSPreflightChecker(Parameters&& parameters, CompletionCallback&& completionCallback)
+ : m_parameters(WTFMove(parameters))
+ , m_completionCallback(WTFMove(completionCallback))
+{
+}
+
+NetworkCORSPreflightChecker::~NetworkCORSPreflightChecker()
+{
+ if (m_task) {
+ ASSERT(m_task->client() == this);
+ m_task->clearClient();
+ m_task->cancel();
+ }
+}
+
+void NetworkCORSPreflightChecker::startPreflight()
+{
+ RELEASE_LOG_IF_ALLOWED("startPreflight");
+ if (CrossOriginPreflightResultCache::singleton().canSkipPreflight(m_parameters.sourceOrigin->toString(), m_parameters.originalRequest.url(), m_parameters.allowStoredCredentials, m_parameters.originalRequest.httpMethod(), m_parameters.originalRequest.httpHeaderFields())) {
+ RELEASE_LOG_IF_ALLOWED("startPreflight - preflight can be skipped thanks to cached result");
+ m_completionCallback(Result::Success);
+ return;
+ }
+
+ NetworkLoadParameters loadParameters;
+ loadParameters.sessionID = m_parameters.sessionID;
+ loadParameters.request = createAccessControlPreflightRequest(m_parameters.originalRequest, m_parameters.sourceOrigin, m_parameters.originalRequest.httpReferrer());
+ loadParameters.shouldFollowRedirects = false;
+ if (auto* networkSession = SessionTracker::networkSession(loadParameters.sessionID)) {
+ m_task = NetworkDataTask::create(*networkSession, *this, WTFMove(loadParameters));
+ m_task->resume();
+ } else
+ ASSERT_NOT_REACHED();
+}
+
+void NetworkCORSPreflightChecker::willPerformHTTPRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, RedirectCompletionHandler&& completionHandler)
+{
+ RELEASE_LOG_IF_ALLOWED("willPerformHTTPRedirection");
+ completionHandler({ });
+ m_completionCallback(Result::Failure);
+}
+
+void NetworkCORSPreflightChecker::didReceiveChallenge(const WebCore::AuthenticationChallenge&, ChallengeCompletionHandler&& completionHandler)
+{
+ RELEASE_LOG_IF_ALLOWED("didReceiveChallenge");
+ completionHandler(AuthenticationChallengeDisposition::Cancel, { });
+ m_completionCallback(Result::Failure);
+}
+
+void NetworkCORSPreflightChecker::didReceiveResponseNetworkSession(WebCore::ResourceResponse&& response, ResponseCompletionHandler&& completionHandler)
+{
+ RELEASE_LOG_IF_ALLOWED("didReceiveResponseNetworkSession");
+ m_response = WTFMove(response);
+ completionHandler(PolicyAction::PolicyUse);
+}
+
+void NetworkCORSPreflightChecker::didReceiveData(Ref<WebCore::SharedBuffer>&&)
+{
+ RELEASE_LOG_IF_ALLOWED("didReceiveData");
+}
+
+void NetworkCORSPreflightChecker::didCompleteWithError(const WebCore::ResourceError& error, const WebCore::NetworkLoadMetrics&)
+{
+ if (!error.isNull()) {
+ RELEASE_LOG_IF_ALLOWED("didCompleteWithError");
+ m_completionCallback(Result::Failure);
+ return;
+ }
+
+ RELEASE_LOG_IF_ALLOWED("didComplete http_status_code: %d", m_response.httpStatusCode());
+
+ String errorDescription;
+ if (!validatePreflightResponse(m_parameters.originalRequest, m_response, m_parameters.allowStoredCredentials, m_parameters.sourceOrigin, errorDescription)) {
+ RELEASE_LOG_IF_ALLOWED("didComplete, AccessControl error: %s", errorDescription.utf8().data());
+ m_completionCallback(Result::Failure);
+ return;
+ }
+ m_completionCallback(Result::Success);
+}
+
+void NetworkCORSPreflightChecker::didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend)
+{
+}
+
+void NetworkCORSPreflightChecker::wasBlocked()
+{
+ RELEASE_LOG_IF_ALLOWED("wasBlocked");
+ m_completionCallback(Result::Failure);
+}
+
+void NetworkCORSPreflightChecker::cannotShowURL()
+{
+ RELEASE_LOG_IF_ALLOWED("cannotShowURL");
+ m_completionCallback(Result::Failure);
+}
+
+} // Namespace WebKit
+
+#endif // USE(NETWORK_SESSION)
Added: trunk/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h (0 => 220442)
--- trunk/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h 2017-08-09 05:15:47 UTC (rev 220442)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if USE(NETWORK_SESSION)
+
+#include "NetworkDataTask.h"
+#include <WebCore/ResourceHandleTypes.h>
+#include <WebCore/ResourceRequest.h>
+#include <WebCore/ResourceResponse.h>
+#include <WebCore/SessionID.h>
+#include <wtf/Function.h>
+
+namespace WebCore {
+class SecurityOrigin;
+}
+
+namespace WebKit {
+
+class NetworkCORSPreflightChecker final : private NetworkDataTaskClient {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ struct Parameters {
+ WebCore::ResourceRequest originalRequest;
+ Ref<WebCore::SecurityOrigin> sourceOrigin;
+ WebCore::SessionID sessionID;
+ WebCore::StoredCredentials allowStoredCredentials;
+ };
+ enum class Result { Success, Failure };
+ using CompletionCallback = WTF::Function<void(Result)>;
+
+ NetworkCORSPreflightChecker(Parameters&&, CompletionCallback&&);
+ ~NetworkCORSPreflightChecker();
+
+ void startPreflight();
+
+private:
+ void willPerformHTTPRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, RedirectCompletionHandler&&) final;
+ void didReceiveChallenge(const WebCore::AuthenticationChallenge&, ChallengeCompletionHandler&&) final;
+ void didReceiveResponseNetworkSession(WebCore::ResourceResponse&&, ResponseCompletionHandler&&) final;
+ void didReceiveData(Ref<WebCore::SharedBuffer>&&) final;
+ void didCompleteWithError(const WebCore::ResourceError&, const WebCore::NetworkLoadMetrics&) final;
+ void didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend) final;
+ void wasBlocked() final;
+ void cannotShowURL() final;
+
+ Parameters m_parameters;
+ WebCore::ResourceResponse m_response;
+ CompletionCallback m_completionCallback;
+ RefPtr<NetworkDataTask> m_task;
+};
+
+} // namespace WebKit
+
+#endif // USE(NETWORK_SESSION)
Modified: trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp (220441 => 220442)
--- trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp 2017-08-09 05:15:47 UTC (rev 220442)
@@ -222,11 +222,11 @@
loader->start();
}
-void NetworkConnectionToWebProcess::loadPing(const NetworkResourceLoadParameters& loadParameters)
+void NetworkConnectionToWebProcess::loadPing(NetworkResourceLoadParameters&& loadParameters)
{
#if USE(NETWORK_SESSION)
// PingLoad manages its own lifetime, deleting itself when its purpose has been fulfilled.
- new PingLoad(loadParameters);
+ new PingLoad(WTFMove(loadParameters));
#else
RefPtr<NetworkingContext> context = RemoteNetworkingContext::create(loadParameters.sessionID, loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect);
Modified: trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h (220441 => 220442)
--- trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h 2017-08-09 05:15:47 UTC (rev 220442)
@@ -82,7 +82,7 @@
void scheduleResourceLoad(const NetworkResourceLoadParameters&);
void performSynchronousLoad(const NetworkResourceLoadParameters&, Ref<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply>&&);
- void loadPing(const NetworkResourceLoadParameters&);
+ void loadPing(NetworkResourceLoadParameters&&);
void prefetchDNS(const String&);
void removeLoadIdentifier(ResourceLoadIdentifier);
Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp (220441 => 220442)
--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp 2017-08-09 05:15:47 UTC (rev 220442)
@@ -29,6 +29,7 @@
#include "ArgumentCoders.h"
#include "DataReference.h"
#include "WebCoreArgumentCoders.h"
+#include <WebCore/SecurityOriginData.h>
using namespace WebCore;
@@ -81,6 +82,11 @@
encoder << needsCertificateInfo;
encoder << maximumBufferingTime;
encoder << derivedCachedDataTypesToRetrieve;
+
+ encoder << static_cast<bool>(sourceOrigin);
+ if (sourceOrigin)
+ encoder << SecurityOriginData::fromSecurityOrigin(*sourceOrigin);
+ encoder.encodeEnum(mode);
}
bool NetworkResourceLoadParameters::decode(IPC::Decoder& decoder, NetworkResourceLoadParameters& result)
@@ -145,6 +151,19 @@
if (!decoder.decode(result.derivedCachedDataTypesToRetrieve))
return false;
+ bool hasSourceOrigin;
+ if (!decoder.decode(hasSourceOrigin))
+ return false;
+ if (hasSourceOrigin) {
+ SecurityOriginData sourceOriginData;
+ if (!decoder.decode(sourceOriginData))
+ return false;
+ ASSERT(!sourceOriginData.isEmpty());
+ result.sourceOrigin = sourceOriginData.securityOrigin();
+ }
+ if (!decoder.decodeEnum(result.mode))
+ return false;
+
return true;
}
Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h (220441 => 220442)
--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h 2017-08-09 05:15:47 UTC (rev 220442)
@@ -28,9 +28,11 @@
#include "NetworkLoadParameters.h"
#include "SandboxExtension.h"
+#include <WebCore/FetchOptions.h>
#include <WebCore/ResourceHandle.h>
#include <WebCore/ResourceLoaderOptions.h>
#include <WebCore/ResourceRequest.h>
+#include <WebCore/SecurityOrigin.h>
#include <WebCore/SessionID.h>
#include <wtf/Seconds.h>
@@ -53,6 +55,8 @@
RefPtr<SandboxExtension> resourceSandboxExtension; // Created automatically for the sender.
Seconds maximumBufferingTime;
Vector<String> derivedCachedDataTypesToRetrieve;
+ RefPtr<WebCore::SecurityOrigin> sourceOrigin;
+ WebCore::FetchOptions::Mode mode;
};
} // namespace WebKit
Added: trunk/Source/WebKit/NetworkProcess/PingLoad.cpp (0 => 220442)
--- trunk/Source/WebKit/NetworkProcess/PingLoad.cpp (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/PingLoad.cpp 2017-08-09 05:15:47 UTC (rev 220442)
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PingLoad.h"
+
+#if USE(NETWORK_SESSION)
+
+#include "AuthenticationManager.h"
+#include "Logging.h"
+#include "NetworkCORSPreflightChecker.h"
+#include "SessionTracker.h"
+
+#define RELEASE_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(m_parameters.sessionID.isAlwaysOnLoggingAllowed(), Network, "%p - PingLoad::" fmt, this, ##__VA_ARGS__)
+
+namespace WebKit {
+
+using namespace WebCore;
+
+PingLoad::PingLoad(NetworkResourceLoadParameters&& parameters)
+ : m_parameters(WTFMove(parameters))
+ , m_timeoutTimer(*this, &PingLoad::timeoutTimerFired)
+{
+ // If the server never responds, this object will hang around forever.
+ // Set a very generous timeout, just in case.
+ m_timeoutTimer.startOneShot(60000_s);
+
+ if (needsCORSPreflight(m_parameters.request))
+ doCORSPreflight(m_parameters.request);
+ else
+ startNetworkLoad();
+}
+
+PingLoad::~PingLoad()
+{
+ if (m_task) {
+ ASSERT(m_task->client() == this);
+ m_task->clearClient();
+ m_task->cancel();
+ }
+}
+
+void PingLoad::startNetworkLoad()
+{
+ RELEASE_LOG_IF_ALLOWED("startNetworkLoad");
+ if (auto* networkSession = SessionTracker::networkSession(m_parameters.sessionID)) {
+ m_task = NetworkDataTask::create(*networkSession, *this, m_parameters);
+ m_task->resume();
+ } else
+ ASSERT_NOT_REACHED();
+}
+
+void PingLoad::willPerformHTTPRedirection(ResourceResponse&&, ResourceRequest&& request, RedirectCompletionHandler&& completionHandler)
+{
+ RELEASE_LOG_IF_ALLOWED("willPerformHTTPRedirection");
+ // FIXME: Do a CORS preflight if necessary.
+ // FIXME: We should ensure the number of redirects does not exceed 20.
+ completionHandler(m_parameters.shouldFollowRedirects ? request : ResourceRequest());
+}
+
+void PingLoad::didReceiveChallenge(const AuthenticationChallenge&, ChallengeCompletionHandler&& completionHandler)
+{
+ RELEASE_LOG_IF_ALLOWED("didReceiveChallenge");
+ completionHandler(AuthenticationChallengeDisposition::Cancel, { });
+ delete this;
+}
+
+void PingLoad::didReceiveResponseNetworkSession(ResourceResponse&&, ResponseCompletionHandler&& completionHandler)
+{
+ RELEASE_LOG_IF_ALLOWED("didReceiveResponseNetworkSession");
+ completionHandler(PolicyAction::PolicyIgnore);
+ delete this;
+}
+
+void PingLoad::didReceiveData(Ref<SharedBuffer>&&)
+{
+ RELEASE_LOG_IF_ALLOWED("didReceiveData");
+ ASSERT_NOT_REACHED();
+}
+
+void PingLoad::didCompleteWithError(const ResourceError& error, const NetworkLoadMetrics&)
+{
+ if (error.isNull())
+ RELEASE_LOG_IF_ALLOWED("didComplete");
+ else
+ RELEASE_LOG_IF_ALLOWED("didCompleteWithError, error_code: %d", error.errorCode());
+ delete this;
+}
+
+void PingLoad::didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend)
+{
+}
+
+void PingLoad::wasBlocked()
+{
+ RELEASE_LOG_IF_ALLOWED("wasBlocked");
+ delete this;
+}
+
+void PingLoad::cannotShowURL()
+{
+ RELEASE_LOG_IF_ALLOWED("cannotShowURL");
+ delete this;
+}
+
+void PingLoad::timeoutTimerFired()
+{
+ RELEASE_LOG_IF_ALLOWED("timeoutTimerFired");
+ delete this;
+}
+
+bool PingLoad::needsCORSPreflight(const ResourceRequest& request) const
+{
+ if (m_parameters.mode == FetchOptions::Mode::Cors) {
+ ASSERT(m_parameters.sourceOrigin);
+ return !m_parameters.sourceOrigin->canRequest(request.url());
+ }
+ return false;
+}
+
+void PingLoad::doCORSPreflight(const ResourceRequest& request)
+{
+ RELEASE_LOG_IF_ALLOWED("doCORSPreflight");
+ ASSERT(!m_corsPreflightChecker);
+ ASSERT(m_parameters.sourceOrigin);
+
+ NetworkCORSPreflightChecker::Parameters parameters = {
+ request,
+ *m_parameters.sourceOrigin,
+ m_parameters.sessionID,
+ m_parameters.allowStoredCredentials
+ };
+ m_corsPreflightChecker = std::make_unique<NetworkCORSPreflightChecker>(WTFMove(parameters), [this](NetworkCORSPreflightChecker::Result result) {
+ RELEASE_LOG_IF_ALLOWED("doCORSPreflight complete, success: %d", result == NetworkCORSPreflightChecker::Result::Success);
+ if (result == NetworkCORSPreflightChecker::Result::Success) {
+ m_corsPreflightChecker = nullptr;
+ startNetworkLoad();
+ } else
+ delete this;
+ });
+ m_corsPreflightChecker->startPreflight();
+}
+
+} // namespace WebKit
+
+#endif // USE(NETWORK_SESSION)
Modified: trunk/Source/WebKit/NetworkProcess/PingLoad.h (220441 => 220442)
--- trunk/Source/WebKit/NetworkProcess/PingLoad.h 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebKit/NetworkProcess/PingLoad.h 2017-08-09 05:15:47 UTC (rev 220442)
@@ -23,69 +23,44 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef PingLoad_h
-#define PingLoad_h
+#pragma once
-#include "AuthenticationManager.h"
+#if USE(NETWORK_SESSION)
+
#include "NetworkDataTask.h"
-#include "SessionTracker.h"
+#include "NetworkResourceLoadParameters.h"
namespace WebKit {
+class NetworkCORSPreflightChecker;
+
class PingLoad final : private NetworkDataTaskClient {
public:
- PingLoad(const NetworkResourceLoadParameters& parameters)
- : m_timeoutTimer(*this, &PingLoad::timeoutTimerFired)
- , m_shouldFollowRedirects(parameters.shouldFollowRedirects)
- {
- if (auto* networkSession = SessionTracker::networkSession(parameters.sessionID)) {
- m_task = NetworkDataTask::create(*networkSession, *this, parameters);
- m_task->resume();
- } else
- ASSERT_NOT_REACHED();
-
- // If the server never responds, this object will hang around forever.
- // Set a very generous timeout, just in case.
- m_timeoutTimer.startOneShot(60000_s);
- }
+ explicit PingLoad(NetworkResourceLoadParameters&&);
private:
- void willPerformHTTPRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&& request, RedirectCompletionHandler&& completionHandler) final
- {
- completionHandler(m_shouldFollowRedirects ? request : WebCore::ResourceRequest());
- }
- void didReceiveChallenge(const WebCore::AuthenticationChallenge&, ChallengeCompletionHandler&& completionHandler) final
- {
- completionHandler(AuthenticationChallengeDisposition::Cancel, { });
- delete this;
- }
- void didReceiveResponseNetworkSession(WebCore::ResourceResponse&&, ResponseCompletionHandler&& completionHandler) final
- {
- completionHandler(WebCore::PolicyAction::PolicyIgnore);
- delete this;
- }
- void didReceiveData(Ref<WebCore::SharedBuffer>&&) final { ASSERT_NOT_REACHED(); }
- void didCompleteWithError(const WebCore::ResourceError&, const WebCore::NetworkLoadMetrics&) final { delete this; }
- void didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend) final { }
- void wasBlocked() final { delete this; }
- void cannotShowURL() final { delete this; }
+ ~PingLoad();
- void timeoutTimerFired() { delete this; }
+ void willPerformHTTPRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, RedirectCompletionHandler&&) final;
+ void didReceiveChallenge(const WebCore::AuthenticationChallenge&, ChallengeCompletionHandler&&) final;
+ void didReceiveResponseNetworkSession(WebCore::ResourceResponse&&, ResponseCompletionHandler&&) final;
+ void didReceiveData(Ref<WebCore::SharedBuffer>&&) final;
+ void didCompleteWithError(const WebCore::ResourceError&, const WebCore::NetworkLoadMetrics&) final;
+ void didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend) final;
+ void wasBlocked() final;
+ void cannotShowURL() final;
+ void timeoutTimerFired();
+
+ void startNetworkLoad();
+ bool needsCORSPreflight(const WebCore::ResourceRequest&) const;
+ void doCORSPreflight(const WebCore::ResourceRequest&);
- virtual ~PingLoad()
- {
- if (m_task) {
- ASSERT(m_task->client() == this);
- m_task->clearClient();
- m_task->cancel();
- }
- }
-
+ NetworkResourceLoadParameters m_parameters;
RefPtr<NetworkDataTask> m_task;
WebCore::Timer m_timeoutTimer;
- bool m_shouldFollowRedirects;
+ std::unique_ptr<NetworkCORSPreflightChecker> m_corsPreflightChecker;
};
}
-#endif
+#endif // USE(NETWORK_SESSION)
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (220441 => 220442)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2017-08-09 05:15:47 UTC (rev 220442)
@@ -902,11 +902,14 @@
41FAF5F81E3C1021001AE678 /* LibWebRTCResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 41FAF5F61E3C0B47001AE678 /* LibWebRTCResolver.h */; };
41FAF5F91E3C1025001AE678 /* LibWebRTCResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41FAF5F71E3C0B47001AE678 /* LibWebRTCResolver.cpp */; };
4450AEC01DC3FAE5009943F2 /* SharedMemoryCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4450AEBF1DC3FAE5009943F2 /* SharedMemoryCocoa.cpp */; };
+ 462107D81F38DBDB00DD7810 /* PingLoad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 462107D71F38DBD300DD7810 /* PingLoad.cpp */; };
463FD4801EB9459600A2982C /* WKProcessTerminationReason.h in Headers */ = {isa = PBXBuildFile; fileRef = 463FD47F1EB9458400A2982C /* WKProcessTerminationReason.h */; settings = {ATTRIBUTES = (Private, ); }; };
463FD4821EB94EC000A2982C /* ProcessTerminationReason.h in Headers */ = {isa = PBXBuildFile; fileRef = 463FD4811EB94EAD00A2982C /* ProcessTerminationReason.h */; };
465250E61ECF52DC002025CB /* WebKit2InitializeCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 465250E51ECF52CD002025CB /* WebKit2InitializeCocoa.mm */; };
46A2B6081E5676A600C3DEDA /* BackgroundProcessResponsivenessTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A2B6061E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.cpp */; };
46A2B6091E5676A600C3DEDA /* BackgroundProcessResponsivenessTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A2B6071E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.h */; };
+ 46DF063B1F3905F8001980BB /* NetworkCORSPreflightChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46DF06391F3905E5001980BB /* NetworkCORSPreflightChecker.cpp */; };
+ 46DF063C1F3905F8001980BB /* NetworkCORSPreflightChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46DF063A1F3905E5001980BB /* NetworkCORSPreflightChecker.h */; };
4A3CC18A19B063E700D14AEF /* UserMediaPermissionRequestManagerProxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A410F3919AF7B04002EBAB5 /* UserMediaPermissionRequestManagerProxy.cpp */; };
4A3CC18B19B0640F00D14AEF /* UserMediaPermissionRequestManagerProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A410F3A19AF7B04002EBAB5 /* UserMediaPermissionRequestManagerProxy.h */; };
4A3CC18C19B0641500D14AEF /* UserMediaPermissionRequestProxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A410F3B19AF7B04002EBAB5 /* UserMediaPermissionRequestProxy.cpp */; };
@@ -3149,11 +3152,14 @@
41FAF5F61E3C0B47001AE678 /* LibWebRTCResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LibWebRTCResolver.h; path = Network/webrtc/LibWebRTCResolver.h; sourceTree = "<group>"; };
41FAF5F71E3C0B47001AE678 /* LibWebRTCResolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibWebRTCResolver.cpp; path = Network/webrtc/LibWebRTCResolver.cpp; sourceTree = "<group>"; };
4450AEBF1DC3FAE5009943F2 /* SharedMemoryCocoa.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SharedMemoryCocoa.cpp; path = cocoa/SharedMemoryCocoa.cpp; sourceTree = "<group>"; };
+ 462107D71F38DBD300DD7810 /* PingLoad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PingLoad.cpp; path = NetworkProcess/PingLoad.cpp; sourceTree = "<group>"; };
463FD47F1EB9458400A2982C /* WKProcessTerminationReason.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKProcessTerminationReason.h; sourceTree = "<group>"; };
463FD4811EB94EAD00A2982C /* ProcessTerminationReason.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessTerminationReason.h; sourceTree = "<group>"; };
465250E51ECF52CD002025CB /* WebKit2InitializeCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebKit2InitializeCocoa.mm; sourceTree = "<group>"; };
46A2B6061E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BackgroundProcessResponsivenessTimer.cpp; sourceTree = "<group>"; };
46A2B6071E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackgroundProcessResponsivenessTimer.h; sourceTree = "<group>"; };
+ 46DF06391F3905E5001980BB /* NetworkCORSPreflightChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkCORSPreflightChecker.cpp; path = NetworkProcess/NetworkCORSPreflightChecker.cpp; sourceTree = "<group>"; };
+ 46DF063A1F3905E5001980BB /* NetworkCORSPreflightChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkCORSPreflightChecker.h; path = NetworkProcess/NetworkCORSPreflightChecker.h; sourceTree = "<group>"; };
4A410F3519AF7AC3002EBAB5 /* WKUserMediaPermissionRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKUserMediaPermissionRequest.cpp; sourceTree = "<group>"; };
4A410F3619AF7AC3002EBAB5 /* WKUserMediaPermissionRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKUserMediaPermissionRequest.h; sourceTree = "<group>"; };
4A410F3919AF7B04002EBAB5 /* UserMediaPermissionRequestManagerProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserMediaPermissionRequestManagerProxy.cpp; sourceTree = "<group>"; };
@@ -5955,6 +5961,8 @@
2DA944BB188511DD00ED86DB /* ios */,
510CC7DC16138E2900D03ED3 /* mac */,
413075971DE84ED70039EC69 /* webrtc */,
+ 46DF06391F3905E5001980BB /* NetworkCORSPreflightChecker.cpp */,
+ 46DF063A1F3905E5001980BB /* NetworkCORSPreflightChecker.h */,
513A16491630A9BF005D7D22 /* NetworkConnectionToWebProcess.cpp */,
513A164A1630A9BF005D7D22 /* NetworkConnectionToWebProcess.h */,
513A164B1630A9BF005D7D22 /* NetworkConnectionToWebProcess.messages.in */,
@@ -5984,6 +5992,7 @@
5C0B177D1E7C886700E9123C /* NetworkSocketStream.cpp */,
5C0B177E1E7C886700E9123C /* NetworkSocketStream.h */,
5C0B177F1E7C886700E9123C /* NetworkSocketStream.messages.in */,
+ 462107D71F38DBD300DD7810 /* PingLoad.cpp */,
5CE85B1F1C88E6430070BFCE /* PingLoad.h */,
E1B78470163F24690007B692 /* RemoteNetworkingContext.h */,
);
@@ -8578,6 +8587,7 @@
1AF1AC6C1651759E00C17D7F /* RemoteLayerTreeTransaction.h in Headers */,
E1B78471163F24690007B692 /* RemoteNetworkingContext.h in Headers */,
1A5704FC1BE1751100874AF1 /* RemoteObjectInvocation.h in Headers */,
+ 46DF063C1F3905F8001980BB /* NetworkCORSPreflightChecker.h in Headers */,
1AC1338018590AE400F3EC05 /* RemoteObjectRegistry.h in Headers */,
1AC1338618590C4600F3EC05 /* RemoteObjectRegistryMessages.h in Headers */,
0F594790187B3B3A00437857 /* RemoteScrollingCoordinator.h in Headers */,
@@ -9860,6 +9870,7 @@
BCEE966C112FAF57006BCC24 /* Attachment.cpp in Sources */,
E1A31735134CEA80007C9A4F /* AttributedString.mm in Sources */,
512F589612A8838800629530 /* AuthenticationChallengeProxy.cpp in Sources */,
+ 46DF063B1F3905F8001980BB /* NetworkCORSPreflightChecker.cpp in Sources */,
512F589812A8838800629530 /* AuthenticationDecisionListener.cpp in Sources */,
518E8EF816B2091C00E91429 /* AuthenticationManager.cpp in Sources */,
518E8EFB16B2091C00E91429 /* AuthenticationManager.mac.mm in Sources */,
@@ -10200,6 +10211,7 @@
51E35209180F5D6B00E53BE9 /* StorageServiceEntryPoint.mm in Sources */,
51E35200180F5D0F00E53BE9 /* StorageToWebProcessConnection.cpp in Sources */,
5118E9AC1F295977003EF9F5 /* StorageToWebProcessConnectionMessageReceiver.cpp in Sources */,
+ 462107D81F38DBDB00DD7810 /* PingLoad.cpp in Sources */,
1AE00D6B18327C1200087DD7 /* StringReference.cpp in Sources */,
296BD85E15019BC30071F424 /* StringUtilities.mm in Sources */,
1ZZ417EF12C00D87002BE67B /* TextCheckerCompletion.cpp in Sources */,
Modified: trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp (220441 => 220442)
--- trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp 2017-08-09 05:15:47 UTC (rev 220442)
@@ -50,6 +50,7 @@
#include <WebCore/DiagnosticLoggingKeys.h>
#include <WebCore/Document.h>
#include <WebCore/DocumentLoader.h>
+#include <WebCore/FetchOptions.h>
#include <WebCore/Frame.h>
#include <WebCore/FrameLoader.h>
#include <WebCore/NetscapePlugInStreamLoader.h>
@@ -56,6 +57,7 @@
#include <WebCore/PlatformStrategies.h>
#include <WebCore/ReferrerPolicy.h>
#include <WebCore/ResourceLoader.h>
+#include <WebCore/SecurityOrigin.h>
#include <WebCore/SessionID.h>
#include <WebCore/Settings.h>
#include <WebCore/SubresourceLoader.h>
@@ -383,7 +385,7 @@
}
}
-void WebLoaderStrategy::createPingHandle(NetworkingContext* networkingContext, ResourceRequest& request, bool shouldUseCredentialStorage, bool shouldFollowRedirects)
+void WebLoaderStrategy::createPingHandle(NetworkingContext* networkingContext, ResourceRequest& request, Ref<SecurityOrigin>&& sourceOrigin, const FetchOptions& options)
{
// It's possible that call to createPingHandle might be made during initial empty Document creation before a NetworkingContext exists.
// It is not clear that we should send ping loads during that process anyways.
@@ -397,9 +399,11 @@
NetworkResourceLoadParameters loadParameters;
loadParameters.request = request;
+ loadParameters.sourceOrigin = WTFMove(sourceOrigin);
loadParameters.sessionID = webPage ? webPage->sessionID() : SessionID::defaultSessionID();
- loadParameters.allowStoredCredentials = shouldUseCredentialStorage ? AllowStoredCredentials : DoNotAllowStoredCredentials;
- loadParameters.shouldFollowRedirects = shouldFollowRedirects;
+ loadParameters.allowStoredCredentials = options.credentials == FetchOptions::Credentials::Omit ? DoNotAllowStoredCredentials : AllowStoredCredentials;
+ loadParameters.mode = options.mode;
+ loadParameters.shouldFollowRedirects = options.redirect == FetchOptions::Redirect::Follow;
loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = networkingContext->shouldClearReferrerOnHTTPSToHTTPRedirect();
WebProcess::singleton().networkConnection().connection().send(Messages::NetworkConnectionToWebProcess::LoadPing(loadParameters), 0);
Modified: trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h (220441 => 220442)
--- trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h 2017-08-09 05:15:47 UTC (rev 220442)
@@ -31,6 +31,10 @@
#include <wtf/HashSet.h>
#include <wtf/RunLoop.h>
+namespace WebCore {
+struct FetchOptions;
+}
+
namespace WebKit {
class NetworkProcessConnection;
@@ -55,7 +59,7 @@
void suspendPendingRequests() override;
void resumePendingRequests() override;
- void createPingHandle(WebCore::NetworkingContext*, WebCore::ResourceRequest&, bool shouldUseCredentialStorage, bool shouldFollowRedirects) override;
+ void createPingHandle(WebCore::NetworkingContext*, WebCore::ResourceRequest&, Ref<WebCore::SecurityOrigin>&& sourceOrigin, const WebCore::FetchOptions&) override;
void storeDerivedDataToCache(const SHA1::Digest& bodyHash, const String& type, const String& partition, WebCore::SharedBuffer&) override;
Modified: trunk/Source/WebKitLegacy/ChangeLog (220441 => 220442)
--- trunk/Source/WebKitLegacy/ChangeLog 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebKitLegacy/ChangeLog 2017-08-09 05:15:47 UTC (rev 220442)
@@ -1,3 +1,18 @@
+2017-08-08 Chris Dumez <cdu...@apple.com>
+
+ [Beacon] Add support for CORS-preflighting for WK2 / NETWORK_SESSION
+ https://bugs.webkit.org/show_bug.cgi?id=175264
+ <rdar://problem/33547793>
+
+ Reviewed by Youenn Fablet.
+
+ createPingHandle() now takes new parameters but there is currently no behavior
+ change on WebKit1.
+
+ * WebCoreSupport/WebResourceLoadScheduler.cpp:
+ (WebResourceLoadScheduler::createPingHandle):
+ * WebCoreSupport/WebResourceLoadScheduler.h:
+
2017-08-03 Per Arne Vollan <pvol...@apple.com>
[Win] WebKit COM header file is not placed in the correct location.
Modified: trunk/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.cpp (220441 => 220442)
--- trunk/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.cpp 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.cpp 2017-08-09 05:15:47 UTC (rev 220442)
@@ -26,6 +26,7 @@
#include <WebCore/Document.h>
#include <WebCore/DocumentLoader.h>
+#include <WebCore/FetchOptions.h>
#include <WebCore/Frame.h>
#include <WebCore/FrameLoader.h>
#include <WebCore/NetscapePlugInStreamLoader.h>
@@ -362,9 +363,9 @@
return m_requestsLoading.size() >= (webResourceLoadScheduler().isSerialLoadingEnabled() ? 1 : m_maxRequestsInFlight);
}
-void WebResourceLoadScheduler::createPingHandle(NetworkingContext* networkingContext, ResourceRequest& request, bool shouldUseCredentialStorage, bool shouldFollowRedirects)
+void WebResourceLoadScheduler::createPingHandle(NetworkingContext* networkingContext, ResourceRequest& request, Ref<SecurityOrigin>&&, const FetchOptions& options)
{
// PingHandle manages its own lifetime, deleting itself when its purpose has been fulfilled.
- new PingHandle(networkingContext, request, shouldUseCredentialStorage, PingHandle::UsesAsyncCallbacks::No, shouldFollowRedirects);
+ new PingHandle(networkingContext, request, options.credentials != FetchOptions::Credentials::Omit, PingHandle::UsesAsyncCallbacks::No, options.redirect == FetchOptions::Redirect::Follow);
}
Modified: trunk/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.h (220441 => 220442)
--- trunk/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.h 2017-08-09 03:48:44 UTC (rev 220441)
+++ trunk/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.h 2017-08-09 05:15:47 UTC (rev 220442)
@@ -37,6 +37,11 @@
class WebResourceLoadScheduler;
+namespace WebCore {
+struct FetchOptions;
+class SecurityOrigin;
+}
+
WebResourceLoadScheduler& webResourceLoadScheduler();
class WebResourceLoadScheduler : public WebCore::LoaderStrategy {
@@ -54,7 +59,7 @@
void suspendPendingRequests() override;
void resumePendingRequests() override;
- void createPingHandle(WebCore::NetworkingContext*, WebCore::ResourceRequest&, bool shouldUseCredentialStorage, bool shouldFollowRedirects) override;
+ void createPingHandle(WebCore::NetworkingContext*, WebCore::ResourceRequest&, Ref<WebCore::SecurityOrigin>&& sourceOrigin, const WebCore::FetchOptions&) override;
void storeDerivedDataToCache(const SHA1::Digest&, const String&, const String&, WebCore::SharedBuffer&) override { }