Diff
Modified: trunk/Source/WebCore/ChangeLog (218749 => 218750)
--- trunk/Source/WebCore/ChangeLog 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebCore/ChangeLog 2017-06-23 17:25:43 UTC (rev 218750)
@@ -1,3 +1,15 @@
+2017-06-23 Alex Christensen <[email protected]>
+
+ Add SPI to WKURLSchemeTask for redirection
+ https://bugs.webkit.org/show_bug.cgi?id=173730
+
+ Reviewed by Brady Eidson.
+
+ * platform/network/CacheValidation.cpp:
+ (WebCore::computeFreshnessLifetimeForHTTPFamily):
+ Asserting that redirects are always http/https URLs is no longer valid.
+ If there's a custom scheme redirect, give it no freshness lifetime in the cache.
+
2017-06-23 Konstantin Tokarev <[email protected]>
Remove excessive headers from WebCore/{editing,fileapi,history,html,loader,page}
Modified: trunk/Source/WebCore/platform/network/CacheValidation.cpp (218749 => 218750)
--- trunk/Source/WebCore/platform/network/CacheValidation.cpp 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebCore/platform/network/CacheValidation.cpp 2017-06-23 17:25:43 UTC (rev 218750)
@@ -118,7 +118,8 @@
{
using namespace std::chrono;
- ASSERT(response.url().protocolIsInHTTPFamily());
+ if (!response.url().protocolIsInHTTPFamily())
+ return 0us;
// Freshness Lifetime:
// http://tools.ietf.org/html/rfc7234#section-4.2.1
Modified: trunk/Source/WebKit2/ChangeLog (218749 => 218750)
--- trunk/Source/WebKit2/ChangeLog 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/ChangeLog 2017-06-23 17:25:43 UTC (rev 218750)
@@ -1,3 +1,54 @@
+2017-06-23 Alex Christensen <[email protected]>
+
+ Add SPI to WKURLSchemeTask for redirection
+ https://bugs.webkit.org/show_bug.cgi?id=173730
+
+ Reviewed by Brady Eidson.
+
+ This is needed for testing an upcoming fix for redirect callbacks, and it might be
+ necessary for loading with custom schemes in general. Right now just responding with
+ an HTTP 301/302/307/308 response code doesn't work because there is nothing that
+ synthesizes an NSURLRequest from the Location header like we do in
+ SynchronousResourceHandleCFURLConnectionDelegate::willSendRequest et al. for HSTS,
+ and that would require using an NSHTTPURLResponse for non-HTTP responses, which is
+ conceptually wrong. Instead of waiting for a completion handler in the API, we are
+ following the pattern of WKNavigationDelegate.didReceiveServerRedirectForProvisionalNavigation
+ and allowing the SPI to indicate that a redirect has happened to update the state of
+ WebKit, but not allowing the SPI to wait for a processed request and slow down loading.
+
+ This adds WKURLSchemeTaskPrivate._didPerformRedirection which is covered by new API tests.
+
+ * UIProcess/API/Cocoa/WKURLSchemeTask.mm:
+ (raiseExceptionIfNecessary):
+ (-[WKURLSchemeTaskImpl _didPerformRedirection:newRequest:completionHandler:]):
+ * UIProcess/API/Cocoa/WKURLSchemeTaskInternal.h:
+ * UIProcess/API/Cocoa/WKURLSchemeTaskPrivate.h: Added.
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::startURLSchemeTask):
+ (WebKit::WebPageProxy::stopURLSchemeTask):
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/WebPageProxy.messages.in:
+ * UIProcess/WebURLSchemeHandler.cpp:
+ (WebKit::WebURLSchemeHandler::startTask):
+ (WebKit::WebURLSchemeHandler::stopTask):
+ * UIProcess/WebURLSchemeHandler.h:
+ * UIProcess/WebURLSchemeTask.cpp:
+ (WebKit::WebURLSchemeTask::didReceiveResponse): Deleted.
+ (WebKit::WebURLSchemeTask::didReceiveData): Deleted.
+ (WebKit::WebURLSchemeTask::didComplete): Deleted.
+ * UIProcess/WebURLSchemeTask.h:
+ * WebKit2.xcodeproj/project.pbxproj:
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::urlSchemeTaskDidPerformRedirection):
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in:
+ * WebProcess/WebPage/WebURLSchemeHandlerProxy.cpp:
+ (WebKit::WebURLSchemeHandlerProxy::taskDidPerformRedirection):
+ * WebProcess/WebPage/WebURLSchemeHandlerProxy.h:
+ * WebProcess/WebPage/WebURLSchemeTaskProxy.cpp:
+ (WebKit::WebURLSchemeTaskProxy::didPerformRedirection):
+ * WebProcess/WebPage/WebURLSchemeTaskProxy.h:
+
2017-06-23 Brent Fulgham <[email protected]>
[WK2][macOS] Support Mac Mini Flash Player Features
Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKURLSchemeTask.mm (218749 => 218750)
--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKURLSchemeTask.mm 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKURLSchemeTask.mm 2017-06-23 17:25:43 UTC (rev 218750)
@@ -28,10 +28,11 @@
#if WK_API_ENABLED
-#include "WebURLSchemeTask.h"
-#include <WebCore/ResourceError.h>
-#include <WebCore/ResourceResponse.h>
-#include <WebCore/SharedBuffer.h>
+#import "WebURLSchemeTask.h"
+#import <WebCore/ResourceError.h>
+#import <WebCore/ResourceResponse.h>
+#import <WebCore/SharedBuffer.h>
+#import <wtf/BlockPtr.h>
using namespace WebCore;
@@ -52,6 +53,9 @@
case WebKit::WebURLSchemeTask::ExceptionType::NoResponseSent:
[NSException raise:NSInternalInconsistencyException format:@"No response has been sent for this task"];
break;
+ case WebKit::WebURLSchemeTask::ExceptionType::RedirectAfterResponse:
+ [NSException raise:NSInternalInconsistencyException format:@"No redirects are allowed after the response"];
+ break;
}
}
@@ -86,6 +90,12 @@
raiseExceptionIfNecessary(result);
}
+- (void)_didPerformRedirection:(NSURLResponse *)response newRequest:(NSURLRequest *)request
+{
+ auto result = _urlSchemeTask->task().didPerformRedirection(response, request);
+ raiseExceptionIfNecessary(result);
+}
+
#pragma mark WKObject protocol implementation
- (API::Object&)_apiObject
Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKURLSchemeTaskInternal.h (218749 => 218750)
--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKURLSchemeTaskInternal.h 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKURLSchemeTaskInternal.h 2017-06-23 17:25:43 UTC (rev 218750)
@@ -23,7 +23,7 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#import "WKURLSchemeTask.h"
+#import "WKURLSchemeTaskPrivate.h"
#if WK_API_ENABLED
@@ -30,7 +30,7 @@
#import "APIURLSchemeTask.h"
#import "WKObject.h"
-@interface WKURLSchemeTaskImpl : NSObject <WKURLSchemeTask>
+@interface WKURLSchemeTaskImpl : NSObject <WKURLSchemeTaskPrivate>
@end
namespace WebKit {
Added: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKURLSchemeTaskPrivate.h (0 => 218750)
--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKURLSchemeTaskPrivate.h (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKURLSchemeTaskPrivate.h 2017-06-23 17:25:43 UTC (rev 218750)
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#import <WebKit/WKURLSchemeTask.h>
+
+#if WK_API_ENABLED
+
+WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA))
+@protocol WKURLSchemeTaskPrivate <WKURLSchemeTask>
+
+- (void)_didPerformRedirection:(NSURLResponse *)response newRequest:(NSURLRequest *)request;
+
+@end
+
+#endif
+
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (218749 => 218750)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp 2017-06-23 17:25:43 UTC (rev 218750)
@@ -6879,20 +6879,20 @@
return m_urlSchemeHandlersByScheme.get(scheme);
}
-void WebPageProxy::startURLSchemeTask(uint64_t handlerIdentifier, uint64_t resourceIdentifier, const WebCore::ResourceRequest& request)
+void WebPageProxy::startURLSchemeTask(uint64_t handlerIdentifier, uint64_t taskIdentifier, const WebCore::ResourceRequest& request)
{
auto iterator = m_urlSchemeHandlersByIdentifier.find(handlerIdentifier);
ASSERT(iterator != m_urlSchemeHandlersByIdentifier.end());
- iterator->value->startTask(*this, resourceIdentifier, request);
+ iterator->value->startTask(*this, taskIdentifier, request);
}
-void WebPageProxy::stopURLSchemeTask(uint64_t handlerIdentifier, uint64_t resourceIdentifier)
+void WebPageProxy::stopURLSchemeTask(uint64_t handlerIdentifier, uint64_t taskIdentifier)
{
auto iterator = m_urlSchemeHandlersByIdentifier.find(handlerIdentifier);
ASSERT(iterator != m_urlSchemeHandlersByIdentifier.end());
- iterator->value->stopTask(*this, resourceIdentifier);
+ iterator->value->stopTask(*this, taskIdentifier);
}
void WebPageProxy::setAvoidsUnsafeArea(bool avoidsUnsafeArea)
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (218749 => 218750)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h 2017-06-23 17:25:43 UTC (rev 218750)
@@ -1607,8 +1607,8 @@
#endif
#endif
- void startURLSchemeTask(uint64_t handlerIdentifier, uint64_t resourceIdentifier, const WebCore::ResourceRequest&);
- void stopURLSchemeTask(uint64_t handlerIdentifier, uint64_t resourceIdentifier);
+ void startURLSchemeTask(uint64_t handlerIdentifier, uint64_t taskIdentifier, const WebCore::ResourceRequest&);
+ void stopURLSchemeTask(uint64_t handlerIdentifier, uint64_t taskIdentifier);
void handleAutoFillButtonClick(const UserData&);
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in (218749 => 218750)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in 2017-06-23 17:25:43 UTC (rev 218750)
@@ -495,6 +495,6 @@
SetIsUsingHighPerformanceWebGL(bool isUsingHighPerformanceWebGL)
- StartURLSchemeTask(uint64_t loaderIdentifier, uint64_t resourceIdentifier, WebCore::ResourceRequest request)
- StopURLSchemeTask(uint64_t loaderIdentifier, uint64_t resourceIdentifier)
+ StartURLSchemeTask(uint64_t handlerIdentifier, uint64_t taskIdentifier, WebCore::ResourceRequest request)
+ StopURLSchemeTask(uint64_t handlerIdentifier, uint64_t taskIdentifier)
}
Modified: trunk/Source/WebKit2/UIProcess/WebURLSchemeHandler.cpp (218749 => 218750)
--- trunk/Source/WebKit2/UIProcess/WebURLSchemeHandler.cpp 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/UIProcess/WebURLSchemeHandler.cpp 2017-06-23 17:25:43 UTC (rev 218750)
@@ -48,17 +48,17 @@
ASSERT(m_tasks.isEmpty());
}
-void WebURLSchemeHandler::startTask(WebPageProxy& page, uint64_t resourceIdentifier, const ResourceRequest& request)
+void WebURLSchemeHandler::startTask(WebPageProxy& page, uint64_t taskIdentifier, const ResourceRequest& request)
{
- auto result = m_tasks.add(resourceIdentifier, WebURLSchemeTask::create(*this, page, resourceIdentifier, request));
+ auto result = m_tasks.add(taskIdentifier, WebURLSchemeTask::create(*this, page, taskIdentifier, request));
ASSERT(result.isNewEntry);
platformStartTask(page, result.iterator->value);
}
-void WebURLSchemeHandler::stopTask(WebPageProxy& page, uint64_t resourceIdentifier)
+void WebURLSchemeHandler::stopTask(WebPageProxy& page, uint64_t taskIdentifier)
{
- auto iterator = m_tasks.find(resourceIdentifier);
+ auto iterator = m_tasks.find(taskIdentifier);
if (iterator == m_tasks.end())
return;
Modified: trunk/Source/WebKit2/UIProcess/WebURLSchemeHandler.h (218749 => 218750)
--- trunk/Source/WebKit2/UIProcess/WebURLSchemeHandler.h 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/UIProcess/WebURLSchemeHandler.h 2017-06-23 17:25:43 UTC (rev 218750)
@@ -45,8 +45,8 @@
uint64_t identifier() const { return m_identifier; }
- void startTask(WebPageProxy&, uint64_t resourceIdentifier, const WebCore::ResourceRequest&);
- void stopTask(WebPageProxy&, uint64_t resourceIdentifier);
+ void startTask(WebPageProxy&, uint64_t taskIdentifier, const WebCore::ResourceRequest&);
+ void stopTask(WebPageProxy&, uint64_t taskIdentifier);
protected:
WebURLSchemeHandler();
Modified: trunk/Source/WebKit2/UIProcess/WebURLSchemeTask.cpp (218749 => 218750)
--- trunk/Source/WebKit2/UIProcess/WebURLSchemeTask.cpp 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/UIProcess/WebURLSchemeTask.cpp 2017-06-23 17:25:43 UTC (rev 218750)
@@ -48,54 +48,74 @@
{
}
-WebURLSchemeTask::ExceptionType WebURLSchemeTask::didReceiveResponse(const ResourceResponse& response)
+auto WebURLSchemeTask::didPerformRedirection(WebCore::ResourceResponse&& response, WebCore::ResourceRequest&& request) -> ExceptionType
{
if (m_stopped)
- return WebURLSchemeTask::ExceptionType::TaskAlreadyStopped;
+ return ExceptionType::TaskAlreadyStopped;
+
+ if (m_completed)
+ return ExceptionType::CompleteAlreadyCalled;
+
+ if (m_dataSent)
+ return ExceptionType::DataAlreadySent;
+
+ if (m_responseSent)
+ return ExceptionType::RedirectAfterResponse;
+
+ m_request = request;
+ m_page->send(Messages::WebPage::URLSchemeTaskDidPerformRedirection(m_urlSchemeHandler->identifier(), m_identifier, response, request));
+ return ExceptionType::None;
+}
+
+auto WebURLSchemeTask::didReceiveResponse(const ResourceResponse& response) -> ExceptionType
+{
+ if (m_stopped)
+ return ExceptionType::TaskAlreadyStopped;
+
if (m_completed)
- return WebURLSchemeTask::ExceptionType::CompleteAlreadyCalled;
+ return ExceptionType::CompleteAlreadyCalled;
if (m_dataSent)
- return WebURLSchemeTask::ExceptionType::DataAlreadySent;
+ return ExceptionType::DataAlreadySent;
m_responseSent = true;
response.includeCertificateInfo();
m_page->send(Messages::WebPage::URLSchemeTaskDidReceiveResponse(m_urlSchemeHandler->identifier(), m_identifier, response));
- return WebURLSchemeTask::ExceptionType::None;
+ return ExceptionType::None;
}
-WebURLSchemeTask::ExceptionType WebURLSchemeTask::didReceiveData(Ref<SharedBuffer> buffer)
+auto WebURLSchemeTask::didReceiveData(Ref<SharedBuffer> buffer) -> ExceptionType
{
if (m_stopped)
- return WebURLSchemeTask::ExceptionType::TaskAlreadyStopped;
+ return ExceptionType::TaskAlreadyStopped;
if (m_completed)
- return WebURLSchemeTask::ExceptionType::CompleteAlreadyCalled;
+ return ExceptionType::CompleteAlreadyCalled;
if (!m_responseSent)
- return WebURLSchemeTask::ExceptionType::NoResponseSent;
+ return ExceptionType::NoResponseSent;
m_dataSent = true;
m_page->send(Messages::WebPage::URLSchemeTaskDidReceiveData(m_urlSchemeHandler->identifier(), m_identifier, IPC::SharedBufferDataReference(buffer.ptr())));
- return WebURLSchemeTask::ExceptionType::None;
+ return ExceptionType::None;
}
-WebURLSchemeTask::ExceptionType WebURLSchemeTask::didComplete(const ResourceError& error)
+auto WebURLSchemeTask::didComplete(const ResourceError& error) -> ExceptionType
{
if (m_stopped)
- return WebURLSchemeTask::ExceptionType::TaskAlreadyStopped;
+ return ExceptionType::TaskAlreadyStopped;
if (m_completed)
- return WebURLSchemeTask::ExceptionType::CompleteAlreadyCalled;
+ return ExceptionType::CompleteAlreadyCalled;
if (!m_responseSent && error.isNull())
- return WebURLSchemeTask::ExceptionType::NoResponseSent;
+ return ExceptionType::NoResponseSent;
m_completed = true;
m_page->send(Messages::WebPage::URLSchemeTaskDidComplete(m_urlSchemeHandler->identifier(), m_identifier, error));
- return WebURLSchemeTask::ExceptionType::None;
+ return ExceptionType::None;
}
void WebURLSchemeTask::pageDestroyed()
Modified: trunk/Source/WebKit2/UIProcess/WebURLSchemeTask.h (218749 => 218750)
--- trunk/Source/WebKit2/UIProcess/WebURLSchemeTask.h 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/UIProcess/WebURLSchemeTask.h 2017-06-23 17:25:43 UTC (rev 218750)
@@ -52,10 +52,12 @@
enum class ExceptionType {
DataAlreadySent,
CompleteAlreadyCalled,
+ RedirectAfterResponse,
TaskAlreadyStopped,
NoResponseSent,
None,
};
+ ExceptionType didPerformRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&);
ExceptionType didReceiveResponse(const WebCore::ResourceResponse&);
ExceptionType didReceiveData(Ref<WebCore::SharedBuffer>);
ExceptionType didComplete(const WebCore::ResourceError&);
Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (218749 => 218750)
--- trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj 2017-06-23 17:25:43 UTC (rev 218750)
@@ -1160,6 +1160,7 @@
5C20CB9D1BB0DCFA00895BB1 /* NetworkSessionCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C20CB9B1BB0DCD200895BB1 /* NetworkSessionCocoa.mm */; };
5C20CBA01BB1ECD800895BB1 /* NetworkSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C20CB9E1BB0DD1800895BB1 /* NetworkSession.h */; };
5C298DA01C3DF02100470AFE /* PendingDownload.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C298D9E1C3DEF2900470AFE /* PendingDownload.h */; };
+ 5C62FDF91EFC271C00CE072E /* WKURLSchemeTaskPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C62FDF81EFC263C00CE072E /* WKURLSchemeTaskPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
5C7706741D1138380012700F /* WebSocketProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C7706731D111D8B0012700F /* WebSocketProvider.cpp */; };
5C85C7881C3F23CE0061A4FA /* PendingDownload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C85C7861C3F23C50061A4FA /* PendingDownload.cpp */; };
5C9E56821DF7F1AB00C9EE33 /* WKWebsitePolicies.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C9E56801DF7F05500C9EE33 /* WKWebsitePolicies.cpp */; };
@@ -3443,6 +3444,7 @@
5C20CB9B1BB0DCD200895BB1 /* NetworkSessionCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = NetworkSessionCocoa.mm; path = NetworkProcess/cocoa/NetworkSessionCocoa.mm; sourceTree = "<group>"; };
5C20CB9E1BB0DD1800895BB1 /* NetworkSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkSession.h; path = NetworkProcess/NetworkSession.h; sourceTree = "<group>"; };
5C298D9E1C3DEF2900470AFE /* PendingDownload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PendingDownload.h; path = NetworkProcess/Downloads/PendingDownload.h; sourceTree = "<group>"; };
+ 5C62FDF81EFC263C00CE072E /* WKURLSchemeTaskPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WKURLSchemeTaskPrivate.h; sourceTree = "<group>"; };
5C7706731D111D8B0012700F /* WebSocketProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebSocketProvider.cpp; path = Network/WebSocketProvider.cpp; sourceTree = "<group>"; };
5C7C88DC1D0F41A0009D2F6D /* WebSocketProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebSocketProvider.h; path = Network/WebSocketProvider.h; sourceTree = "<group>"; };
5C85C7861C3F23C50061A4FA /* PendingDownload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PendingDownload.cpp; path = NetworkProcess/Downloads/PendingDownload.cpp; sourceTree = "<group>"; };
@@ -5718,6 +5720,7 @@
51D1242F1E6DDDD7002B2820 /* WKURLSchemeTask.h */,
51D124301E6DDDD7002B2820 /* WKURLSchemeTask.mm */,
51D124371E6DFD2A002B2820 /* WKURLSchemeTaskInternal.h */,
+ 5C62FDF81EFC263C00CE072E /* WKURLSchemeTaskPrivate.h */,
1AFA3AC718E61C61003CCBAE /* WKUserContentController.h */,
1AFA3AC618E61C61003CCBAE /* WKUserContentController.mm */,
1AAF08A3192682DA00B6390C /* WKUserContentControllerInternal.h */,
@@ -8944,6 +8947,7 @@
37F623B812A57B6200E3FDF6 /* WKFindOptions.h in Headers */,
C54256B518BEC18C00DE4179 /* WKFormInputControl.h in Headers */,
C54256B718BEC18C00DE4179 /* WKFormPeripheral.h in Headers */,
+ 5C62FDF91EFC271C00CE072E /* WKURLSchemeTaskPrivate.h in Headers */,
C54256B818BEC18C00DE4179 /* WKFormPopover.h in Headers */,
C54256BA18BEC18C00DE4179 /* WKFormSelectControl.h in Headers */,
0F08CF521D63C13A00B48DF1 /* WKFormSelectPicker.h in Headers */,
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (218749 => 218750)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp 2017-06-23 17:25:43 UTC (rev 218750)
@@ -5905,7 +5905,7 @@
void WebPage::registerURLSchemeHandler(uint64_t handlerIdentifier, const String& scheme)
{
- auto schemeResult = m_schemeToURLSchemeHandlerProxyMap.add(scheme, std::make_unique<WebURLSchemeHandlerProxy>(*this, handlerIdentifier));
+ auto schemeResult = m_schemeToURLSchemeHandlerProxyMap.add(scheme, WebURLSchemeHandlerProxy::create(*this, handlerIdentifier));
ASSERT(schemeResult.isNewEntry);
auto identifierResult = m_identifierToURLSchemeHandlerProxyMap.add(handlerIdentifier, schemeResult.iterator->value.get());
@@ -5912,6 +5912,14 @@
ASSERT_UNUSED(identifierResult, identifierResult.isNewEntry);
}
+void WebPage::urlSchemeTaskDidPerformRedirection(uint64_t handlerIdentifier, uint64_t taskIdentifier, ResourceResponse&& response, ResourceRequest&& request)
+{
+ auto* handler = m_identifierToURLSchemeHandlerProxyMap.get(handlerIdentifier);
+ ASSERT(handler);
+
+ handler->taskDidPerformRedirection(taskIdentifier, WTFMove(response), WTFMove(request));
+}
+
void WebPage::urlSchemeTaskDidReceiveResponse(uint64_t handlerIdentifier, uint64_t taskIdentifier, const ResourceResponse& response)
{
auto* handler = m_identifierToURLSchemeHandlerProxyMap.get(handlerIdentifier);
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (218749 => 218750)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h 2017-06-23 17:25:43 UTC (rev 218750)
@@ -1276,6 +1276,7 @@
void registerURLSchemeHandler(uint64_t identifier, const String& scheme);
+ void urlSchemeTaskDidPerformRedirection(uint64_t handlerIdentifier, uint64_t taskIdentifier, WebCore::ResourceResponse&&, WebCore::ResourceRequest&&);
void urlSchemeTaskDidReceiveResponse(uint64_t handlerIdentifier, uint64_t taskIdentifier, const WebCore::ResourceResponse&);
void urlSchemeTaskDidReceiveData(uint64_t handlerIdentifier, uint64_t taskIdentifier, const IPC::DataReference&);
void urlSchemeTaskDidComplete(uint64_t handlerIdentifier, uint64_t taskIdentifier, const WebCore::ResourceError&);
@@ -1568,7 +1569,7 @@
const String m_overrideContentSecurityPolicy;
const std::optional<double> m_cpuLimit;
- HashMap<String, std::unique_ptr<WebURLSchemeHandlerProxy>> m_schemeToURLSchemeHandlerProxyMap;
+ HashMap<String, RefPtr<WebURLSchemeHandlerProxy>> m_schemeToURLSchemeHandlerProxyMap;
HashMap<uint64_t, WebURLSchemeHandlerProxy*> m_identifierToURLSchemeHandlerProxyMap;
};
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (218749 => 218750)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in 2017-06-23 17:25:43 UTC (rev 218750)
@@ -475,7 +475,8 @@
RegisterURLSchemeHandler(uint64_t identifier, String scheme)
- URLSchemeTaskDidReceiveResponse(uint64_t providerIdentifier, uint64_t taskIdentifier, WebCore::ResourceResponse response)
- URLSchemeTaskDidReceiveData(uint64_t providerIdentifier, uint64_t taskIdentifier, IPC::DataReference data)
- URLSchemeTaskDidComplete(uint64_t providerIdentifier, uint64_t taskIdentifier, WebCore::ResourceError error)
+ URLSchemeTaskDidPerformRedirection(uint64_t handlerIdentifier, uint64_t taskIdentifier, WebCore::ResourceResponse response, WebCore::ResourceRequest request)
+ URLSchemeTaskDidReceiveResponse(uint64_t handlerIdentifier, uint64_t taskIdentifier, WebCore::ResourceResponse response)
+ URLSchemeTaskDidReceiveData(uint64_t handlerIdentifier, uint64_t taskIdentifier, IPC::DataReference data)
+ URLSchemeTaskDidComplete(uint64_t handlerIdentifier, uint64_t taskIdentifier, WebCore::ResourceError error)
}
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebURLSchemeHandlerProxy.cpp (218749 => 218750)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebURLSchemeHandlerProxy.cpp 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebURLSchemeHandlerProxy.cpp 2017-06-23 17:25:43 UTC (rev 218750)
@@ -48,7 +48,7 @@
void WebURLSchemeHandlerProxy::startNewTask(ResourceLoader& loader)
{
- auto result = m_tasks.add(loader.identifier(), std::make_unique<WebURLSchemeTaskProxy>(*this, loader));
+ auto result = m_tasks.add(loader.identifier(), WebURLSchemeTaskProxy::create(*this, loader));
ASSERT(result.isNewEntry);
WebProcess::singleton().webLoaderStrategy().addURLSchemeTaskProxy(*result.iterator->value);
@@ -55,6 +55,14 @@
result.iterator->value->startLoading();
}
+void WebURLSchemeHandlerProxy::taskDidPerformRedirection(uint64_t taskIdentifier, WebCore::ResourceResponse&& redirectResponse, WebCore::ResourceRequest&& newRequest)
+{
+ auto* task = m_tasks.get(taskIdentifier);
+ if (!task)
+ return;
+
+ task->didPerformRedirection(WTFMove(redirectResponse), WTFMove(newRequest));
+}
void WebURLSchemeHandlerProxy::taskDidReceiveResponse(uint64_t taskIdentifier, const ResourceResponse& response)
{
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebURLSchemeHandlerProxy.h (218749 => 218750)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebURLSchemeHandlerProxy.h 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebURLSchemeHandlerProxy.h 2017-06-23 17:25:43 UTC (rev 218750)
@@ -27,11 +27,13 @@
#include "WebURLSchemeTaskProxy.h"
#include <wtf/HashMap.h>
+#include <wtf/RefCounted.h>
namespace WebCore {
class ResourceError;
class ResourceLoader;
class ResourceResponse;
+class ResourceRequest;
}
namespace WebKit {
@@ -38,10 +40,12 @@
class WebPage;
-class WebURLSchemeHandlerProxy {
- WTF_MAKE_NONCOPYABLE(WebURLSchemeHandlerProxy);
+class WebURLSchemeHandlerProxy : public RefCounted<WebURLSchemeHandlerProxy> {
public:
- WebURLSchemeHandlerProxy(WebPage&, uint64_t identifier);
+ static Ref<WebURLSchemeHandlerProxy> create(WebPage& page, uint64_t identifier)
+ {
+ return adoptRef(*new WebURLSchemeHandlerProxy(page, identifier));
+ }
~WebURLSchemeHandlerProxy();
void startNewTask(WebCore::ResourceLoader&);
@@ -49,6 +53,7 @@
uint64_t identifier() const { return m_identifier; }
WebPage& page() { return m_webPage; }
+ void taskDidPerformRedirection(uint64_t taskIdentifier, WebCore::ResourceResponse&&, WebCore::ResourceRequest&&);
void taskDidReceiveResponse(uint64_t taskIdentifier, const WebCore::ResourceResponse&);
void taskDidReceiveData(uint64_t taskIdentifier, size_t, const uint8_t* data);
void taskDidComplete(uint64_t taskIdentifier, const WebCore::ResourceError&);
@@ -55,10 +60,11 @@
void taskDidStopLoading(WebURLSchemeTaskProxy&);
private:
+ WebURLSchemeHandlerProxy(WebPage&, uint64_t identifier);
WebPage& m_webPage;
uint64_t m_identifier { 0 };
- HashMap<unsigned long, std::unique_ptr<WebURLSchemeTaskProxy>> m_tasks;
+ HashMap<uint64_t, RefPtr<WebURLSchemeTaskProxy>> m_tasks;
}; // class WebURLSchemeHandlerProxy
} // namespace WebKit
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebURLSchemeTaskProxy.cpp (218749 => 218750)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebURLSchemeTaskProxy.cpp 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebURLSchemeTaskProxy.cpp 2017-06-23 17:25:43 UTC (rev 218750)
@@ -62,9 +62,32 @@
// This line will result in this being deleted.
m_urlSchemeHandler.taskDidStopLoading(*this);
}
+
+void WebURLSchemeTaskProxy::didPerformRedirection(WebCore::ResourceResponse&& redirectResponse, WebCore::ResourceRequest&& request)
+{
+ if (!hasLoader())
+ return;
+
+ auto completionHandler = [this, protectedThis = makeRef(*this), originalRequest = request] (ResourceRequest&& request) {
+ m_waitingForRedirectCompletionHandler = false;
+ // We do not inform the UIProcess of WebKit's new request with the given suggested request.
+ // We do want to know if WebKit would have generated a request that differs from the suggested request, though.
+ if (request.url() != originalRequest.url())
+ WTFLogAlways("Redirected scheme task would have been sent to a different URL.");
+ };
+
+ if (m_waitingForRedirectCompletionHandler)
+ WTFLogAlways("Received redirect during previous redirect processing.");
+ m_waitingForRedirectCompletionHandler = true;
+ m_coreLoader->willSendRequest(WTFMove(request), redirectResponse, WTFMove(completionHandler));
+}
+
void WebURLSchemeTaskProxy::didReceiveResponse(const ResourceResponse& response)
{
+ if (m_waitingForRedirectCompletionHandler)
+ WTFLogAlways("Received response during redirect processing.");
+
if (!hasLoader())
return;
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebURLSchemeTaskProxy.h (218749 => 218750)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebURLSchemeTaskProxy.h 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebURLSchemeTaskProxy.h 2017-06-23 17:25:43 UTC (rev 218750)
@@ -26,6 +26,7 @@
#pragma once
#include <WebCore/ResourceRequest.h>
+#include <wtf/RefCounted.h>
namespace WebCore {
class ResourceError;
@@ -37,16 +38,19 @@
class WebURLSchemeHandlerProxy;
-class WebURLSchemeTaskProxy {
- WTF_MAKE_NONCOPYABLE(WebURLSchemeTaskProxy);
+class WebURLSchemeTaskProxy : public RefCounted<WebURLSchemeTaskProxy> {
public:
- WebURLSchemeTaskProxy(WebURLSchemeHandlerProxy&, WebCore::ResourceLoader&);
-
+ static Ref<WebURLSchemeTaskProxy> create(WebURLSchemeHandlerProxy& handler, WebCore::ResourceLoader& loader)
+ {
+ return adoptRef(*new WebURLSchemeTaskProxy(handler, loader));
+ }
+
const WebCore::ResourceRequest& request() const { return m_request; }
void startLoading();
void stopLoading();
+ void didPerformRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&);
void didReceiveResponse(const WebCore::ResourceResponse&);
void didReceiveData(size_t, const uint8_t* data);
void didComplete(const WebCore::ResourceError&);
@@ -54,6 +58,7 @@
unsigned long identifier() const { return m_identifier; }
private:
+ WebURLSchemeTaskProxy(WebURLSchemeHandlerProxy&, WebCore::ResourceLoader&);
bool hasLoader();
WebURLSchemeHandlerProxy& m_urlSchemeHandler;
@@ -60,6 +65,7 @@
RefPtr<WebCore::ResourceLoader> m_coreLoader;
WebCore::ResourceRequest m_request;
unsigned long m_identifier;
+ bool m_waitingForRedirectCompletionHandler { };
};
} // namespace WebKit
Modified: trunk/Tools/ChangeLog (218749 => 218750)
--- trunk/Tools/ChangeLog 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Tools/ChangeLog 2017-06-23 17:25:43 UTC (rev 218750)
@@ -1,3 +1,20 @@
+2017-06-23 Alex Christensen <[email protected]>
+
+ Add SPI to WKURLSchemeTask for redirection
+ https://bugs.webkit.org/show_bug.cgi?id=173730
+
+ Reviewed by Brady Eidson.
+
+ * TestWebKitAPI/Tests/WebKit2Cocoa/WKURLSchemeHandler-1.mm:
+ (-[SchemeHandler webView:startURLSchemeTask:]):
+ (-[SchemeHandler webView:stopURLSchemeTask:]):
+ (TEST):
+ (-[RedirectSchemeHandler webView:startURLSchemeTask:]):
+ (-[RedirectSchemeHandler webView:stopURLSchemeTask:]):
+ (-[RedirectSchemeHandler webView:didReceiveServerRedirectForProvisionalNavigation:]):
+ (-[RedirectSchemeHandler webView:decidePolicyForNavigationResponse:decisionHandler:]):
+ (-[RedirectSchemeHandler userContentController:didReceiveScriptMessage:]):
+
2017-06-23 Carlos Garcia Campos <[email protected]>
[WPE] Use JSC API to send script messages from web extension in tests
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKURLSchemeHandler-1.mm (218749 => 218750)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKURLSchemeHandler-1.mm 2017-06-23 17:21:48 UTC (rev 218749)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKURLSchemeHandler-1.mm 2017-06-23 17:25:43 UTC (rev 218750)
@@ -28,14 +28,15 @@
#import "PlatformUtilities.h"
#import "Test.h"
#import <WebKit/WKURLSchemeHandler.h>
-#import <WebKit/WKURLSchemeTask.h>
+#import <WebKit/WKURLSchemeTaskPrivate.h>
#import <WebKit/WKWebViewConfigurationPrivate.h>
#import <WebKit/WebKit.h>
#import <wtf/RetainPtr.h>
+#import <wtf/Vector.h>
#if WK_API_ENABLED
-static bool receivedScriptMessage;
+static bool done;
@interface SchemeHandler : NSObject <WKURLSchemeHandler>
@property (readonly) NSMutableArray<NSURL *> *startedURLs;
@@ -76,7 +77,7 @@
// Always fail the image load.
if ([task.request.URL.absoluteString isEqualToString:@"testing:image"]) {
[task didFailWithError:[NSError errorWithDomain:@"TestWebKitAPI" code:1 userInfo:nil]];
- receivedScriptMessage = true;
+ done = true;
return;
}
@@ -90,7 +91,7 @@
{
[_stoppedURLs addObject:task.request.URL];
- receivedScriptMessage = true;
+ done = true;
}
@end
@@ -102,7 +103,7 @@
TEST(URLSchemeHandler, Basic)
{
- receivedScriptMessage = false;
+ done = false;
RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
@@ -114,7 +115,7 @@
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"testing:main"]];
[webView loadRequest:request];
- TestWebKitAPI::Util::run(&receivedScriptMessage);
+ TestWebKitAPI::Util::run(&done);
EXPECT_EQ([handler.get().startedURLs count], 2u);
EXPECT_TRUE([[handler.get().startedURLs objectAtIndex:0] isEqual:[NSURL URLWithString:@"testing:main"]]);
@@ -127,7 +128,7 @@
// Since there's no MIMEType, and no NavigationDelegate to tell WebKit to do the load anyways, WebKit will ignore (silently fail) the load.
// This test makes sure that is communicated back to the URLSchemeHandler.
- receivedScriptMessage = false;
+ done = false;
RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
@@ -139,7 +140,7 @@
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"testing:main"]];
[webView loadRequest:request];
- TestWebKitAPI::Util::run(&receivedScriptMessage);
+ TestWebKitAPI::Util::run(&done);
EXPECT_EQ([handler.get().startedURLs count], 1u);
EXPECT_TRUE([[handler.get().startedURLs objectAtIndex:0] isEqual:[NSURL URLWithString:@"testing:main"]]);
@@ -191,5 +192,166 @@
}
}
+static bool receivedRedirect;
+static bool responsePolicyDecided;
+@interface RedirectSchemeHandler : NSObject <WKURLSchemeHandler, WKNavigationDelegate, WKScriptMessageHandler>
+@end
+
+@implementation RedirectSchemeHandler { }
+
+- (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)task
+{
+ ASSERT_STREQ(task.request.URL.absoluteString.UTF8String, "testing:///initial");
+ NSURLResponse *response = [[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:nil expectedContentLength:0 textEncodingName:nil] autorelease];
+ NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"testing:///redirected"]];
+ [(id<WKURLSchemeTaskPrivate>)task _didPerformRedirection:response newRequest:request];
+ ASSERT_FALSE(receivedRedirect);
+ ASSERT_STREQ(task.request.URL.absoluteString.UTF8String, "testing:///redirected");
+ NSString *html = @"<script>window.webkit.messageHandlers.testHandler.postMessage('Document URL: ' + document.URL);</script>";
+ [task didReceiveResponse:[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:html.length textEncodingName:nil]];
+ [task didReceiveData:[html dataUsingEncoding:NSUTF8StringEncoding]];
+ [task didFinish];
+}
+
+- (void)webView:(WKWebView *)webView stopURLSchemeTask:(id <WKURLSchemeTask>)task
+{
+ ASSERT_TRUE(false);
+}
+
+- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation
+{
+ ASSERT_FALSE(receivedRedirect);
+ receivedRedirect = true;
+}
+
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
+{
+ ASSERT_TRUE(receivedRedirect);
+ ASSERT_STREQ(navigationResponse.response.URL.absoluteString.UTF8String, "testing:///redirected");
+ ASSERT_FALSE(responsePolicyDecided);
+ responsePolicyDecided = true;
+ decisionHandler(WKNavigationResponsePolicyAllow);
+}
+
+- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
+{
+ EXPECT_WK_STREQ(@"Document URL: testing:///redirected", [message body]);
+ done = true;
+}
+@end
+
+TEST(URLSchemeHandler, Redirection)
+{
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ auto handler = adoptNS([[RedirectSchemeHandler alloc] init]);
+ [configuration setURLSchemeHandler:handler.get() forURLScheme:@"testing"];
+ [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"];
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+ [webView setNavigationDelegate:handler.get()];
+
+ NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"testing:///initial"]];
+ [webView loadRequest:request];
+
+ TestWebKitAPI::Util::run(&done);
+
+ EXPECT_TRUE(responsePolicyDecided);
+ EXPECT_STREQ(webView.get().URL.absoluteString.UTF8String, "testing:///redirected");
+}
+
+enum class Command {
+ Redirect,
+ Response,
+ Data,
+ Finish,
+ Error,
+};
+
+@interface TaskSchemeHandler : NSObject <WKURLSchemeHandler>
+- (instancetype)initWithCommands:(Vector<Command>&&)commandVector expectedException:(bool)expected;
+@end
+
+@implementation TaskSchemeHandler {
+ Vector<Command> commands;
+ bool expectedException;
+}
+
+- (instancetype)initWithCommands:(Vector<Command>&&)commandVector expectedException:(bool)expected
+{
+ self = [super init];
+ if (!self)
+ return nil;
+
+ self->commands = WTFMove(commandVector);
+ self->expectedException = expected;
+
+ return self;
+}
+
+- (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)task
+{
+ bool caughtException = false;
+ @try {
+ for (auto command : commands) {
+ switch (command) {
+ case Command::Redirect:
+ [(id<WKURLSchemeTaskPrivate>)task _didPerformRedirection:[[[NSURLResponse alloc] init] autorelease] newRequest:[[[NSURLRequest alloc] init] autorelease]];
+ break;
+ case Command::Response:
+ [task didReceiveResponse:[[[NSURLResponse alloc] init] autorelease]];
+ break;
+ case Command::Data:
+ [task didReceiveData:[[[NSData alloc] init] autorelease]];
+ break;
+ case Command::Finish:
+ [task didFinish];
+ break;
+ case Command::Error:
+ [task didFailWithError:[[[NSError alloc] init] autorelease]];
+ break;
+ }
+ }
+ }
+ @catch(NSException *exception)
+ {
+ caughtException = true;
+ }
+ ASSERT_EQ(caughtException, expectedException);
+ done = true;
+}
+
+- (void)webView:(WKWebView *)webView stopURLSchemeTask:(id <WKURLSchemeTask>)task
+{
+}
+@end
+
+enum class ShouldRaiseException { No, Yes };
+
+static void checkCallSequence(Vector<Command>&& commands, ShouldRaiseException shouldRaiseException)
+{
+ done = false;
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ auto handler = adoptNS([[TaskSchemeHandler alloc] initWithCommands:WTFMove(commands) expectedException:shouldRaiseException == ShouldRaiseException::Yes]);
+ [configuration setURLSchemeHandler:handler.get() forURLScheme:@"testing"];
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"testing:///initial"]]];
+ TestWebKitAPI::Util::run(&done);
+}
+
+TEST(URLSchemeHandler, Exceptions)
+{
+ checkCallSequence({Command::Response, Command::Data, Command::Finish}, ShouldRaiseException::No);
+ checkCallSequence({Command::Response, Command::Redirect}, ShouldRaiseException::Yes);
+ checkCallSequence({Command::Redirect, Command::Response}, ShouldRaiseException::No);
+ checkCallSequence({Command::Data, Command::Finish}, ShouldRaiseException::Yes);
+ checkCallSequence({Command::Error}, ShouldRaiseException::No);
+ checkCallSequence({Command::Error, Command::Error}, ShouldRaiseException::Yes);
+ checkCallSequence({Command::Error, Command::Data}, ShouldRaiseException::Yes);
+ checkCallSequence({Command::Response, Command::Finish, Command::Data}, ShouldRaiseException::Yes);
+ checkCallSequence({Command::Response, Command::Finish, Command::Redirect}, ShouldRaiseException::Yes);
+ checkCallSequence({Command::Response, Command::Finish, Command::Response}, ShouldRaiseException::Yes);
+ checkCallSequence({Command::Response, Command::Finish, Command::Finish}, ShouldRaiseException::Yes);
+ checkCallSequence({Command::Response, Command::Finish, Command::Error}, ShouldRaiseException::Yes);
+}
+
#endif