WebKit Bugzilla
Attachment 343378 Details for
Bug 186902
: WKURLSchemeHandler doesn't handle sync XHR
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
patch (text/plain), 28.97 KB, created by
Brady Eidson
on 2018-06-22 15:42:21 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Brady Eidson
Created:
2018-06-22 15:42:21 PDT
Size:
28.97 KB
patch
obsolete
>diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 4e7ad30cd82..7d571871293 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,12 @@ >+2018-06-22 Brady Eidson <beidson@apple.com> >+ >+ WKURLSchemeHandler doesn't handle sync XHR. >+ <rdar://problem/40955884> and https://bugs.webkit.org/show_bug.cgi?id=186902 >+ >+ Reviewed by Chris Dumez. >+ >+ * English.lproj/Localizable.strings: >+ > 2018-06-19 David Kilzer <ddkilzer@apple.com> > > Revert: Add logging when splashboardd enables WebThread >diff --git a/Source/WebCore/English.lproj/Localizable.strings b/Source/WebCore/English.lproj/Localizable.strings >index 68d17b6769a..3b5dc9b61f6 100644 >--- a/Source/WebCore/English.lproj/Localizable.strings >+++ b/Source/WebCore/English.lproj/Localizable.strings >@@ -265,6 +265,9 @@ > /* Validation message for input form controls of type 'email' that have an invalid value */ > "Enter an email address" = "Enter an email address"; > >+/* Custom protocol synchronous load failure description */ >+"Error handling synchronous load with custom protocol" = "Error handling synchronous load with custom protocol"; >+ > /* Button for exiting full screen when in full screen media playback */ > "Exit Full Screen" = "Exit Full Screen"; > >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 13f3ad7ac87..8c1419c3f69 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,49 @@ >+2018-06-22 Brady Eidson <beidson@apple.com> >+ >+ WKURLSchemeHandler doesn't handle sync XHR. >+ <rdar://problem/40955884> and https://bugs.webkit.org/show_bug.cgi?id=186902 >+ >+ Reviewed by Chris Dumez. >+ >+ This patch allows WebProcesses to block on sync loads to a custom scheme, >+ and teaches WebURLSchemeTasks how to buffer up data and the response if >+ operating synchronously. >+ >+ * Shared/WebErrors.cpp: >+ (WebKit::failedCustomProtocolSyncLoad): >+ * Shared/WebErrors.h: >+ >+ * UIProcess/WebPageProxy.cpp: >+ (WebKit::WebPageProxy::startURLSchemeTask): >+ (WebKit::WebPageProxy::loadSynchronousURLSchemeTask): >+ * UIProcess/WebPageProxy.h: >+ * UIProcess/WebPageProxy.messages.in: >+ >+ * UIProcess/WebURLSchemeHandler.cpp: >+ (WebKit::WebURLSchemeHandler::startTask): >+ * UIProcess/WebURLSchemeHandler.h: >+ >+ * UIProcess/WebURLSchemeTask.cpp: >+ (WebKit::WebURLSchemeTask::create): >+ (WebKit::WebURLSchemeTask::WebURLSchemeTask): >+ (WebKit::WebURLSchemeTask::didPerformRedirection): >+ (WebKit::WebURLSchemeTask::didReceiveResponse): >+ (WebKit::WebURLSchemeTask::didReceiveData): >+ (WebKit::WebURLSchemeTask::didComplete): >+ (WebKit::WebURLSchemeTask::pageDestroyed): >+ (WebKit::WebURLSchemeTask::stop): >+ * UIProcess/WebURLSchemeTask.h: >+ (WebKit::WebURLSchemeTask::isSync const): >+ >+ * WebProcess/Network/WebLoaderStrategy.cpp: >+ (WebKit::WebLoaderStrategy::tryLoadingSynchronouslyUsingURLSchemeHandler): >+ (WebKit::WebLoaderStrategy::loadResourceSynchronously): >+ * WebProcess/Network/WebLoaderStrategy.h: >+ >+ * WebProcess/WebPage/WebURLSchemeHandlerProxy.cpp: >+ (WebKit::WebURLSchemeHandlerProxy::loadSynchronously): >+ * WebProcess/WebPage/WebURLSchemeHandlerProxy.h: >+ > 2018-06-19 Wenson Hsieh <wenson_hsieh@apple.com> > > [WebKit on watchOS] Vend username text content type when using scribble in login fields >diff --git a/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp b/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp >index 4d51ba75021..489354e7f0f 100644 >--- a/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp >+++ b/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp >@@ -991,7 +991,7 @@ static void logBlockedCookieInformation(const String& label, const void* loggedO > LOCAL_LOG(R"( "isSameSite": "%{public}s",)", sameSiteInfo.isSameSite ? "true" : "false"); > LOCAL_LOG(R"( "isTopSite": "%{public}s",)", sameSiteInfo.isTopSite ? "true" : "false"); > LOCAL_LOG(R"( "cookies": [])"); >- LOCAL_LOG(R"( "})"); >+ LOCAL_LOG(R"( })"); > #undef LOCAL_LOG > #undef LOCAL_LOG_IF_ALLOWED > } >diff --git a/Source/WebKit/Shared/WebErrors.cpp b/Source/WebKit/Shared/WebErrors.cpp >index 8f15cd30c5c..b6dc50ceb55 100644 >--- a/Source/WebKit/Shared/WebErrors.cpp >+++ b/Source/WebKit/Shared/WebErrors.cpp >@@ -57,6 +57,11 @@ ResourceError interruptedForPolicyChangeError(const ResourceRequest& request) > return ResourceError(API::Error::webKitPolicyErrorDomain(), API::Error::Policy::FrameLoadInterruptedByPolicyChange, request.url(), WEB_UI_STRING("Frame load interrupted", "WebKitErrorFrameLoadInterruptedByPolicyChange description")); > } > >+ResourceError failedCustomProtocolSyncLoad(const ResourceRequest& request) >+{ >+ return ResourceError(errorDomainWebKitInternal, 0, request.url(), WEB_UI_STRING("Error handling synchronous load with custom protocol", "Custom protocol synchronous load failure description")); >+} >+ > #if ENABLE(CONTENT_FILTERING) > ResourceError blockedByContentFilterError(const ResourceRequest& request) > { >diff --git a/Source/WebKit/Shared/WebErrors.h b/Source/WebKit/Shared/WebErrors.h >index 593ea88537d..27d14e31b31 100644 >--- a/Source/WebKit/Shared/WebErrors.h >+++ b/Source/WebKit/Shared/WebErrors.h >@@ -41,6 +41,7 @@ WebCore::ResourceError blockedError(const WebCore::ResourceRequest&); > WebCore::ResourceError blockedByContentBlockerError(const WebCore::ResourceRequest&); > WebCore::ResourceError cannotShowURLError(const WebCore::ResourceRequest&); > WebCore::ResourceError interruptedForPolicyChangeError(const WebCore::ResourceRequest&); >+WebCore::ResourceError failedCustomProtocolSyncLoad(const WebCore::ResourceRequest&); > #if ENABLE(CONTENT_FILTERING) > WebCore::ResourceError blockedByContentFilterError(const WebCore::ResourceRequest&); > #endif >diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp >index b9af1d6bff9..c444c045744 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.cpp >+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp >@@ -7586,7 +7586,7 @@ void WebPageProxy::startURLSchemeTask(URLSchemeTaskParameters&& parameters) > auto iterator = m_urlSchemeHandlersByIdentifier.find(parameters.handlerIdentifier); > MESSAGE_CHECK(iterator != m_urlSchemeHandlersByIdentifier.end()); > >- iterator->value->startTask(*this, parameters.taskIdentifier, WTFMove(parameters.request)); >+ iterator->value->startTask(*this, parameters.taskIdentifier, WTFMove(parameters.request), nullptr); > } > > void WebPageProxy::stopURLSchemeTask(uint64_t handlerIdentifier, uint64_t taskIdentifier) >@@ -7597,6 +7597,14 @@ void WebPageProxy::stopURLSchemeTask(uint64_t handlerIdentifier, uint64_t taskId > iterator->value->stopTask(*this, taskIdentifier); > } > >+void WebPageProxy::loadSynchronousURLSchemeTask(URLSchemeTaskParameters&& parameters, Messages::WebPageProxy::LoadSynchronousURLSchemeTask::DelayedReply&& reply) >+{ >+ auto iterator = m_urlSchemeHandlersByIdentifier.find(parameters.handlerIdentifier); >+ MESSAGE_CHECK(iterator != m_urlSchemeHandlersByIdentifier.end()); >+ >+ iterator->value->startTask(*this, parameters.taskIdentifier, WTFMove(parameters.request), WTFMove(reply)); >+} >+ > #if HAVE(CFNETWORK_STORAGE_PARTITIONING) > void WebPageProxy::hasStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t webProcessContextId) > { >diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h >index b1050c94097..2ee2adb3146 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.h >+++ b/Source/WebKit/UIProcess/WebPageProxy.h >@@ -1752,6 +1752,7 @@ private: > > void startURLSchemeTask(URLSchemeTaskParameters&&); > void stopURLSchemeTask(uint64_t handlerIdentifier, uint64_t taskIdentifier); >+ void loadSynchronousURLSchemeTask(URLSchemeTaskParameters&&, Messages::WebPageProxy::LoadSynchronousURLSchemeTask::DelayedReply&&); > > void handleAutoFillButtonClick(const UserData&); > >diff --git a/Source/WebKit/UIProcess/WebPageProxy.messages.in b/Source/WebKit/UIProcess/WebPageProxy.messages.in >index 7f3c6683c61..4e1de5ca22a 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.messages.in >+++ b/Source/WebKit/UIProcess/WebPageProxy.messages.in >@@ -513,6 +513,7 @@ messages -> WebPageProxy { > > StartURLSchemeTask(struct WebKit::URLSchemeTaskParameters parameters) > StopURLSchemeTask(uint64_t handlerIdentifier, uint64_t taskIdentifier) >+ LoadSynchronousURLSchemeTask(struct WebKit::URLSchemeTaskParameters parameters) -> (WebCore::ResourceResponse response, WebCore::ResourceError error, IPC::DataReference data) Delayed > > #if HAVE(CFNETWORK_STORAGE_PARTITIONING) > HasStorageAccess(String subFrameHost, String topFrameHost, uint64_t frameID, uint64_t contextID) >diff --git a/Source/WebKit/UIProcess/WebURLSchemeHandler.cpp b/Source/WebKit/UIProcess/WebURLSchemeHandler.cpp >index 1f682c1ebe8..dab593fb21f 100644 >--- a/Source/WebKit/UIProcess/WebURLSchemeHandler.cpp >+++ b/Source/WebKit/UIProcess/WebURLSchemeHandler.cpp >@@ -49,9 +49,9 @@ WebURLSchemeHandler::~WebURLSchemeHandler() > ASSERT(m_tasks.isEmpty()); > } > >-void WebURLSchemeHandler::startTask(WebPageProxy& page, uint64_t taskIdentifier, ResourceRequest&& request) >+void WebURLSchemeHandler::startTask(WebPageProxy& page, uint64_t taskIdentifier, ResourceRequest&& request, SyncLoadCompletionHandler&& completionHandler) > { >- auto result = m_tasks.add(taskIdentifier, WebURLSchemeTask::create(*this, page, taskIdentifier, WTFMove(request))); >+ auto result = m_tasks.add(taskIdentifier, WebURLSchemeTask::create(*this, page, taskIdentifier, WTFMove(request), WTFMove(completionHandler))); > ASSERT(result.isNewEntry); > > auto pageEntry = m_tasksByPageIdentifier.add(page.pageID(), HashSet<uint64_t>()); >diff --git a/Source/WebKit/UIProcess/WebURLSchemeHandler.h b/Source/WebKit/UIProcess/WebURLSchemeHandler.h >index 41f803e0012..b784a53a4b1 100644 >--- a/Source/WebKit/UIProcess/WebURLSchemeHandler.h >+++ b/Source/WebKit/UIProcess/WebURLSchemeHandler.h >@@ -31,6 +31,10 @@ > #include <wtf/RefCounted.h> > #include <wtf/RefPtr.h> > >+namespace IPC { >+class DataReference; >+} >+ > namespace WebCore { > class ResourceRequest; > } >@@ -39,6 +43,8 @@ namespace WebKit { > > class WebPageProxy; > >+using SyncLoadCompletionHandler = CompletionHandler<void(const WebCore::ResourceResponse&, const WebCore::ResourceError&, const IPC::DataReference&)>; >+ > class WebURLSchemeHandler : public RefCounted<WebURLSchemeHandler> { > WTF_MAKE_NONCOPYABLE(WebURLSchemeHandler); > public: >@@ -46,7 +52,7 @@ public: > > uint64_t identifier() const { return m_identifier; } > >- void startTask(WebPageProxy&, uint64_t taskIdentifier, WebCore::ResourceRequest&&); >+ void startTask(WebPageProxy&, uint64_t taskIdentifier, WebCore::ResourceRequest&&, SyncLoadCompletionHandler&&); > void stopTask(WebPageProxy&, uint64_t taskIdentifier); > void stopAllTasksForPage(WebPageProxy&); > void taskCompleted(WebURLSchemeTask&); >@@ -65,6 +71,8 @@ private: > > HashMap<uint64_t, Ref<WebURLSchemeTask>> m_tasks; > HashMap<uint64_t, HashSet<uint64_t>> m_tasksByPageIdentifier; >+ >+ SyncLoadCompletionHandler m_syncLoadCompletionHandler; > > }; // class WebURLSchemeHandler > >diff --git a/Source/WebKit/UIProcess/WebURLSchemeTask.cpp b/Source/WebKit/UIProcess/WebURLSchemeTask.cpp >index 5549488bd84..7b247cca11c 100644 >--- a/Source/WebKit/UIProcess/WebURLSchemeTask.cpp >+++ b/Source/WebKit/UIProcess/WebURLSchemeTask.cpp >@@ -27,6 +27,7 @@ > #include "WebURLSchemeTask.h" > > #include "DataReference.h" >+#include "WebErrors.h" > #include "WebPageMessages.h" > #include "WebPageProxy.h" > #include "WebURLSchemeHandler.h" >@@ -35,17 +36,18 @@ using namespace WebCore; > > namespace WebKit { > >-Ref<WebURLSchemeTask> WebURLSchemeTask::create(WebURLSchemeHandler& handler, WebPageProxy& page, uint64_t resourceIdentifier, ResourceRequest&& request) >+Ref<WebURLSchemeTask> WebURLSchemeTask::create(WebURLSchemeHandler& handler, WebPageProxy& page, uint64_t resourceIdentifier, ResourceRequest&& request, SyncLoadCompletionHandler&& syncCompletionHandler) > { >- return adoptRef(*new WebURLSchemeTask(handler, page, resourceIdentifier, WTFMove(request))); >+ return adoptRef(*new WebURLSchemeTask(handler, page, resourceIdentifier, WTFMove(request), WTFMove(syncCompletionHandler))); > } > >-WebURLSchemeTask::WebURLSchemeTask(WebURLSchemeHandler& handler, WebPageProxy& page, uint64_t resourceIdentifier, ResourceRequest&& request) >+WebURLSchemeTask::WebURLSchemeTask(WebURLSchemeHandler& handler, WebPageProxy& page, uint64_t resourceIdentifier, ResourceRequest&& request, SyncLoadCompletionHandler&& syncCompletionHandler) > : m_urlSchemeHandler(handler) > , m_page(&page) > , m_identifier(resourceIdentifier) > , m_pageIdentifier(page.pageID()) > , m_request(WTFMove(request)) >+ , m_syncCompletionHandler(WTFMove(syncCompletionHandler)) > { > } > >@@ -63,6 +65,9 @@ auto WebURLSchemeTask::didPerformRedirection(WebCore::ResourceResponse&& respons > if (m_responseSent) > return ExceptionType::RedirectAfterResponse; > >+ if (isSync()) >+ m_syncResponse = response; >+ > m_request = request; > m_page->send(Messages::WebPage::URLSchemeTaskDidPerformRedirection(m_urlSchemeHandler->identifier(), m_identifier, response, request)); > >@@ -83,6 +88,10 @@ auto WebURLSchemeTask::didReceiveResponse(const ResourceResponse& response) -> E > m_responseSent = true; > > response.includeCertificateInfo(); >+ >+ if (isSync()) >+ m_syncResponse = response; >+ > m_page->send(Messages::WebPage::URLSchemeTaskDidReceiveResponse(m_urlSchemeHandler->identifier(), m_identifier, response)); > return ExceptionType::None; > } >@@ -99,6 +108,13 @@ auto WebURLSchemeTask::didReceiveData(Ref<SharedBuffer> buffer) -> ExceptionType > return ExceptionType::NoResponseSent; > > m_dataSent = true; >+ >+ if (isSync()) { >+ if (!m_syncData) >+ m_syncData = SharedBuffer::create(); >+ m_syncData->append(buffer); >+ } >+ > m_page->send(Messages::WebPage::URLSchemeTaskDidReceiveData(m_urlSchemeHandler->identifier(), m_identifier, IPC::SharedBufferDataReference(buffer.ptr()))); > return ExceptionType::None; > } >@@ -115,6 +131,12 @@ auto WebURLSchemeTask::didComplete(const ResourceError& error) -> ExceptionType > return ExceptionType::NoResponseSent; > > m_completed = true; >+ >+ if (isSync()) { >+ m_syncCompletionHandler(m_syncResponse, error, IPC::DataReference { (const uint8_t*)m_syncData->data(), m_syncData->size() }); >+ m_syncData = nullptr; >+ } >+ > m_page->send(Messages::WebPage::URLSchemeTaskDidComplete(m_urlSchemeHandler->identifier(), m_identifier, error)); > m_urlSchemeHandler->taskCompleted(*this); > >@@ -126,12 +148,18 @@ void WebURLSchemeTask::pageDestroyed() > ASSERT(m_page); > m_page = nullptr; > m_stopped = true; >+ >+ if (isSync()) >+ m_syncCompletionHandler({ }, failedCustomProtocolSyncLoad(m_request), { }); > } > > void WebURLSchemeTask::stop() > { > ASSERT(!m_stopped); > m_stopped = true; >+ >+ if (isSync()) >+ m_syncCompletionHandler({ }, failedCustomProtocolSyncLoad(m_request), { }); > } > > } // namespace WebKit >diff --git a/Source/WebKit/UIProcess/WebURLSchemeTask.h b/Source/WebKit/UIProcess/WebURLSchemeTask.h >index 375474c1fad..ad81dd532ac 100644 >--- a/Source/WebKit/UIProcess/WebURLSchemeTask.h >+++ b/Source/WebKit/UIProcess/WebURLSchemeTask.h >@@ -26,10 +26,17 @@ > #pragma once > > #include <WebCore/ResourceRequest.h> >+#include <WebCore/ResourceResponse.h> >+#include <WebCore/SharedBuffer.h> >+#include <wtf/CompletionHandler.h> > #include <wtf/InstanceCounted.h> > #include <wtf/RefCounted.h> > #include <wtf/RefPtr.h> > >+namespace IPC { >+class DataReference; >+} >+ > namespace WebCore { > class ResourceError; > class ResourceResponse; >@@ -41,10 +48,12 @@ namespace WebKit { > class WebURLSchemeHandler; > class WebPageProxy; > >+using SyncLoadCompletionHandler = CompletionHandler<void(const WebCore::ResourceResponse&, const WebCore::ResourceError&, const IPC::DataReference&)>; >+ > class WebURLSchemeTask : public RefCounted<WebURLSchemeTask>, public InstanceCounted<WebURLSchemeTask> { > WTF_MAKE_NONCOPYABLE(WebURLSchemeTask); > public: >- static Ref<WebURLSchemeTask> create(WebURLSchemeHandler&, WebPageProxy&, uint64_t identifier, WebCore::ResourceRequest&&); >+ static Ref<WebURLSchemeTask> create(WebURLSchemeHandler&, WebPageProxy&, uint64_t identifier, WebCore::ResourceRequest&&, SyncLoadCompletionHandler&&); > > uint64_t identifier() const { return m_identifier; } > uint64_t pageID() const { return m_pageIdentifier; } >@@ -68,7 +77,9 @@ public: > void pageDestroyed(); > > private: >- WebURLSchemeTask(WebURLSchemeHandler&, WebPageProxy&, uint64_t identifier, WebCore::ResourceRequest&&); >+ WebURLSchemeTask(WebURLSchemeHandler&, WebPageProxy&, uint64_t identifier, WebCore::ResourceRequest&&, SyncLoadCompletionHandler&&); >+ >+ bool isSync() const { return !!m_syncCompletionHandler; } > > Ref<WebURLSchemeHandler> m_urlSchemeHandler; > WebPageProxy* m_page; >@@ -79,6 +90,10 @@ private: > bool m_responseSent { false }; > bool m_dataSent { false }; > bool m_completed { false }; >+ >+ SyncLoadCompletionHandler m_syncCompletionHandler; >+ WebCore::ResourceResponse m_syncResponse; >+ RefPtr<WebCore::SharedBuffer> m_syncData; > }; > > } // namespace WebKit >diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp >index 95998a5af23..15cb99b7a71 100644 >--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp >+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp >@@ -473,6 +473,26 @@ static bool shouldClearReferrerOnHTTPSToHTTPRedirect(Frame* frame) > return true; > } > >+std::optional<WebLoaderStrategy::SyncLoadResult> WebLoaderStrategy::tryLoadingSynchronouslyUsingURLSchemeHandler(FrameLoader& frameLoader, ResourceLoadIdentifier identifier, const ResourceRequest& request) >+{ >+ auto* webFrameLoaderClient = toWebFrameLoaderClient(frameLoader.client()); >+ auto* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : nullptr; >+ auto* webPage = webFrame ? webFrame->page() : nullptr; >+ if (!webPage) >+ return std::nullopt; >+ >+ auto* handler = webPage->urlSchemeHandlerForScheme(request.url().protocol().toStringWithoutCopying()); >+ if (!handler) >+ return std::nullopt; >+ >+ LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, sync load to URL '%s' will be handled by a UIProcess URL scheme handler.", request.url().string().utf8().data()); >+ >+ SyncLoadResult result; >+ handler->loadSynchronously(identifier, request, result.response, result.error, result.data); >+ >+ return WTFMove(result); >+} >+ > void WebLoaderStrategy::loadResourceSynchronously(FrameLoader& frameLoader, unsigned long resourceLoadIdentifier, const ResourceRequest& request, ClientCredentialPolicy clientCredentialPolicy, const FetchOptions& options, const HTTPHeaderMap& originalRequestHeaders, ResourceError& error, ResourceResponse& response, Vector<char>& data) > { > auto* document = frameLoader.frame().document(); >@@ -481,6 +501,13 @@ void WebLoaderStrategy::loadResourceSynchronously(FrameLoader& frameLoader, unsi > return; > } > >+ if (auto syncLoadResult = tryLoadingSynchronouslyUsingURLSchemeHandler(frameLoader, resourceLoadIdentifier, request)) { >+ error = WTFMove(syncLoadResult->error); >+ response = WTFMove(syncLoadResult->response); >+ data = WTFMove(syncLoadResult->data); >+ return; >+ } >+ > WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frameLoader.client()); > WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : nullptr; > WebPage* webPage = webFrame ? webFrame->page() : nullptr; >diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h >index 0983f4210ff..5b7e97fc935 100644 >--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h >+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h >@@ -27,7 +27,9 @@ > > #include "WebResourceLoader.h" > #include <WebCore/LoaderStrategy.h> >+#include <WebCore/ResourceError.h> > #include <WebCore/ResourceLoader.h> >+#include <WebCore/ResourceResponse.h> > #include <wtf/HashSet.h> > #include <wtf/RunLoop.h> > >@@ -90,6 +92,13 @@ private: > void internallyFailedLoadTimerFired(); > void startLocalLoad(WebCore::ResourceLoader&); > bool tryLoadingUsingURLSchemeHandler(WebCore::ResourceLoader&); >+ >+ struct SyncLoadResult { >+ WebCore::ResourceResponse response; >+ WebCore::ResourceError error; >+ Vector<char> data; >+ }; >+ std::optional<SyncLoadResult> tryLoadingSynchronouslyUsingURLSchemeHandler(WebCore::FrameLoader&, ResourceLoadIdentifier, const WebCore::ResourceRequest&); > > WebCore::ResourceResponse responseFromResourceLoadIdentifier(uint64_t resourceLoadIdentifier) final; > Vector<WebCore::NetworkTransactionInformation> intermediateLoadInformationFromResourceLoadIdentifier(uint64_t resourceLoadIdentifier) final; >diff --git a/Source/WebKit/WebProcess/WebPage/WebURLSchemeHandlerProxy.cpp b/Source/WebKit/WebProcess/WebPage/WebURLSchemeHandlerProxy.cpp >index cdb43fb9eaf..ad2026a5c79 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebURLSchemeHandlerProxy.cpp >+++ b/Source/WebKit/WebProcess/WebPage/WebURLSchemeHandlerProxy.cpp >@@ -26,10 +26,18 @@ > #include "config.h" > #include "WebURLSchemeHandlerProxy.h" > >+#include "DataReference.h" >+#include "URLSchemeTaskParameters.h" >+#include "WebCoreArgumentCoders.h" > #include "WebErrors.h" > #include "WebLoaderStrategy.h" >+#include "WebPage.h" >+#include "WebPageProxyMessages.h" > #include "WebProcess.h" >+#include <WebCore/ResourceError.h> > #include <WebCore/ResourceLoader.h> >+#include <WebCore/ResourceRequest.h> >+#include <WebCore/ResourceResponse.h> > > using namespace WebCore; > >@@ -55,6 +63,18 @@ void WebURLSchemeHandlerProxy::startNewTask(ResourceLoader& loader) > result.iterator->value->startLoading(); > } > >+void WebURLSchemeHandlerProxy::loadSynchronously(ResourceLoadIdentifier loadIdentifier, const ResourceRequest& request, ResourceResponse& response, ResourceError& error, Vector<char>& data) >+{ >+ IPC::DataReference dataReference; >+ if (!m_webPage.sendSync(Messages::WebPageProxy::LoadSynchronousURLSchemeTask(URLSchemeTaskParameters { m_identifier, loadIdentifier, request }), Messages::WebPageProxy::LoadSynchronousURLSchemeTask::Reply(response, error, dataReference))) { >+ error = failedCustomProtocolSyncLoad(request); >+ return; >+ } >+ >+ data.resize(dataReference.size()); >+ memcpy(data.data(), dataReference.data(), dataReference.size()); >+} >+ > void WebURLSchemeHandlerProxy::stopAllTasks() > { > while (!m_tasks.isEmpty()) >diff --git a/Source/WebKit/WebProcess/WebPage/WebURLSchemeHandlerProxy.h b/Source/WebKit/WebProcess/WebPage/WebURLSchemeHandlerProxy.h >index 742415c771a..d8e377a75c4 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebURLSchemeHandlerProxy.h >+++ b/Source/WebKit/WebProcess/WebPage/WebURLSchemeHandlerProxy.h >@@ -39,6 +39,7 @@ class ResourceRequest; > namespace WebKit { > > class WebPage; >+typedef uint64_t ResourceLoadIdentifier; > > class WebURLSchemeHandlerProxy : public RefCounted<WebURLSchemeHandlerProxy> { > public: >@@ -51,6 +52,8 @@ public: > void startNewTask(WebCore::ResourceLoader&); > void stopAllTasks(); > >+ void loadSynchronously(ResourceLoadIdentifier, const WebCore::ResourceRequest&, WebCore::ResourceResponse&, WebCore::ResourceError&, Vector<char>&); >+ > uint64_t identifier() const { return m_identifier; } > WebPage& page() { return m_webPage; } > >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index c369afeaab6..da976163d54 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,16 @@ >+2018-06-22 Brady Eidson <beidson@apple.com> >+ >+ WKURLSchemeHandler doesn't handle sync XHR. >+ <rdar://problem/40955884> and https://bugs.webkit.org/show_bug.cgi?id=186902 >+ >+ Reviewed by Chris Dumez. >+ >+ * TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm: >+ (-[SyncScheme webView:startURLSchemeTask:]): >+ (-[SyncScheme webView:stopURLSchemeTask:]): >+ (-[SyncMessageHandler userContentController:didReceiveScriptMessage:]): >+ (catch): >+ > 2018-06-19 Daniel Bates <dabates@apple.com> > > QueueStatusServer: "'NoneType' object has no attribute 'message'" in ReleasePatch.get() >diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm >index 412e77f510a..f0e6897a035 100644 >--- a/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm >+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm >@@ -31,8 +31,11 @@ > #import <WebKit/WKURLSchemeTaskPrivate.h> > #import <WebKit/WKWebViewConfigurationPrivate.h> > #import <WebKit/WebKit.h> >+#import <wtf/HashMap.h> > #import <wtf/RetainPtr.h> > #import <wtf/Vector.h> >+#import <wtf/text/StringHash.h> >+#import <wtf/text/WTFString.h> > > #if WK_API_ENABLED > >@@ -409,4 +412,131 @@ TEST(URLSchemeHandler, Exceptions) > checkCallSequence({Command::Response, Command::Finish, Command::Error}, ShouldRaiseException::Yes); > } > >-#endif >+struct SchemeResourceInfo { >+ RetainPtr<NSString> mimeType; >+ const char* data; >+ bool shouldRespond; >+}; >+ >+static bool startedXHR; >+static bool receivedStop; >+ >+@interface SyncScheme : NSObject <WKURLSchemeHandler> { >+@public >+ HashMap<String, SchemeResourceInfo> resources; >+} >+@end >+ >+@implementation SyncScheme >+ >+- (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)task >+{ >+ auto entry = resources.find([task.request.URL absoluteString]); >+ if (entry == resources.end()) { >+ NSLog(@"Did not find resource entry for URL %@", task.request.URL); >+ return; >+ } >+ >+ if (entry->key == "syncxhr://host/test.dat") >+ startedXHR = true; >+ >+ if (!entry->value.shouldRespond) >+ return; >+ >+ RetainPtr<NSURLResponse> response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:entry->value.mimeType.get() expectedContentLength:1 textEncodingName:nil]); >+ [task didReceiveResponse:response.get()]; >+ >+ [task didReceiveData:[NSData dataWithBytesNoCopy:(void*)entry->value.data length:strlen(entry->value.data) freeWhenDone:NO]]; >+ [task didFinish]; >+ >+ if (entry->key == "syncxhr://host/test.dat") >+ startedXHR = false; >+} >+ >+- (void)webView:(WKWebView *)webView stopURLSchemeTask:(id <WKURLSchemeTask>)task >+{ >+ EXPECT_TRUE([[task.request.URL absoluteString] isEqualToString:@"syncxhr://host/test.dat"]); >+ receivedStop = true; >+} >+ >+@end >+ >+static RetainPtr<NSMutableArray> receivedMessages = adoptNS([@[] mutableCopy]); >+static bool receivedMessage; >+ >+@interface SyncMessageHandler : NSObject <WKScriptMessageHandler> >+@end >+ >+@implementation SyncMessageHandler >+- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message >+{ >+ if ([message body]) >+ [receivedMessages addObject:[message body]]; >+ else >+ [receivedMessages addObject:@""]; >+ >+ receivedMessage = true; >+} >+@end >+ >+static const char* syncMainBytes = R"SYNCRESOURCE( >+<script> >+ >+var req = new XMLHttpRequest(); >+req.open("GET", "test.dat", false); >+try >+{ >+ req.send(null); >+ window.webkit.messageHandlers.sync.postMessage(req.responseText); >+} >+catch (e) >+{ >+ window.webkit.messageHandlers.sync.postMessage("Failed sync XHR load"); >+} >+ >+</script> >+)SYNCRESOURCE"; >+ >+static const char* syncXHRBytes = "My XHR text!"; >+ >+TEST(URLSchemeHandler, SyncXHR) >+{ >+ auto *pool = [[NSAutoreleasePool alloc] init]; >+ >+ auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]); >+ auto handler = adoptNS([[SyncScheme alloc] init]); >+ [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"syncxhr"]; >+ >+ handler.get()->resources.set("syncxhr://host/main.html", SchemeResourceInfo { @"text/html", syncMainBytes, true }); >+ handler.get()->resources.set("syncxhr://host/test.dat", SchemeResourceInfo { @"text/plain", syncXHRBytes, true }); >+ >+ auto messageHandler = adoptNS([[SyncMessageHandler alloc] init]); >+ [[webViewConfiguration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sync"]; >+ >+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]); >+ >+ NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"syncxhr://host/main.html"]]; >+ [webView loadRequest:request]; >+ >+ TestWebKitAPI::Util::run(&receivedMessage); >+ receivedMessage = false; >+ >+ EXPECT_EQ((unsigned)receivedMessages.get().count, (unsigned)1); >+ EXPECT_TRUE([receivedMessages.get()[0] isEqualToString:@"My XHR text!"]); >+ >+ // Now try again, but hang the WebProcess in the reply to the XHR by telling the scheme handler to never >+ // respond to it. >+ handler.get()->resources.find("syncxhr://host/test.dat")->value.shouldRespond = false; >+ [webView loadRequest:request]; >+ >+ TestWebKitAPI::Util::run(&startedXHR); >+ receivedMessage = false; >+ >+ webView = nil; >+ [pool drain]; >+ >+ TestWebKitAPI::Util::run(&receivedStop); >+} >+ >+#endif // WK_API_ENABLED >+
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 186902
:
343295
|
343308
|
343363
| 343378