Diff
Modified: trunk/LayoutTests/ChangeLog (220496 => 220497)
--- trunk/LayoutTests/ChangeLog 2017-08-09 23:18:13 UTC (rev 220496)
+++ trunk/LayoutTests/ChangeLog 2017-08-09 23:23:58 UTC (rev 220497)
@@ -1,5 +1,26 @@
2017-08-09 Chris Dumez <cdu...@apple.com>
+ [Beacon][NetworkSession] Support CORS-preflighting on redirects
+ https://bugs.webkit.org/show_bug.cgi?id=175386
+ <rdar://problem/33801370>
+
+ Reviewed by Youenn Fablet.
+
+ Add layout test coverage.
+
+ * http/wpt/beacon/cors/cors-preflight-redirect-failure-expected.txt: Added.
+ * http/wpt/beacon/cors/cors-preflight-redirect-failure.html: Added.
+ * http/wpt/beacon/cors/cors-preflight-redirect-from-crossorigin-to-sameorigin-expected.txt: Added.
+ * http/wpt/beacon/cors/cors-preflight-redirect-from-crossorigin-to-sameorigin.html: Added.
+ * http/wpt/beacon/cors/cors-preflight-redirect-success-expected.txt: Added.
+ * http/wpt/beacon/cors/cors-preflight-redirect-success.html: Added.
+ * http/wpt/beacon/resources/beacon-preflight.py:
+ (main):
+ * http/wpt/beacon/resources/redirect.py: Added.
+ (main):
+
+2017-08-09 Chris Dumez <cdu...@apple.com>
+
Unreviewed, deflake http/wpt/beacon/keepalive-after-navigation.html
Temporarily restore previous timeout on this test to address flakiness on the
Modified: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-failure.html (220496 => 220497)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-failure.html 2017-08-09 23:18:13 UTC (rev 220496)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-failure.html 2017-08-09 23:23:58 UTC (rev 220497)
@@ -18,7 +18,7 @@
return new Promise(resolve => {
step_timeout(test.step_func(() => {
fetch(checkUrl).then(response => {
- response.text().then(body => {
+ response.json().then(body => {
resolve(body);
});
});
@@ -33,8 +33,7 @@
promise_test(function(test) {
assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
- return pollResult(test, id) .then(json => {
- result = JSON.parse(json);
+ return pollResult(test, id) .then(result => {
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")
Modified: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-success.html (220496 => 220497)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-success.html 2017-08-09 23:18:13 UTC (rev 220496)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-success.html 2017-08-09 23:23:58 UTC (rev 220497)
@@ -18,7 +18,7 @@
return new Promise(resolve => {
step_timeout(test.step_func(() => {
fetch(checkUrl).then(response => {
- response.text().then(body => {
+ response.json().then(body => {
resolve(body);
});
});
@@ -33,8 +33,7 @@
promise_test(function(test) {
assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
- return pollResult(test, id) .then(json => {
- result = JSON.parse(json);
+ return pollResult(test, id) .then(result => {
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")
Modified: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-failure.html (220496 => 220497)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-failure.html 2017-08-09 23:18:13 UTC (rev 220496)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-failure.html 2017-08-09 23:23:58 UTC (rev 220497)
@@ -18,7 +18,7 @@
return new Promise(resolve => {
step_timeout(test.step_func(() => {
fetch(checkUrl).then(response => {
- response.text().then(body => {
+ response.json().then(body => {
resolve(body);
});
});
@@ -33,8 +33,7 @@
promise_test(function(test) {
assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
- return pollResult(test, id) .then(json => {
- result = JSON.parse(json);
+ return pollResult(test, id) .then(result => {
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")
Modified: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-success.html (220496 => 220497)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-success.html 2017-08-09 23:18:13 UTC (rev 220496)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-success.html 2017-08-09 23:23:58 UTC (rev 220497)
@@ -18,7 +18,7 @@
return new Promise(resolve => {
step_timeout(test.step_func(() => {
fetch(checkUrl).then(response => {
- response.text().then(body => {
+ response.json().then(body => {
resolve(body);
});
});
@@ -33,8 +33,7 @@
promise_test(function(test) {
assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
- return pollResult(test, id) .then(json => {
- result = JSON.parse(json);
+ return pollResult(test, id) .then(result => {
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")
Modified: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-cookie.html (220496 => 220497)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-cookie.html 2017-08-09 23:18:13 UTC (rev 220496)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-cookie.html 2017-08-09 23:23:58 UTC (rev 220497)
@@ -21,7 +21,7 @@
return new Promise(resolve => {
step_timeout(test.step_func(() => {
fetch(checkUrl).then(response => {
- response.text().then(body => {
+ response.json().then(body => {
resolve(body);
});
});
@@ -46,8 +46,7 @@
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);
+ return pollResult(test, id).then(result => {
assert_equals(result['preflight'], 1, "Received preflight")
assert_equals(result['preflight_cookie_header'], "", "Preflight cookie header")
assert_equals(result['beacon'], 1, "Received beacon")
Added: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-failure-expected.txt (0 => 220497)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-failure-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-failure-expected.txt 2017-08-09 23:23:58 UTC (rev 220497)
@@ -0,0 +1,3 @@
+
+PASS CORS preflight failure test
+
Copied: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-failure.html (from rev 220496, trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-failure.html) (0 => 220497)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-failure.html (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-failure.html 2017-08-09 23:23:58 UTC (rev 220497)
@@ -0,0 +1,52 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>SendBeacon CORS preflight on redirect 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.json().then(body => {
+ resolve(body);
+ });
+ });
+ }), 1000);
+ });
+}
+
+function testCORSPreflightRedirectSuccess(what) {
+ var testBase = get_host_info().HTTP_REMOTE_ORIGIN + RESOURCES_DIR;
+ var id = self.token();
+ var target = encodeURIComponent(testBase + "beacon-preflight.py?allowCors=0&cmd=put&id=" + id);
+
+ // 307 & 308 redirections are the only ones that maintain the POST method.
+ var testUrl = RESOURCES_DIR + "redirect.py?redirect_status=307&location=" + target;
+
+ promise_test(function(test) {
+ assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
+ return pollResult(test, id) .then(result => {
+ 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")
+ assert_equals(result['beacon'], 0, "Did not receive beacon")
+ });
+ }, "CORS preflight failure test");
+}
+
+let blob = new Blob(["123"], {type: "application/octet-stream"});
+testCORSPreflightRedirectSuccess(blob);
+ </script>
+ </body>
+</html>
Added: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-from-crossorigin-to-sameorigin-expected.txt (0 => 220497)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-from-crossorigin-to-sameorigin-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-from-crossorigin-to-sameorigin-expected.txt 2017-08-09 23:23:58 UTC (rev 220497)
@@ -0,0 +1,3 @@
+
+PASS CORS preflight success test
+
Copied: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-from-crossorigin-to-sameorigin.html (from rev 220496, trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-success.html) (0 => 220497)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-from-crossorigin-to-sameorigin.html (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-from-crossorigin-to-sameorigin.html 2017-08-09 23:23:58 UTC (rev 220497)
@@ -0,0 +1,54 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>SendBeacon CORS preflight on redirect test from cross origin to same origin</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.json().then(body => {
+ resolve(body);
+ });
+ });
+ }), 1000);
+ });
+}
+
+function testCORSPreflightRedirectSuccess(what) {
+ var testBase = get_host_info().HTTP_REMOTE_ORIGIN + RESOURCES_DIR;
+ var id = self.token();
+ var target = encodeURIComponent(get_host_info().HTTP_ORIGIN + RESOURCES_DIR + "beacon-preflight.py?allowCors=1&cmd=put&id=" + id);
+
+ // 307 & 308 redirections are the only ones that maintain the POST method.
+ var testUrl = testBase + "redirect.py?redirect_status=307&location=" + target;
+
+ promise_test(function(test) {
+ assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
+ return pollResult(test, id) .then(result => {
+ 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")
+ assert_equals(result['preflight_origin'], "null", "Received beacon")
+ assert_equals(result['beacon'], 1, "Received beacon")
+ assert_equals(result['beacon_origin'], "null", "Received beacon")
+ });
+ }, "CORS preflight success test");
+}
+
+let blob = new Blob(["123"], {type: "application/octet-stream"});
+testCORSPreflightRedirectSuccess(blob);
+ </script>
+ </body>
+</html>
Added: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-success-expected.txt (0 => 220497)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-success-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-success-expected.txt 2017-08-09 23:23:58 UTC (rev 220497)
@@ -0,0 +1,3 @@
+
+PASS CORS preflight success test
+
Copied: trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-success.html (from rev 220496, trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-success.html) (0 => 220497)
--- trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-success.html (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-success.html 2017-08-09 23:23:58 UTC (rev 220497)
@@ -0,0 +1,52 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>SendBeacon CORS preflight on redirect 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.json().then(body => {
+ resolve(body);
+ });
+ });
+ }), 1000);
+ });
+}
+
+function testCORSPreflightRedirectSuccess(what) {
+ var testBase = get_host_info().HTTP_REMOTE_ORIGIN + RESOURCES_DIR;
+ var id = self.token();
+ var target = encodeURIComponent(testBase + "beacon-preflight.py?allowCors=1&cmd=put&id=" + id);
+
+ // 307 & 308 redirections are the only ones that maintain the POST method.
+ var testUrl = RESOURCES_DIR + "redirect.py?redirect_status=307&location=" + target;
+
+ promise_test(function(test) {
+ assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
+ return pollResult(test, id) .then(result => {
+ 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")
+ assert_equals(result['beacon'], 1, "Received beacon")
+ });
+ }, "CORS preflight success test");
+}
+
+let blob = new Blob(["123"], {type: "application/octet-stream"});
+testCORSPreflightRedirectSuccess(blob);
+ </script>
+ </body>
+</html>
Modified: trunk/LayoutTests/http/wpt/beacon/resources/beacon-preflight.py (220496 => 220497)
--- trunk/LayoutTests/http/wpt/beacon/resources/beacon-preflight.py 2017-08-09 23:18:13 UTC (rev 220496)
+++ trunk/LayoutTests/http/wpt/beacon/resources/beacon-preflight.py 2017-08-09 23:23:58 UTC (rev 220497)
@@ -35,11 +35,13 @@
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", "")
+ stashed_data['preflight_origin'] = request.headers.get("Origin", "")
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", "")
+ stashed_data['beacon_origin'] = request.headers.get("Origin", "")
request.server.stash.put(test_id, stashed_data)
return [("Content-Type", "text/plain")], ""
Added: trunk/LayoutTests/http/wpt/beacon/resources/redirect.py (0 => 220497)
--- trunk/LayoutTests/http/wpt/beacon/resources/redirect.py (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/resources/redirect.py 2017-08-09 23:23:58 UTC (rev 220497)
@@ -0,0 +1,63 @@
+from urllib import urlencode
+from urlparse import urlparse
+
+def main(request, response):
+ stashed_data = {'count': 0, 'preflight': "0"}
+ status = 302
+ headers = [("Content-Type", "text/plain"),
+ ("Cache-Control", "no-cache"),
+ ("Pragma", "no-cache"),
+ ("Access-Control-Allow-Credentials", "true")]
+ headers.append(("Access-Control-Allow-Origin", request.headers.get("Origin", "*")))
+ token = None
+
+ if "token" in request.GET:
+ token = request.GET.first("token")
+ data = ""
+ if data:
+ stashed_data = data
+
+ if request.method == "OPTIONS":
+ 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))
+ stashed_data['preflight'] = "1"
+ #Preflight is not redirected: return 200
+ if not "redirect_preflight" in request.GET:
+ if token:
+ request.server.stash.put(request.GET.first("token"), stashed_data)
+ return 200, headers, ""
+
+ if "redirect_status" in request.GET:
+ status = int(request.GET['redirect_status'])
+
+ stashed_data['count'] += 1
+
+ if "location" in request.GET:
+ url = ""
+ scheme = urlparse(url).scheme
+ if scheme == "" or scheme == "http" or scheme == "https":
+ url += "&" if '?' in url else "?"
+ #keep url parameters in location
+ url_parameters = {}
+ for item in request.GET.items():
+ url_parameters[item[0]] = item[1][0]
+ url += urlencode(url_parameters)
+ #make sure location changes during redirection loop
+ url += "&count=" + str(stashed_data['count'])
+ headers.append(("Location", url))
+
+ if "redirect_referrerpolicy" in request.GET:
+ headers.append(("Referrer-Policy", request.GET['redirect_referrerpolicy']))
+
+ if token:
+ request.server.stash.put(request.GET.first("token"), stashed_data)
+ if "max_count" in request.GET:
+ max_count = int(request.GET['max_count'])
+ #stop redirecting and return count
+ if stashed_data['count'] > max_count:
+ # -1 because the last is not a redirection
+ return str(stashed_data['count'] - 1)
+
+ return status, headers, ""
Modified: trunk/Source/WebCore/ChangeLog (220496 => 220497)
--- trunk/Source/WebCore/ChangeLog 2017-08-09 23:18:13 UTC (rev 220496)
+++ trunk/Source/WebCore/ChangeLog 2017-08-09 23:23:58 UTC (rev 220497)
@@ -1,3 +1,20 @@
+2017-08-09 Chris Dumez <cdu...@apple.com>
+
+ [Beacon][NetworkSession] Support CORS-preflighting on redirects
+ https://bugs.webkit.org/show_bug.cgi?id=175386
+ <rdar://problem/33801370>
+
+ Reviewed by Youenn Fablet.
+
+ Export a couple of WebCore symbols so I can use them in WebKit2.
+
+ Tests: http/wpt/beacon/cors/cors-preflight-redirect-failure.html
+ http/wpt/beacon/cors/cors-preflight-redirect-from-crossorigin-to-sameorigin.html
+ http/wpt/beacon/cors/cors-preflight-redirect-success.html
+
+ * loader/CrossOriginAccessControl.h:
+ * page/SecurityOrigin.h:
+
2017-08-09 Jeremy Jones <jere...@apple.com>
Use MPAVRoutingController instead of deprecated versions.
Modified: trunk/Source/WebCore/loader/CrossOriginAccessControl.h (220496 => 220497)
--- trunk/Source/WebCore/loader/CrossOriginAccessControl.h 2017-08-09 23:18:13 UTC (rev 220496)
+++ trunk/Source/WebCore/loader/CrossOriginAccessControl.h 2017-08-09 23:23:58 UTC (rev 220497)
@@ -40,7 +40,7 @@
bool isSimpleCrossOriginAccessRequest(const String& method, const HTTPHeaderMap&);
bool isOnAccessControlSimpleRequestMethodWhitelist(const String&);
-void updateRequestForAccessControl(ResourceRequest&, SecurityOrigin&, StoredCredentials);
+WEBCORE_EXPORT void updateRequestForAccessControl(ResourceRequest&, SecurityOrigin&, StoredCredentials);
WEBCORE_EXPORT ResourceRequest createAccessControlPreflightRequest(const ResourceRequest&, SecurityOrigin&, const String&);
bool isValidCrossOriginRedirectionURL(const URL&);
Modified: trunk/Source/WebCore/page/SecurityOrigin.h (220496 => 220497)
--- trunk/Source/WebCore/page/SecurityOrigin.h 2017-08-09 23:18:13 UTC (rev 220496)
+++ trunk/Source/WebCore/page/SecurityOrigin.h 2017-08-09 23:23:58 UTC (rev 220497)
@@ -50,7 +50,7 @@
};
WEBCORE_EXPORT static Ref<SecurityOrigin> create(const URL&);
- static Ref<SecurityOrigin> createUnique();
+ WEBCORE_EXPORT static Ref<SecurityOrigin> createUnique();
WEBCORE_EXPORT static Ref<SecurityOrigin> createFromString(const String&);
WEBCORE_EXPORT static Ref<SecurityOrigin> create(const String& protocol, const String& host, std::optional<uint16_t> port);
Modified: trunk/Source/WebKit/ChangeLog (220496 => 220497)
--- trunk/Source/WebKit/ChangeLog 2017-08-09 23:18:13 UTC (rev 220496)
+++ trunk/Source/WebKit/ChangeLog 2017-08-09 23:23:58 UTC (rev 220497)
@@ -1,3 +1,26 @@
+2017-08-09 Chris Dumez <cdu...@apple.com>
+
+ [Beacon][NetworkSession] Support CORS-preflighting on redirects
+ https://bugs.webkit.org/show_bug.cgi?id=175386
+ <rdar://problem/33801370>
+
+ Reviewed by Youenn Fablet.
+
+ Add support to Beacon for doing CORS-preflighting upon redirect to a different
+ domain.
+
+ * NetworkProcess/NetworkCORSPreflightChecker.h:
+ * NetworkProcess/PingLoad.cpp:
+ (WebKit::PingLoad::PingLoad):
+ (WebKit::PingLoad::~PingLoad):
+ (WebKit::PingLoad::loadRequest):
+ (WebKit::PingLoad::securityOrigin const):
+ (WebKit::PingLoad::willPerformHTTPRedirection):
+ (WebKit::PingLoad::didReceiveResponseNetworkSession):
+ (WebKit::PingLoad::needsCORSPreflight const):
+ (WebKit::PingLoad::doCORSPreflight):
+ * NetworkProcess/PingLoad.h:
+
2017-08-09 Jeremy Jones <jere...@apple.com>
Use MPAVRoutingController instead of deprecated versions.
Modified: trunk/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h (220496 => 220497)
--- trunk/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h 2017-08-09 23:18:13 UTC (rev 220496)
+++ trunk/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h 2017-08-09 23:23:58 UTC (rev 220497)
@@ -54,6 +54,7 @@
NetworkCORSPreflightChecker(Parameters&&, CompletionCallback&&);
~NetworkCORSPreflightChecker();
+ const WebCore::ResourceRequest& originalRequest() const { return m_parameters.originalRequest; }
void startPreflight();
Modified: trunk/Source/WebKit/NetworkProcess/PingLoad.cpp (220496 => 220497)
--- trunk/Source/WebKit/NetworkProcess/PingLoad.cpp 2017-08-09 23:18:13 UTC (rev 220496)
+++ trunk/Source/WebKit/NetworkProcess/PingLoad.cpp 2017-08-09 23:23:58 UTC (rev 220497)
@@ -32,6 +32,7 @@
#include "Logging.h"
#include "NetworkCORSPreflightChecker.h"
#include "SessionTracker.h"
+#include <WebCore/CrossOriginAccessControl.h>
#define RELEASE_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(m_parameters.sessionID.isAlwaysOnLoggingAllowed(), Network, "%p - PingLoad::" fmt, this, ##__VA_ARGS__)
@@ -42,6 +43,7 @@
PingLoad::PingLoad(NetworkResourceLoadParameters&& parameters)
: m_parameters(WTFMove(parameters))
, m_timeoutTimer(*this, &PingLoad::timeoutTimerFired)
+ , m_isSameOriginRequest(securityOrigin().canRequest(m_parameters.request.url()))
{
// If the server never responds, this object will hang around forever.
// Set a very generous timeout, just in case.
@@ -50,11 +52,14 @@
if (needsCORSPreflight(m_parameters.request))
doCORSPreflight(m_parameters.request);
else
- startNetworkLoad();
+ loadRequest(m_parameters.request);
}
PingLoad::~PingLoad()
{
+ if (m_redirectHandler)
+ m_redirectHandler({ });
+
if (m_task) {
ASSERT(m_task->client() == this);
m_task->clearClient();
@@ -62,22 +67,53 @@
}
}
-void PingLoad::startNetworkLoad()
+void PingLoad::loadRequest(const ResourceRequest& request)
{
RELEASE_LOG_IF_ALLOWED("startNetworkLoad");
if (auto* networkSession = SessionTracker::networkSession(m_parameters.sessionID)) {
- m_task = NetworkDataTask::create(*networkSession, *this, m_parameters);
+ auto loadParameters = m_parameters;
+ loadParameters.request = request;
+ m_task = NetworkDataTask::create(*networkSession, *this, WTFMove(loadParameters));
m_task->resume();
} else
ASSERT_NOT_REACHED();
}
-void PingLoad::willPerformHTTPRedirection(ResourceResponse&&, ResourceRequest&& request, RedirectCompletionHandler&& completionHandler)
+SecurityOrigin& PingLoad::securityOrigin() const
{
- RELEASE_LOG_IF_ALLOWED("willPerformHTTPRedirection");
- // FIXME: Do a CORS preflight if necessary.
+ return m_origin ? *m_origin : *m_parameters.sourceOrigin;
+}
+
+void PingLoad::willPerformHTTPRedirection(ResourceResponse&& redirectResponse, ResourceRequest&& request, RedirectCompletionHandler&& completionHandler)
+{
+ RELEASE_LOG_IF_ALLOWED("willPerformHTTPRedirection - shouldFollowRedirects? %d", m_parameters.shouldFollowRedirects);
+ if (!m_parameters.shouldFollowRedirects) {
+ completionHandler({ });
+ return;
+ }
+ // FIXME: Do CSP check.
// FIXME: We should ensure the number of redirects does not exceed 20.
- completionHandler(m_parameters.shouldFollowRedirects ? request : ResourceRequest());
+ if (!needsCORSPreflight(request)) {
+ completionHandler(request);
+ return;
+ }
+ RELEASE_LOG_IF_ALLOWED("willPerformHTTPRedirection - Redirect requires a CORS preflight");
+
+ // Use a unique origin for subsequent loads if needed.
+ // https://fetch.spec.whatwg.org/#concept-http-redirect-fetch (Step 10).
+ ASSERT(m_parameters.mode == FetchOptions::Mode::Cors);
+ if (!securityOrigin().canRequest(redirectResponse.url()) && !protocolHostAndPortAreEqual(redirectResponse.url(), request.url())) {
+ if (!m_origin || !m_origin->isUnique())
+ m_origin = SecurityOrigin::createUnique();
+ }
+
+ m_isSameOriginRequest = false;
+ m_redirectHandler = WTFMove(completionHandler);
+
+ // Let's fetch the request with the original headers (equivalent to request cloning specified by fetch algorithm).
+ request.setHTTPHeaderFields(m_parameters.request.httpHeaderFields());
+
+ doCORSPreflight(request);
}
void PingLoad::didReceiveChallenge(const AuthenticationChallenge&, ChallengeCompletionHandler&& completionHandler)
@@ -87,9 +123,9 @@
delete this;
}
-void PingLoad::didReceiveResponseNetworkSession(ResourceResponse&&, ResponseCompletionHandler&& completionHandler)
+void PingLoad::didReceiveResponseNetworkSession(ResourceResponse&& response, ResponseCompletionHandler&& completionHandler)
{
- RELEASE_LOG_IF_ALLOWED("didReceiveResponseNetworkSession");
+ RELEASE_LOG_IF_ALLOWED("didReceiveResponseNetworkSession - httpStatusCode: %d", response.httpStatusCode());
completionHandler(PolicyAction::PolicyIgnore);
delete this;
}
@@ -133,11 +169,10 @@
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;
+ if (m_parameters.mode == FetchOptions::Mode::NoCors)
+ return false;
+
+ return !m_isSameOriginRequest || !securityOrigin().canRequest(request.url());
}
void PingLoad::doCORSPreflight(const ResourceRequest& request)
@@ -144,19 +179,23 @@
{
RELEASE_LOG_IF_ALLOWED("doCORSPreflight");
ASSERT(!m_corsPreflightChecker);
- ASSERT(m_parameters.sourceOrigin);
NetworkCORSPreflightChecker::Parameters parameters = {
request,
- *m_parameters.sourceOrigin,
+ securityOrigin(),
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);
+ RELEASE_LOG_IF_ALLOWED("doCORSPreflight complete, success: %d forRedirect? %d", result == NetworkCORSPreflightChecker::Result::Success, !!m_redirectHandler);
+ auto corsPreflightChecker = WTFMove(m_corsPreflightChecker);
if (result == NetworkCORSPreflightChecker::Result::Success) {
- m_corsPreflightChecker = nullptr;
- startNetworkLoad();
+ ResourceRequest actualRequest = corsPreflightChecker->originalRequest();
+ updateRequestForAccessControl(actualRequest, securityOrigin(), m_parameters.allowStoredCredentials);
+ if (auto redirectHandler = std::exchange(m_redirectHandler, nullptr))
+ redirectHandler(actualRequest);
+ else
+ loadRequest(actualRequest);
} else
delete this;
});
Modified: trunk/Source/WebKit/NetworkProcess/PingLoad.h (220496 => 220497)
--- trunk/Source/WebKit/NetworkProcess/PingLoad.h 2017-08-09 23:18:13 UTC (rev 220496)
+++ trunk/Source/WebKit/NetworkProcess/PingLoad.h 2017-08-09 23:23:58 UTC (rev 220497)
@@ -51,14 +51,19 @@
void cannotShowURL() final;
void timeoutTimerFired();
- void startNetworkLoad();
+ void loadRequest(const WebCore::ResourceRequest&);
bool needsCORSPreflight(const WebCore::ResourceRequest&) const;
void doCORSPreflight(const WebCore::ResourceRequest&);
+
+ WebCore::SecurityOrigin& securityOrigin() const;
NetworkResourceLoadParameters m_parameters;
RefPtr<NetworkDataTask> m_task;
WebCore::Timer m_timeoutTimer;
std::unique_ptr<NetworkCORSPreflightChecker> m_corsPreflightChecker;
+ RefPtr<WebCore::SecurityOrigin> m_origin;
+ bool m_isSameOriginRequest;
+ RedirectCompletionHandler m_redirectHandler;
};
}