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-175264-20170808120943.patch (text/plain), 74.16 KB, created by
Chris Dumez
on 2017-08-08 12:09:44 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Chris Dumez
Created:
2017-08-08 12:09:44 PDT
Size:
74.16 KB
patch
obsolete
>Subversion Revision: 220369 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index fe54866a712295754ae50270f4c2189a7ada28da..66dd95b32365e9d90992bcb181f060bac0474668 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,32 @@ >+2017-08-08 Chris Dumez <cdumez@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 NOBODY (OOPS!). >+ >+ 175264_cors_preflight2 >+ >+ Tests: http/wpt/beacon/headers/cors-preflight-arraybufferview-failure.html >+ http/wpt/beacon/headers/cors-preflight-arraybufferview-success.html >+ http/wpt/beacon/headers/cors-preflight-blob-failure.html >+ http/wpt/beacon/headers/cors-preflight-blob-success.html >+ >+ * WebCore.xcodeproj/project.pbxproj: >+ * loader/CrossOriginAccessControl.h: >+ * 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-07 Chris Dumez <cdumez@apple.com> > > Update sendBeacon() to rely on FetchBody instead of the whole FetchRequest >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 983b94d035c50ad0105a35fde66124a29f85372f..c76bfb2d407cd655d6273ac2c4f8721c5ae40055 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,60 @@ >+2017-08-08 Chris Dumez <cdumez@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 NOBODY (OOPS!). >+ >+ 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. >+ >+ * 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/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-07 Filip Pizlo <fpizlo@apple.com> > > Baseline JIT should do caging >diff --git a/Source/WebKitLegacy/ChangeLog b/Source/WebKitLegacy/ChangeLog >index c28212b70dc25c2f7662c958688c3176114d8bf0..de4a524cfbde9f25455ff8d91845fd96aa03f46d 100644 >--- a/Source/WebKitLegacy/ChangeLog >+++ b/Source/WebKitLegacy/ChangeLog >@@ -1,3 +1,18 @@ >+2017-08-08 Chris Dumez <cdumez@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 NOBODY (OOPS!). >+ >+ 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 <pvollan@apple.com> > > [Win] WebKit COM header file is not placed in the correct location. >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index fd55fd5de377086b37e792fdbf7208aa4aa31137..7f91651a6caa20a4228953bf211b29e04c1d16cc 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -6646,7 +6646,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 */; }; >diff --git a/Source/WebCore/loader/CrossOriginAccessControl.h b/Source/WebCore/loader/CrossOriginAccessControl.h >index 0d684b3fbc13a65dd3a5edc6019c1a1e66028926..724237cfff72cbf2beaf53aa2686caa2ed8ea9af 100644 >--- a/Source/WebCore/loader/CrossOriginAccessControl.h >+++ b/Source/WebCore/loader/CrossOriginAccessControl.h >@@ -41,11 +41,11 @@ bool isSimpleCrossOriginAccessRequest(const String& method, const HTTPHeaderMap& > 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); > > } // namespace WebCore >diff --git a/Source/WebCore/loader/CrossOriginPreflightResultCache.h b/Source/WebCore/loader/CrossOriginPreflightResultCache.h >index 094496e588612fbb14b5cd4ae6004bf9697abcf4..c8d01000704d0233212b62a888e51acea89a1405 100644 >--- a/Source/WebCore/loader/CrossOriginPreflightResultCache.h >+++ b/Source/WebCore/loader/CrossOriginPreflightResultCache.h >@@ -46,9 +46,9 @@ public: > { > } > >- 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 @@ class CrossOriginPreflightResultCache { > 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(); > >diff --git a/Source/WebCore/loader/LoaderStrategy.h b/Source/WebCore/loader/LoaderStrategy.h >index 2871a21aa6b24c49fdb929fc93a9e9e6efa86ba2..863aa9c4dfb092a135e31b400985aeb9183be1c2 100644 >--- a/Source/WebCore/loader/LoaderStrategy.h >+++ b/Source/WebCore/loader/LoaderStrategy.h >@@ -42,10 +42,13 @@ class ResourceError; > 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 @@ public: > 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; > >diff --git a/Source/WebCore/loader/PingLoader.cpp b/Source/WebCore/loader/PingLoader.cpp >index 865eb1cdb8052d1638634575315b8cc3bba92772..89bbade6e5cad33d63d4c4e310c058ad6e3b23a7 100644 >--- a/Source/WebCore/loader/PingLoader.cpp >+++ b/Source/WebCore/loader/PingLoader.cpp >@@ -103,7 +103,7 @@ void PingLoader::loadImage(Frame& frame, const URL& url) > 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 @@ void PingLoader::sendPing(Frame& frame, const URL& pingURL, const URL& destinati > } > } > >- 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 @@ void PingLoader::sendViolationReport(Frame& frame, const URL& reportURL, Ref<For > 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 @@ void PingLoader::startPingLoad(Frame& frame, ResourceRequest& request, ShouldFol > // 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); > } > > } >diff --git a/Source/WebCore/loader/PingLoader.h b/Source/WebCore/loader/PingLoader.h >index b7937de209bb24d82e227cb33eb48f711c29b2af..97354fb378e8e754b5f342ed0f021a78707a2ffa 100644 >--- a/Source/WebCore/loader/PingLoader.h >+++ b/Source/WebCore/loader/PingLoader.h >@@ -41,6 +41,7 @@ class FormData; > class Frame; > class URL; > class ResourceRequest; >+class SecurityOrigin; > > enum class ViolationReportType { > ContentSecurityPolicy, >@@ -55,7 +56,7 @@ public: > > private: > enum class ShouldFollowRedirects { No, Yes }; >- static void startPingLoad(Frame&, ResourceRequest&, ShouldFollowRedirects); >+ static void startPingLoad(Frame&, ResourceRequest&, SecurityOrigin& sourceOrigin, ShouldFollowRedirects); > }; > > } // namespace WebCore >diff --git a/Source/WebCore/loader/cache/CachedResource.cpp b/Source/WebCore/loader/cache/CachedResource.cpp >index 5fff7a9649bd26dbe1506c29bad88b0f6d5d34cf..b5b0c8bbd263dc57e18b0e63da3b85c39d7ecf3f 100644 >--- a/Source/WebCore/loader/cache/CachedResource.cpp >+++ b/Source/WebCore/loader/cache/CachedResource.cpp >@@ -261,7 +261,8 @@ void CachedResource::load(CachedResourceLoader& cachedResourceLoader) > > // 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; > } > >diff --git a/Source/WebCore/page/SecurityOrigin.h b/Source/WebCore/page/SecurityOrigin.h >index d56a6fff5d5abc9803d69f611d42a3dadd6be3ea..0ead4bc8b88c7ad207e7df8c8e0c25c8f8dfe13c 100644 >--- a/Source/WebCore/page/SecurityOrigin.h >+++ b/Source/WebCore/page/SecurityOrigin.h >@@ -97,7 +97,7 @@ public: > // 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 >diff --git a/Source/WebKit/CMakeLists.txt b/Source/WebKit/CMakeLists.txt >index 64b5abffb151157a9c3a329b0f9c7c41e0bfc067..c17f5bf160a800e84f79d6c4d2629771f31a8cc7 100644 >--- a/Source/WebKit/CMakeLists.txt >+++ b/Source/WebKit/CMakeLists.txt >@@ -100,6 +100,7 @@ set(WebKit2_SOURCES > > NetworkProcess/FileAPI/NetworkBlobRegistry.cpp > >+ NetworkProcess/NetworkCORSPreflightChecker.cpp > NetworkProcess/NetworkConnectionToWebProcess.cpp > NetworkProcess/NetworkDataTask.cpp > NetworkProcess/NetworkDataTaskBlob.cpp >@@ -111,6 +112,7 @@ set(WebKit2_SOURCES > NetworkProcess/NetworkResourceLoader.cpp > NetworkProcess/NetworkSession.cpp > NetworkProcess/NetworkSocketStream.cpp >+ NetworkProcess/PingLoad.cpp > > NetworkProcess/cache/NetworkCache.cpp > NetworkProcess/cache/NetworkCacheBlobStorage.cpp >diff --git a/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.cpp b/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..1713728dc819aa819d56e13b2cbd42f4c1e29b88 >--- /dev/null >+++ b/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.cpp >@@ -0,0 +1,154 @@ >+/* >+ * 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, loadParameters); >+ m_task->resume(); >+ } else >+ ASSERT_NOT_REACHED(); >+} >+ >+void NetworkCORSPreflightChecker::willPerformHTTPRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, RedirectCompletionHandler&& completionHandler) >+{ >+ RELEASE_LOG_IF_ALLOWED("willPerformHTTPRedirection"); >+ completionHandler(ResourceRequest { }); >+ 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 description; >+ if (!passesAccessControlCheck(m_response, m_parameters.allowStoredCredentials, m_parameters.sourceOrigin, description)) { >+ RELEASE_LOG_IF_ALLOWED("didComplete, AccessControl error: %s", description.utf8().data()); >+ m_completionCallback(Result::Failure); >+ return; >+ } >+ >+ auto result = std::make_unique<CrossOriginPreflightResultCacheItem>(m_parameters.allowStoredCredentials); >+ if (!result->parse(m_response, description) >+ || !result->allowsCrossOriginMethod(m_parameters.originalRequest.httpMethod(), description) >+ || !result->allowsCrossOriginHeaders(m_parameters.originalRequest.httpHeaderFields(), description)) { >+ RELEASE_LOG_IF_ALLOWED("didComplete, AccessControl error: %s", description.utf8().data()); >+ m_completionCallback(Result::Failure); >+ return; >+ } >+ >+ CrossOriginPreflightResultCache::singleton().appendEntry(m_parameters.sourceOrigin->toString(), m_parameters.originalRequest.url(), WTFMove(result)); >+ 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) >diff --git a/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h b/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h >new file mode 100644 >index 0000000000000000000000000000000000000000..446b67dcac1ef44b596cb8605562cc10648d262b >--- /dev/null >+++ b/Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h >@@ -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) >diff --git a/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp b/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp >index 4e197c8eb25ab5d3f20ca8eba7f796d80e943e99..26b9dc1e38b407b9a65e58f5a4712677a414725a 100644 >--- a/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp >+++ b/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp >@@ -29,6 +29,7 @@ > #include "ArgumentCoders.h" > #include "DataReference.h" > #include "WebCoreArgumentCoders.h" >+#include <WebCore/SecurityOriginData.h> > > using namespace WebCore; > >@@ -81,6 +82,11 @@ void NetworkResourceLoadParameters::encode(IPC::Encoder& encoder) const > 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 @@ bool NetworkResourceLoadParameters::decode(IPC::Decoder& decoder, NetworkResourc > 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; > } > >diff --git a/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h b/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h >index c1da45749a465ae4fdb3da38524bbb2506a3feb7..36ca0e89c5997b8b5d2bd13555c64259f23aadd8 100644 >--- a/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h >+++ b/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h >@@ -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 @@ public: > RefPtr<SandboxExtension> resourceSandboxExtension; // Created automatically for the sender. > Seconds maximumBufferingTime; > Vector<String> derivedCachedDataTypesToRetrieve; >+ RefPtr<WebCore::SecurityOrigin> sourceOrigin; >+ WebCore::FetchOptions::Mode mode; > }; > > } // namespace WebKit >diff --git a/Source/WebKit/NetworkProcess/PingLoad.cpp b/Source/WebKit/NetworkProcess/PingLoad.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..2b8ecdc1d7cde6e27ce8901c0d81a34a0541f69c >--- /dev/null >+++ b/Source/WebKit/NetworkProcess/PingLoad.cpp >@@ -0,0 +1,167 @@ >+/* >+ * 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(const NetworkResourceLoadParameters& parameters) >+ : m_parameters(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. >+ 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) >diff --git a/Source/WebKit/NetworkProcess/PingLoad.h b/Source/WebKit/NetworkProcess/PingLoad.h >index 39be06d3e1bc44fe21a69640cda49e4d8265adf4..15c16f683571562a4b35568dbb2338755789dac1 100644 >--- a/Source/WebKit/NetworkProcess/PingLoad.h >+++ b/Source/WebKit/NetworkProcess/PingLoad.h >@@ -23,69 +23,44 @@ > * THE POSSIBILITY OF SUCH DAMAGE. > */ > >-#ifndef PingLoad_h >-#define PingLoad_h >+#pragma once >+ >+#if USE(NETWORK_SESSION) > >-#include "AuthenticationManager.h" > #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(const 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; } >- >- virtual ~PingLoad() >- { >- if (m_task) { >- ASSERT(m_task->client() == this); >- m_task->clearClient(); >- m_task->cancel(); >- } >- } >+ 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&); > >+ 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) >diff --git a/Source/WebKit/WebKit.xcodeproj/project.pbxproj b/Source/WebKit/WebKit.xcodeproj/project.pbxproj >index 217710d24cfb9fbdc54c83394eb4e37c9c5631c5..9d07d07b6b19acdf6d93072b869a01d7c861c14d 100644 >--- a/Source/WebKit/WebKit.xcodeproj/project.pbxproj >+++ b/Source/WebKit/WebKit.xcodeproj/project.pbxproj >@@ -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 */, >diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp >index 20253cc3e5a4f9e4ba4927b0887fb92692f8dc30..c16d08bb7fc4e25f8cbbde0454a1e239c0da5924 100644 >--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp >+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp >@@ -50,12 +50,14 @@ > #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> > #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::loadResourceSynchronously(NetworkingContext* context, un > } > } > >-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 @@ void WebLoaderStrategy::createPingHandle(NetworkingContext* networkingContext, R > > 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); >diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h >index 947843b40f5d7d57012c575dbf3d1502b191ede3..bfc10746fc4b8dfd5330780352244b2ab6d82460 100644 >--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h >+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h >@@ -31,6 +31,10 @@ > #include <wtf/HashSet.h> > #include <wtf/RunLoop.h> > >+namespace WebCore { >+struct FetchOptions; >+} >+ > namespace WebKit { > > class NetworkProcessConnection; >@@ -55,7 +59,7 @@ public: > 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; > >diff --git a/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.cpp b/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.cpp >index 2c7be1a4d7608a0cf145e7531dd32ac84af95831..479776ec9d2fe1761ef4815598d0092cde398a92 100644 >--- a/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.cpp >+++ b/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.cpp >@@ -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 @@ bool WebResourceLoadScheduler::HostInformation::limitRequests(ResourceLoadPriori > 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); > } > >diff --git a/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.h b/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.h >index 076a334d9cce1a00ccd22505201dbcf91f0c0b49..60970bb4fbb79d23590281ac36c480e22f085433 100644 >--- a/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.h >+++ b/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.h >@@ -37,6 +37,11 @@ > > class WebResourceLoadScheduler; > >+namespace WebCore { >+struct FetchOptions; >+class SecurityOrigin; >+} >+ > WebResourceLoadScheduler& webResourceLoadScheduler(); > > class WebResourceLoadScheduler : public WebCore::LoaderStrategy { >@@ -54,7 +59,7 @@ public: > 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 { } > >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 50a8e86492c3a2034d13b9ac3478bda09add1f8c..95f5154504a0f8ccfe6c4527ad5f0f2c83d8e566 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,28 @@ >+2017-08-08 Chris Dumez <cdumez@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 NOBODY (OOPS!). >+ >+ Add layout test coverage. >+ >+ * http/wpt/beacon/headers/cors-preflight-arraybufferview-failure-expected.txt: Added. >+ * http/wpt/beacon/headers/cors-preflight-arraybufferview-failure.html: Added. >+ * http/wpt/beacon/headers/cors-preflight-arraybufferview-success-expected.txt: Added. >+ * http/wpt/beacon/headers/cors-preflight-arraybufferview-success.html: Added. >+ * http/wpt/beacon/headers/cors-preflight-blob-failure-expected.txt: Added. >+ * http/wpt/beacon/headers/cors-preflight-blob-failure.html: Added. >+ * http/wpt/beacon/headers/cors-preflight-blob-success-expected.txt: Added. >+ * http/wpt/beacon/headers/cors-preflight-blob-success.html: Added. >+ * http/wpt/beacon/resources/beacon-preflight.py: Added. >+ (respondToCORSPreflight): >+ (main): >+ * platform/mac-wk1/TestExpectations: >+ * platform/mac-wk2/TestExpectations: >+ * platform/win/TestExpectations: >+ > 2017-08-07 Ryan Haddad <ryanhaddad@apple.com> > > Skip workers/wasm-hashset-many.html and workers/wasm-hashset-many-2.html on El Capitan. >diff --git a/LayoutTests/http/wpt/beacon/headers/cors-preflight-arraybufferview-failure-expected.txt b/LayoutTests/http/wpt/beacon/headers/cors-preflight-arraybufferview-failure-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..11932f72f6b0699a54c9e7ed92f2b7a6c948cdd8 >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/headers/cors-preflight-arraybufferview-failure-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS CORS preflight failure test >+ >diff --git a/LayoutTests/http/wpt/beacon/headers/cors-preflight-arraybufferview-failure.html b/LayoutTests/http/wpt/beacon/headers/cors-preflight-arraybufferview-failure.html >new file mode 100644 >index 0000000000000000000000000000000000000000..73c3b2ddf1426eb4aeef61f7730e10e6437450e8 >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/headers/cors-preflight-arraybufferview-failure.html >@@ -0,0 +1,64 @@ >+<!doctype html> >+<html> >+ <head> >+ <meta charset="utf-8"> >+ <title>SendBeacon CORS preflight 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.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> >diff --git a/LayoutTests/http/wpt/beacon/headers/cors-preflight-arraybufferview-success-expected.txt b/LayoutTests/http/wpt/beacon/headers/cors-preflight-arraybufferview-success-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..154498269f5d4e0c9454f20e81158ed995fed593 >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/headers/cors-preflight-arraybufferview-success-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS CORS preflight success test >+ >diff --git a/LayoutTests/http/wpt/beacon/headers/cors-preflight-arraybufferview-success.html b/LayoutTests/http/wpt/beacon/headers/cors-preflight-arraybufferview-success.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c71131394a91ee14cab9114bd411aa42e02e097e >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/headers/cors-preflight-arraybufferview-success.html >@@ -0,0 +1,64 @@ >+<!doctype html> >+<html> >+ <head> >+ <meta charset="utf-8"> >+ <title>SendBeacon CORS preflight 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.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> >diff --git a/LayoutTests/http/wpt/beacon/headers/cors-preflight-blob-failure-expected.txt b/LayoutTests/http/wpt/beacon/headers/cors-preflight-blob-failure-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..11932f72f6b0699a54c9e7ed92f2b7a6c948cdd8 >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/headers/cors-preflight-blob-failure-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS CORS preflight failure test >+ >diff --git a/LayoutTests/http/wpt/beacon/headers/cors-preflight-blob-failure.html b/LayoutTests/http/wpt/beacon/headers/cors-preflight-blob-failure.html >new file mode 100644 >index 0000000000000000000000000000000000000000..061fcd2cdd2d9e8f53bffbd573f199eeb549b5ef >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/headers/cors-preflight-blob-failure.html >@@ -0,0 +1,54 @@ >+<!doctype html> >+<html> >+ <head> >+ <meta charset="utf-8"> >+ <title>SendBeacon CORS preflight 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.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> >diff --git a/LayoutTests/http/wpt/beacon/headers/cors-preflight-blob-success-expected.txt b/LayoutTests/http/wpt/beacon/headers/cors-preflight-blob-success-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..154498269f5d4e0c9454f20e81158ed995fed593 >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/headers/cors-preflight-blob-success-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS CORS preflight success test >+ >diff --git a/LayoutTests/http/wpt/beacon/headers/cors-preflight-blob-success.html b/LayoutTests/http/wpt/beacon/headers/cors-preflight-blob-success.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a0d909279cfb03e44ac8a37deed64d6a3b788e29 >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/headers/cors-preflight-blob-success.html >@@ -0,0 +1,54 @@ >+<!doctype html> >+<html> >+ <head> >+ <meta charset="utf-8"> >+ <title>SendBeacon CORS preflight 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.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> >diff --git a/LayoutTests/http/wpt/beacon/resources/beacon-preflight.py b/LayoutTests/http/wpt/beacon/resources/beacon-preflight.py >new file mode 100644 >index 0000000000000000000000000000000000000000..e055bed81abbd650a794101dc0b0778eee0f2064 >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/resources/beacon-preflight.py >@@ -0,0 +1,50 @@ >+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': '' } >+ >+ 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_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; >+ 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!" >diff --git a/LayoutTests/platform/mac-wk1/TestExpectations b/LayoutTests/platform/mac-wk1/TestExpectations >index 6819eee26dadef3c037d0c584a86dd0b08da0283..628b6eef2b149f99d5a471c464bb96f9bfb3c686 100644 >--- a/LayoutTests/platform/mac-wk1/TestExpectations >+++ b/LayoutTests/platform/mac-wk1/TestExpectations >@@ -360,6 +360,12 @@ css3/viewport-percentage-lengths/vh-auto-size.html [ Skip ] > > 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/headers/cors-preflight-arraybufferview-failure.html [ Failure ] >+webkit.org/b/175330 http/wpt/beacon/headers/cors-preflight-arraybufferview-success.html [ Failure ] >+webkit.org/b/175330 http/wpt/beacon/headers/cors-preflight-blob-failure.html [ Failure ] >+webkit.org/b/175330 http/wpt/beacon/headers/cors-preflight-blob-success.html [ Failure ] >+ > # This was a WK2-only fix. > http/tests/css/filters-on-iframes.html [ Skip ] > >diff --git a/LayoutTests/platform/mac-wk2/TestExpectations b/LayoutTests/platform/mac-wk2/TestExpectations >index 59f86b4152bc8568f542ffc19dc3c15775839f1a..41f240a5b303921c9de1bb6ec31596b50de588a2 100644 >--- a/LayoutTests/platform/mac-wk2/TestExpectations >+++ b/LayoutTests/platform/mac-wk2/TestExpectations >@@ -722,6 +722,13 @@ webkit.org/b/172834 [ ElCapitan ] imported/w3c/web-platform-tests/IndexedDB/idbi > > 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/headers/cors-preflight-arraybufferview-failure.html [ Failure ] >+webkit.org/b/175330 [ ElCapitan ] http/wpt/beacon/headers/cors-preflight-arraybufferview-success.html [ Failure ] >+webkit.org/b/175330 [ ElCapitan ] http/wpt/beacon/headers/cors-preflight-blob-failure.html [ Failure ] >+webkit.org/b/175330 [ ElCapitan ] http/wpt/beacon/headers/cors-preflight-blob-success.html [ Failure ] >+ > webkit.org/b/172201 webaudio/silent-audio-interrupted-in-background.html [ Pass Timeout ] > > webkit.org/b/167757 workers/bomb.html [ Pass Timeout ] >diff --git a/LayoutTests/platform/win/TestExpectations b/LayoutTests/platform/win/TestExpectations >index 8e65fe911f15998efef5d1b2cbe15118268d8576..7ed39503790884a8aa214392fbb7f3f3d1b87980 100644 >--- a/LayoutTests/platform/win/TestExpectations >+++ b/LayoutTests/platform/win/TestExpectations >@@ -4046,6 +4046,12 @@ svg/animations/animated-svg-image-outside-viewport-paused.html [ Skip ] > # 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/headers/cors-preflight-arraybufferview-failure.html [ Failure ] >+webkit.org/b/175330 http/wpt/beacon/headers/cors-preflight-arraybufferview-success.html [ Failure ] >+webkit.org/b/175330 http/wpt/beacon/headers/cors-preflight-blob-failure.html [ Failure ] >+webkit.org/b/175330 http/wpt/beacon/headers/cors-preflight-blob-success.html [ Failure ] >+ > # 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 ]
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 175264
:
317456
|
317457
|
317477
|
317478
|
317484
|
317499
|
317501
|
317539
|
317544
|
317580
|
317595
|
317607
|
317645
|
317655
|
317659
|
317660
|
317668
|
317670