WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-175386-20170809143313.patch (text/plain), 31.65 KB, created by
Chris Dumez
on 2017-08-09 14:33:13 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Chris Dumez
Created:
2017-08-09 14:33:13 PDT
Size:
31.65 KB
patch
obsolete
>Subversion Revision: 220455 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 9b54ce1716f206c400702c2eeb0c7d55ebcd48b4..a4a18959d95077d13bb071894dcbbc6e4c1cdec0 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,20 @@ >+2017-08-09 Chris Dumez <cdumez@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 Ms2ger <Ms2ger@igalia.com> > > Remove unnecessary copies of PlatformMediaSessionManager::m_sessions >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 6a7ac634d3057f39a15dc01d97e2e7471957dd25..3dd4ca30ce0bcaa51b89e67bf38df30889e406af 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,26 @@ >+2017-08-09 Chris Dumez <cdumez@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-08 Wenson Hsieh <wenson_hsieh@apple.com> > > Unreviewed, rolling out r220393. >diff --git a/Source/WebCore/loader/CrossOriginAccessControl.h b/Source/WebCore/loader/CrossOriginAccessControl.h >index 5e87b1fe910a53141e1d112704ef64df0086797a..94f223043b4131bb557086b07e6c61f6b73e9e31 100644 >--- a/Source/WebCore/loader/CrossOriginAccessControl.h >+++ b/Source/WebCore/loader/CrossOriginAccessControl.h >@@ -40,7 +40,7 @@ class URL; > 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&); >diff --git a/Source/WebCore/page/SecurityOrigin.h b/Source/WebCore/page/SecurityOrigin.h >index 0ead4bc8b88c7ad207e7df8c8e0c25c8f8dfe13c..63bef48d434305296c5e84d6cd94554ada88ccc0 100644 >--- a/Source/WebCore/page/SecurityOrigin.h >+++ b/Source/WebCore/page/SecurityOrigin.h >@@ -50,7 +50,7 @@ public: > }; > > 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); >diff --git a/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h b/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h >index 446b67dcac1ef44b596cb8605562cc10648d262b..6522d9826840cbe8413dc37c3dbfb3d831af256a 100644 >--- a/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h >+++ b/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h >@@ -54,6 +54,7 @@ public: > > NetworkCORSPreflightChecker(Parameters&&, CompletionCallback&&); > ~NetworkCORSPreflightChecker(); >+ const WebCore::ResourceRequest& originalRequest() const { return m_parameters.originalRequest; } > > void startPreflight(); > >diff --git a/Source/WebKit/NetworkProcess/PingLoad.cpp b/Source/WebKit/NetworkProcess/PingLoad.cpp >index 2df014ce54cf23da996ebd91a1162e1e4373aca7..ee8118ecf7b3eef4a1f205a32b82bfa2307521f2 100644 >--- a/Source/WebKit/NetworkProcess/PingLoad.cpp >+++ b/Source/WebKit/NetworkProcess/PingLoad.cpp >@@ -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 @@ using namespace WebCore; > 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 @@ PingLoad::PingLoad(NetworkResourceLoadParameters&& parameters) > 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 @@ PingLoad::~PingLoad() > } > } > >-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 >+{ >+ return m_origin ? *m_origin : *m_parameters.sourceOrigin; >+} >+ >+void PingLoad::willPerformHTTPRedirection(ResourceResponse&& redirectResponse, ResourceRequest&& request, RedirectCompletionHandler&& completionHandler) > { >- RELEASE_LOG_IF_ALLOWED("willPerformHTTPRedirection"); >- // FIXME: Do a CORS preflight if necessary. >+ 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 @@ void PingLoad::didReceiveChallenge(const AuthenticationChallenge&, ChallengeComp > 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,30 +169,33 @@ void PingLoad::timeoutTimerFired() > > 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) > { > 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; > }); >diff --git a/Source/WebKit/NetworkProcess/PingLoad.h b/Source/WebKit/NetworkProcess/PingLoad.h >index 8872d2f4bc256ad0ccc852d0cb92f1b841b78bc4..0144496892e7cdc0a32c14c3e1e0a0404a42c192 100644 >--- a/Source/WebKit/NetworkProcess/PingLoad.h >+++ b/Source/WebKit/NetworkProcess/PingLoad.h >@@ -51,14 +51,19 @@ private: > 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; > }; > > } >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 06b2b2b4a40fe378cc8f1b87c13df8dd5491ffce..69b746263fbce636eab036e2d33bd66ed42e612b 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,24 @@ >+2017-08-09 Chris Dumez <cdumez@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 Zan Dobersek <zdobersek@igalia.com> > > Unreviewed WPE gardening. >diff --git a/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-failure.html b/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-failure.html >index 73c3b2ddf1426eb4aeef61f7730e10e6437450e8..c83acf5eaebe3c4fa0f8b595f394ba4fb0f4c2c6 100644 >--- a/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-failure.html >+++ b/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-failure.html >@@ -18,7 +18,7 @@ function pollResult(test, id) { > 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 @@ function testCORSPreflightFailure(what) { > > 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") >diff --git a/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-success.html b/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-success.html >index c71131394a91ee14cab9114bd411aa42e02e097e..083f91b5ffa402837526098bcbd6ca63cadd8a92 100644 >--- a/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-success.html >+++ b/LayoutTests/http/wpt/beacon/cors/cors-preflight-arraybufferview-success.html >@@ -18,7 +18,7 @@ function pollResult(test, id) { > 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 @@ function testCORSPreflightSuccess(what) { > > 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") >diff --git a/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-failure.html b/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-failure.html >index 061fcd2cdd2d9e8f53bffbd573f199eeb549b5ef..6eda9a3dbca07f47cd9f436eddc352abc902b386 100644 >--- a/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-failure.html >+++ b/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-failure.html >@@ -18,7 +18,7 @@ function pollResult(test, id) { > 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 @@ function testCORSPreflightFailure(what) { > > 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") >diff --git a/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-success.html b/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-success.html >index a0d909279cfb03e44ac8a37deed64d6a3b788e29..f64b3b7c57ae082de625608ce307e762feceb3b7 100644 >--- a/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-success.html >+++ b/LayoutTests/http/wpt/beacon/cors/cors-preflight-blob-success.html >@@ -18,7 +18,7 @@ function pollResult(test, id) { > 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 @@ function testCORSPreflightSuccess(what) { > > 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") >diff --git a/LayoutTests/http/wpt/beacon/cors/cors-preflight-cookie.html b/LayoutTests/http/wpt/beacon/cors/cors-preflight-cookie.html >index b7957eedd2af296c33d6ffb9449e2b25e42a6055..3d49c8aae02e18fc1cf5a75bb4a351329be91ade 100644 >--- a/LayoutTests/http/wpt/beacon/cors/cors-preflight-cookie.html >+++ b/LayoutTests/http/wpt/beacon/cors/cors-preflight-cookie.html >@@ -21,7 +21,7 @@ function pollResult(test, id) { > 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 @@ function testCORSPreflightSuccessWithCookie(what) { > 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") >diff --git a/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-failure-expected.txt b/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-failure-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..11932f72f6b0699a54c9e7ed92f2b7a6c948cdd8 >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-failure-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS CORS preflight failure test >+ >diff --git a/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-failure.html b/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-failure.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a963da0af4e5c622a70f2628cd801c2e941dbe70 >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-failure.html >@@ -0,0 +1,52 @@ >+<!doctype html> >+<html> >+ <head> >+ <meta charset="utf-8"> >+ <title>SendBeacon CORS preflight on redirect test</title> >+ <script src=/resources/testharness.js></script> >+ <script src=/resources/testharnessreport.js></script> >+ </head> >+ <body> >+ <script src="/common/utils.js"></script> >+ <script src="/common/get-host-info.sub.js"></script> >+ <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> >diff --git a/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-from-crossorigin-to-sameorigin-expected.txt b/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-from-crossorigin-to-sameorigin-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..154498269f5d4e0c9454f20e81158ed995fed593 >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-from-crossorigin-to-sameorigin-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS CORS preflight success test >+ >diff --git a/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-from-crossorigin-to-sameorigin.html b/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-from-crossorigin-to-sameorigin.html >new file mode 100644 >index 0000000000000000000000000000000000000000..9c1093f58c3e5f1347b6022a995ad21cb5a26fd3 >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-from-crossorigin-to-sameorigin.html >@@ -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=/resources/testharness.js></script> >+ <script src=/resources/testharnessreport.js></script> >+ </head> >+ <body> >+ <script src="/common/utils.js"></script> >+ <script src="/common/get-host-info.sub.js"></script> >+ <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> >diff --git a/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-success-expected.txt b/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-success-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..154498269f5d4e0c9454f20e81158ed995fed593 >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-success-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS CORS preflight success test >+ >diff --git a/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-success.html b/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-success.html >new file mode 100644 >index 0000000000000000000000000000000000000000..4d7fecdaca3c171503e9f478dc46a670f508f673 >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/cors/cors-preflight-redirect-success.html >@@ -0,0 +1,52 @@ >+<!doctype html> >+<html> >+ <head> >+ <meta charset="utf-8"> >+ <title>SendBeacon CORS preflight on redirect test</title> >+ <script src=/resources/testharness.js></script> >+ <script src=/resources/testharnessreport.js></script> >+ </head> >+ <body> >+ <script src="/common/utils.js"></script> >+ <script src="/common/get-host-info.sub.js"></script> >+ <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> >diff --git a/LayoutTests/http/wpt/beacon/resources/beacon-preflight.py b/LayoutTests/http/wpt/beacon/resources/beacon-preflight.py >index cce4cd1143be098dfaf4b8e2e431587bf782714a..9e64e76ffd6e3b9ca9a1a5c032d62e565d5d5848 100644 >--- a/LayoutTests/http/wpt/beacon/resources/beacon-preflight.py >+++ b/LayoutTests/http/wpt/beacon/resources/beacon-preflight.py >@@ -35,11 +35,13 @@ def main(request, response): > 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")], "" > >diff --git a/LayoutTests/http/wpt/beacon/resources/redirect.py b/LayoutTests/http/wpt/beacon/resources/redirect.py >new file mode 100644 >index 0000000000000000000000000000000000000000..39c574c402f02a9b5c98d9edfc464426e57aac59 >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/resources/redirect.py >@@ -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 = request.server.stash.take(token) >+ 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 = request.GET['location'] >+ 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, ""
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 175386
:
317714
|
317721
|
317733
|
317734
| 317743