https://bugs.webkit.org/show_bug.cgi?id=176481
<rdar://problem/
34309065>
Reviewed by Geoffrey Garen.
Source/WebKit:
Notify client when downloads are redirected via both ObjC and C
API.
* NetworkProcess/Downloads/Download.cpp:
(WebKit::Download::willSendRedirectedRequest):
* NetworkProcess/Downloads/Download.h:
* NetworkProcess/Downloads/mac/DownloadMac.mm:
(-[WKDownloadAsDelegate download:willSendRequest:redirectResponse:]):
* UIProcess/API/APIDownloadClient.h:
(API::DownloadClient::willSendRequest):
* UIProcess/API/C/WKContext.cpp:
(WKContextSetDownloadClient):
* UIProcess/API/C/WKContextDownloadClient.h:
* UIProcess/API/Cocoa/_WKDownloadDelegate.h:
* UIProcess/Cocoa/DownloadClient.h:
* UIProcess/Cocoa/DownloadClient.mm:
(WebKit::DownloadClient::DownloadClient):
(WebKit::DownloadClient::willSendRequest):
* UIProcess/Downloads/DownloadProxy.cpp:
(WebKit::DownloadProxy::willSendRequest):
* UIProcess/Downloads/DownloadProxy.h:
* UIProcess/Downloads/DownloadProxy.messages.in:
* UIProcess/mac/WebContextMenuProxyMac.mm:
(WebKit::WebContextMenuProxyMac::showContextMenuWithItems):
Set menu proxy before calling menuFromProposedMenu() client delegate.
This allows me to perform one of the menu item's action from the
menuFromProposedMenu() client delegate in my API test.
Tools:
* TestWebKitAPI/Tests/WebKitCocoa/Download.mm:
(-[UIDownloadAsFileTestDelegate _webView:contextMenu:forElement:]):
(-[RedirectedDownloadDelegate _download:decideDestinationWithSuggestedFilename:allowOverwrite:]):
(-[RedirectedDownloadDelegate _download:didReceiveServerRedirectToURL:]):
(-[RedirectedDownloadDelegate _downloadDidFinish:]):
(TEST):
Add API test coverage.
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::createWebViewWithOptions):
(WTR::TestController::downloadDidReceiveServerRedirectToURL):
* WebKitTestRunner/TestController.h:
Add layout test infrastructure.
LayoutTests:
Add layout test coverage.
* http/tests/download/anchor-download-redirect-expected.txt: Added.
* http/tests/download/anchor-download-redirect.html: Added.
* platform/ios-wk2/TestExpectations:
* platform/mac-wk1/TestExpectations:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221749
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2017-09-07 Chris Dumez <cdumez@apple.com>
+
+ [WK2] Notify client when downloads are redirected
+ https://bugs.webkit.org/show_bug.cgi?id=176481
+ <rdar://problem/34309065>
+
+ Reviewed by Geoffrey Garen.
+
+ Add layout test coverage.
+
+ * http/tests/download/anchor-download-redirect-expected.txt: Added.
+ * http/tests/download/anchor-download-redirect.html: Added.
+ * platform/ios-wk2/TestExpectations:
+ * platform/mac-wk1/TestExpectations:
+
2017-09-07 Per Arne Vollan <pvollan@apple.com>
Marked imported/w3c/web-platform-tests/html/semantics/embedded-content/the-iframe-element/cross_origin_parentage.html as slow.
--- /dev/null
+Download started.
+Download was redirected to "http://127.0.0.1:8000/media/resources/test.pdf".
+Downloading URL with suggested filename "foo.pdf"
+Download completed.
+Tests that download redirects are reported to the client. the link.
+
+The suggested filename at the top should be foo.pdf and you should see a redirect to /media/resources/test.pdf.
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.setShouldLogDownloadCallbacks(true);
+ testRunner.waitUntilDownloadFinished();
+ }
+</script>
+</head>
+<body>
+<p>
+Tests that download redirects are reported to the client.
+<a id="dl" href="/resources/redirect.php?url=/media/resources/test.pdf" download="foo.pdf">the link</a>.
+<p>
+The suggested filename at the top should be foo.pdf and you should see a redirect to /media/resources/test.pdf.
+<script>
+ function click(elmt)
+ {
+ if (!window.eventSender)
+ return;
+
+ eventSender.mouseMoveTo(elmt.offsetLeft + 5, elmt.offsetTop + 5);
+ eventSender.mouseDown();
+ eventSender.mouseUp();
+ }
+
+ function runTest()
+ {
+ var link = document.getElementById("dl");
+ click(link);
+ }
+ runTest();
+</script>
+</body>
+</html>
webkit.org/b/156067 fast/dom/HTMLAnchorElement/anchor-download-user-triggered-synthetic-click.html [ Skip ]
webkit.org/b/156067 http/tests/download/anchor-download-attribute-content-disposition.html [ Skip ]
webkit.org/b/156067 http/tests/download/anchor-download-no-extension.html [ Skip ]
+webkit.org/b/156067 http/tests/download/anchor-download-redirect.html [ Skip ]
webkit.org/b/156067 http/tests/download/area-download.html [ Skip ]
webkit.org/b/156067 http/tests/security/anchor-download-allow-blob.html [ Skip ]
webkit.org/b/156067 http/tests/security/anchor-download-allow-data.html [ Skip ]
webkit.org/b/156069 fast/dom/HTMLAnchorElement/anchor-file-blob-download-no-extension.html [ Skip ]
webkit.org/b/156069 http/tests/download/anchor-download-attribute-content-disposition.html [ Skip ]
webkit.org/b/156069 http/tests/download/anchor-download-no-extension.html [ Skip ]
+webkit.org/b/156069 http/tests/download/anchor-download-redirect.html [ Skip ]
webkit.org/b/156069 http/tests/download/area-download.html [ Skip ]
webkit.org/b/156069 http/tests/security/anchor-download-allow-blob.html [ Skip ]
webkit.org/b/156069 http/tests/security/anchor-download-allow-data.html [ Skip ]
+2017-09-07 Chris Dumez <cdumez@apple.com>
+
+ [WK2] Notify client when downloads are redirected
+ https://bugs.webkit.org/show_bug.cgi?id=176481
+ <rdar://problem/34309065>
+
+ Reviewed by Geoffrey Garen.
+
+ Notify client when downloads are redirected via both ObjC and C
+ API.
+
+ * NetworkProcess/Downloads/Download.cpp:
+ (WebKit::Download::willSendRedirectedRequest):
+ * NetworkProcess/Downloads/Download.h:
+ * NetworkProcess/Downloads/mac/DownloadMac.mm:
+ (-[WKDownloadAsDelegate download:willSendRequest:redirectResponse:]):
+ * UIProcess/API/APIDownloadClient.h:
+ (API::DownloadClient::willSendRequest):
+ * UIProcess/API/C/WKContext.cpp:
+ (WKContextSetDownloadClient):
+ * UIProcess/API/C/WKContextDownloadClient.h:
+ * UIProcess/API/Cocoa/_WKDownloadDelegate.h:
+ * UIProcess/Cocoa/DownloadClient.h:
+ * UIProcess/Cocoa/DownloadClient.mm:
+ (WebKit::DownloadClient::DownloadClient):
+ (WebKit::DownloadClient::willSendRequest):
+ * UIProcess/Downloads/DownloadProxy.cpp:
+ (WebKit::DownloadProxy::willSendRequest):
+ * UIProcess/Downloads/DownloadProxy.h:
+ * UIProcess/Downloads/DownloadProxy.messages.in:
+
+ * UIProcess/mac/WebContextMenuProxyMac.mm:
+ (WebKit::WebContextMenuProxyMac::showContextMenuWithItems):
+ Set menu proxy before calling menuFromProposedMenu() client delegate.
+ This allows me to perform one of the menu item's action from the
+ menuFromProposedMenu() client delegate in my API test.
+
2017-09-07 Alex Christensen <achristensen@webkit.org>
Modernize Geolocation code
send(Messages::DownloadProxy::DidStart(m_request, m_suggestedName));
}
+void Download::willSendRedirectedRequest(WebCore::ResourceRequest&& redirectRequest, WebCore::ResourceResponse&& redirectResponse)
+{
+ send(Messages::DownloadProxy::WillSendRequest(WTFMove(redirectRequest), WTFMove(redirectResponse)));
+}
+
void Download::didReceiveAuthenticationChallenge(const AuthenticationChallenge& authenticationChallenge)
{
m_downloadManager.downloadsAuthenticationManager().didReceiveAuthenticationChallenge(*this, authenticationChallenge);
class Credential;
class ResourceError;
class ResourceHandle;
+class ResourceRequest;
class ResourceResponse;
}
const WebCore::ResourceRequest& request() const { return m_request; }
void didReceiveAuthenticationChallenge(const WebCore::AuthenticationChallenge&);
void didStart();
+ void willSendRedirectedRequest(WebCore::ResourceRequest&&, WebCore::ResourceResponse&&);
void didReceiveResponse(const WebCore::ResourceResponse&);
bool shouldDecodeSourceDataOfMIMEType(const String& mimeType);
String decideDestinationWithSuggestedFilename(const String& filename, bool& allowOverwrite);
- (NSURLRequest *)download:(NSURLDownload *)download willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse
{
+ dispatchOnMainThread(^ {
+ if (_download && redirectResponse)
+ _download->willSendRedirectedRequest(request, redirectResponse);
+ });
return request;
}
virtual void didCancel(WebKit::WebProcessPool*, WebKit::DownloadProxy*) { }
virtual void processDidCrash(WebKit::WebProcessPool*, WebKit::DownloadProxy*) { }
virtual bool canAuthenticateAgainstProtectionSpace(WebKit::WebProtectionSpace*) { return true; }
- virtual void willSendRequest(const WebCore::ResourceRequest& request, const WebCore::ResourceResponse&, WTF::Function<void(const WebCore::ResourceRequest&)>&& callback) { callback(request); }
+ virtual void willSendRequest(WebKit::WebProcessPool*, WebKit::DownloadProxy*, const WebCore::ResourceRequest& request, const WebCore::ResourceResponse&, WTF::Function<void(const WebCore::ResourceRequest&)>&& callback) { callback(request); }
};
} // namespace API
namespace API {
template<> struct ClientTraits<WKContextDownloadClientBase> {
- typedef std::tuple<WKContextDownloadClientV0> Versions;
+ typedef std::tuple<WKContextDownloadClientV0, WKContextDownloadClientV1> Versions;
};
template<> struct ClientTraits<WKContextHistoryClientBase> {
typedef std::tuple<WKContextHistoryClientV0> Versions;
m_client.processDidCrash(toAPI(processPool), toAPI(downloadProxy), m_client.base.clientInfo);
}
+ void willSendRequest(WebProcessPool* processPool, DownloadProxy* downloadProxy, const ResourceRequest& request, const ResourceResponse&, WTF::Function<void(const ResourceRequest&)>&& callback) override
+ {
+ if (m_client.didReceiveServerRedirect)
+ m_client.didReceiveServerRedirect(toAPI(processPool), toAPI(downloadProxy), toURLRef(request.url().string().impl()), m_client.base.clientInfo);
+
+ callback(request);
+ }
+
+
};
toImpl(contextRef)->setDownloadClient(std::make_unique<DownloadClient>(wkClient));
typedef void (*WKContextDownloadDidFailCallback)(WKContextRef context, WKDownloadRef download, WKErrorRef error, const void *clientInfo);
typedef void (*WKContextDownloadDidCancel)(WKContextRef context, WKDownloadRef download, const void *clientInfo);
typedef void (*WKContextDownloadProcessDidCrashCallback)(WKContextRef context, WKDownloadRef download, const void *clientInfo);
+typedef void (*WKContextDownloadDidReceiveServerRedirect)(WKContextRef context, WKDownloadRef download, WKURLRef url, const void *clientInfo);
typedef struct WKContextDownloadClientBase {
int version;
WKContextDownloadProcessDidCrashCallback processDidCrash;
} WKContextDownloadClientV0;
+typedef struct WKContextDownloadClientV1 {
+ WKContextDownloadClientBase base;
+
+ // Version 0.
+ WKContextDownloadDidStartCallback didStart;
+ WKContextDownloadDidReceiveAuthenticationChallengeCallback didReceiveAuthenticationChallenge;
+ WKContextDownloadDidReceiveResponseCallback didReceiveResponse;
+ WKContextDownloadDidReceiveDataCallback didReceiveData;
+ WKContextDownloadShouldDecodeSourceDataOfMIMETypeCallback shouldDecodeSourceDataOfMIMEType;
+ WKContextDownloadDecideDestinationWithSuggestedFilenameCallback decideDestinationWithSuggestedFilename;
+ WKContextDownloadDidCreateDestinationCallback didCreateDestination;
+ WKContextDownloadDidFinishCallback didFinish;
+ WKContextDownloadDidFailCallback didFail;
+ WKContextDownloadDidCancel didCancel;
+ WKContextDownloadProcessDidCrashCallback processDidCrash;
+
+ // Version 1.
+ WKContextDownloadDidReceiveServerRedirect didReceiveServerRedirect;
+} WKContextDownloadClientV1;
+
#endif // WKContextDownloadClient_h
@protocol _WKDownloadDelegate <NSObject>
@optional
- (void)_downloadDidStart:(_WKDownload *)download;
+- (void)_download:(_WKDownload *)download didReceiveServerRedirectToURL:(NSURL *)url WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
- (void)_download:(_WKDownload *)download didReceiveResponse:(NSURLResponse *)response;
- (void)_download:(_WKDownload *)download didReceiveData:(uint64_t)length;
- (NSString *)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename allowOverwrite:(BOOL *)allowOverwrite;
private:
// From API::DownloadClient
- virtual void didStart(WebProcessPool*, DownloadProxy*);
- virtual void didReceiveResponse(WebProcessPool*, DownloadProxy*, const WebCore::ResourceResponse&);
- virtual void didReceiveData(WebProcessPool*, DownloadProxy*, uint64_t length);
- virtual String decideDestinationWithSuggestedFilename(WebProcessPool*, DownloadProxy*, const String& filename, bool& allowOverwriteParam);
- virtual void didFinish(WebProcessPool*, DownloadProxy*);
- virtual void didFail(WebProcessPool*, DownloadProxy*, const WebCore::ResourceError&);
- virtual void didCancel(WebProcessPool*, DownloadProxy*);
+ void didStart(WebProcessPool*, DownloadProxy*) final;
+ void didReceiveResponse(WebProcessPool*, DownloadProxy*, const WebCore::ResourceResponse&) final;
+ void didReceiveData(WebProcessPool*, DownloadProxy*, uint64_t length) final;
+ String decideDestinationWithSuggestedFilename(WebProcessPool*, DownloadProxy*, const String& filename, bool& allowOverwriteParam) final;
+ void didFinish(WebProcessPool*, DownloadProxy*) final;
+ void didFail(WebProcessPool*, DownloadProxy*, const WebCore::ResourceError&) final;
+ void didCancel(WebProcessPool*, DownloadProxy*) final;
+ void willSendRequest(WebProcessPool*, DownloadProxy*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, WTF::Function<void(const WebCore::ResourceRequest&)>&&) final;
WeakObjCPtr<id <_WKDownloadDelegate>> m_delegate;
bool downloadDidFinish : 1;
bool downloadDidFail : 1;
bool downloadDidCancel : 1;
+ bool downloadDidReceiveServerRedirectToURL : 1;
} m_delegateMethods;
};
#import "_WKDownloadDelegate.h"
#import "_WKDownloadInternal.h"
#import "DownloadProxy.h"
+#import "WKNSURLExtras.h"
#import <WebCore/ResourceError.h>
#import <WebCore/ResourceResponse.h>
m_delegateMethods.downloadDidFinish = [delegate respondsToSelector:@selector(_downloadDidFinish:)];
m_delegateMethods.downloadDidFail = [delegate respondsToSelector:@selector(_download:didFailWithError:)];
m_delegateMethods.downloadDidCancel = [delegate respondsToSelector:@selector(_downloadDidCancel:)];
+ m_delegateMethods.downloadDidReceiveServerRedirectToURL = [delegate respondsToSelector:@selector(_download:didReceiveServerRedirectToURL:)];
}
void DownloadClient::didStart(WebProcessPool*, DownloadProxy* downloadProxy)
[m_delegate.get() _downloadDidCancel:wrapper(*downloadProxy)];
}
+void DownloadClient::willSendRequest(WebProcessPool*, DownloadProxy* downloadProxy, const WebCore::ResourceRequest& request, const WebCore::ResourceResponse&, WTF::Function<void(const WebCore::ResourceRequest&)>&& callback)
+{
+ if (m_delegateMethods.downloadDidReceiveServerRedirectToURL)
+ [m_delegate.get() _download:wrapper(*downloadProxy) didReceiveServerRedirectToURL:[NSURL _web_URLWithWTFString:request.url().string()]];
+
+ callback(request);
+}
+
} // namespace WebKit
#endif // WK_API_ENABLED
m_processPool->downloadClient().didReceiveAuthenticationChallenge(m_processPool.get(), this, authenticationChallengeProxy.get());
}
-#if USE(NETWORK_SESSION)
-#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
+#if USE(NETWORK_SESSION) && USE(PROTECTION_SPACE_AUTH_CALLBACK)
void DownloadProxy::canAuthenticateAgainstProtectionSpace(const ProtectionSpace& protectionSpace)
{
if (!m_processPool)
return;
RefPtr<DownloadProxy> protectedThis(this);
- m_processPool->downloadClient().willSendRequest(proposedRequest, redirectResponse, [protectedThis](const ResourceRequest& newRequest) {
+ m_processPool->downloadClient().willSendRequest(m_processPool.get(), this, proposedRequest, redirectResponse, [protectedThis](const ResourceRequest& newRequest) {
+#if USE(NETWORK_SESSION)
if (!protectedThis->m_processPool)
return;
-
+
auto* networkProcessProxy = protectedThis->m_processPool->networkProcess();
if (!networkProcessProxy)
return;
-
+
networkProcessProxy->send(Messages::NetworkProcess::ContinueWillSendRequest(protectedThis->m_downloadID, newRequest), 0);
+#else
+ UNUSED_PARAM(newRequest);
+#endif
});
}
-#endif
void DownloadProxy::didReceiveResponse(const ResourceResponse& response)
{
void didFinish();
void didFail(const WebCore::ResourceError&, const IPC::DataReference& resumeData);
void didCancel(const IPC::DataReference& resumeData);
+ void willSendRequest(const WebCore::ResourceRequest& redirectRequest, const WebCore::ResourceResponse& redirectResponse);
#if USE(NETWORK_SESSION)
#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
void canAuthenticateAgainstProtectionSpace(const WebCore::ProtectionSpace&);
#endif
- void willSendRequest(const WebCore::ResourceRequest& redirectRequest, const WebCore::ResourceResponse& redirectResponse);
#else
void decideDestinationWithSuggestedFilename(const String& filename, const String& mimeType, String& destination, bool& allowOverwrite, SandboxExtension::Handle& sandboxExtensionHandle);
#endif
messages -> DownloadProxy {
DidStart(WebCore::ResourceRequest request, AtomicString suggestedFilename)
DidReceiveAuthenticationChallenge(WebCore::AuthenticationChallenge challenge, uint64_t challengeID)
-#if USE(NETWORK_SESSION)
WillSendRequest(WebCore::ResourceRequest redirectRequest, WebCore::ResourceResponse redirectResponse))
+#if USE(NETWORK_SESSION)
#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
CanAuthenticateAgainstProtectionSpace(WebCore::ProtectionSpace protectionSpace)
#endif
void WebContextMenuProxyMac::showContextMenuWithItems(const Vector<WebContextMenuItemData>& items)
{
auto menu = createContextMenuFromItems(items);
- m_menu = m_page.contextMenuClient().menuFromProposedMenu(m_page, menu.get(), m_context.webHitTestResultData(), m_userData.object());
-
[[WKMenuTarget sharedMenuTarget] setMenuProxy:this];
+ m_menu = m_page.contextMenuClient().menuFromProposedMenu(m_page, menu.get(), m_context.webHitTestResultData(), m_userData.object());
NSPoint menuLocation = [m_webView convertPoint:m_context.menuLocation() toView:nil];
NSEvent *event = [NSEvent mouseEventWithType:NSEventTypeRightMouseUp location:menuLocation modifierFlags:0 timestamp:0 windowNumber:m_webView.window.windowNumber context:nil eventNumber:0 clickCount:0 pressure:0];
+2017-09-07 Chris Dumez <cdumez@apple.com>
+
+ [WK2] Notify client when downloads are redirected
+ https://bugs.webkit.org/show_bug.cgi?id=176481
+ <rdar://problem/34309065>
+
+ Reviewed by Geoffrey Garen.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/Download.mm:
+ (-[UIDownloadAsFileTestDelegate _webView:contextMenu:forElement:]):
+ (-[RedirectedDownloadDelegate _download:decideDestinationWithSuggestedFilename:allowOverwrite:]):
+ (-[RedirectedDownloadDelegate _download:didReceiveServerRedirectToURL:]):
+ (-[RedirectedDownloadDelegate _downloadDidFinish:]):
+ (TEST):
+ Add API test coverage.
+
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::createWebViewWithOptions):
+ (WTR::TestController::downloadDidReceiveServerRedirectToURL):
+ * WebKitTestRunner/TestController.h:
+ Add layout test infrastructure.
+
2017-09-07 Per Arne Vollan <pvollan@apple.com>
[Win] fast/canvas/2d.getPath.modification.html is failing.
#import "PlatformUtilities.h"
#import "Test.h"
+#import "TestProtocol.h"
+#import "TestWKWebView.h"
#import <WebCore/FileSystem.h>
#import <WebKit/_WKDownload.h>
#import <WebKit/_WKDownloadDelegate.h>
#import <WebKit/WKNavigationDelegatePrivate.h>
#import <WebKit/WKProcessPoolPrivate.h>
+#import <WebKit/WKUIDelegatePrivate.h>
#import <WebKit/WKWebView.h>
#import <WebKit/WKWebViewConfiguration.h>
#import <wtf/RetainPtr.h>
+#import <wtf/mac/AppKitCompatibilityDeclarations.h>
#import <wtf/text/WTFString.h>
static bool isDone;
+static bool hasReceivedRedirect;
static bool hasReceivedResponse;
static NSURL *sourceURL = [[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
runTest(adoptNS([[DownloadBlobURLNavigationDelegate alloc] init]).get(), adoptNS([[BlobDownloadDelegate alloc] init]).get(), originalURL);
}
+@interface UIDownloadAsFileTestDelegate : NSObject <WKUIDelegatePrivate>
+@end
+
+@implementation UIDownloadAsFileTestDelegate
+
+- (NSMenu *)_webView:(WKWebView *)webView contextMenu:(NSMenu *)menu forElement:(_WKContextMenuElementInfo *)element
+{
+ static const long downloadLinkedFileTag = 2;
+ auto index = [menu indexOfItemWithTag:downloadLinkedFileTag];
+ [menu performActionForItemAtIndex:index];
+ return nil;
+}
+
+@end
+
+@interface RedirectedDownloadDelegate : NSObject <_WKDownloadDelegate>
+@end
+
+@implementation RedirectedDownloadDelegate {
+ String _destinationPath;
+}
+
+- (NSString *)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename allowOverwrite:(BOOL *)allowOverwrite
+{
+ WebCore::PlatformFileHandle fileHandle;
+ _destinationPath = WebCore::openTemporaryFile("TestWebKitAPI", fileHandle);
+ EXPECT_TRUE(fileHandle != WebCore::invalidPlatformFileHandle);
+ WebCore::closeFile(fileHandle);
+ *allowOverwrite = YES;
+ return _destinationPath;
+}
+
+- (void)_download:(_WKDownload *)download didReceiveServerRedirectToURL:(NSURL *)url
+{
+ EXPECT_STREQ("http://pass/", [url.absoluteString UTF8String]);
+ hasReceivedRedirect = true;
+}
+
+- (void)_downloadDidFinish:(_WKDownload *)download
+{
+ WebCore::deleteFile(_destinationPath);
+ isDone = true;
+}
+
+@end
+
+TEST(_WKDownload, RedirectedDownload)
+{
+ [TestProtocol registerWithScheme:@"http"];
+
+ hasReceivedRedirect = false;
+ isDone = false;
+
+ auto delegate = adoptNS([[UIDownloadAsFileTestDelegate alloc] init]);
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
+ [webView setUIDelegate:delegate.get()];
+ auto downloadDelegate = adoptNS([[RedirectedDownloadDelegate alloc] init]);
+ [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];
+
+ auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
+ [[window contentView] addSubview:webView.get()];
+
+ [webView synchronouslyLoadHTMLString:@"<a style='display: block; height: 100%; width: 100%' href='http://redirect/?pass'>test</a>"];
+
+ NSPoint clickPoint = NSMakePoint(100, 100);
+ [[webView hitTest:clickPoint] mouseDown:[NSEvent mouseEventWithType:NSEventTypeRightMouseDown location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
+ [[webView hitTest:clickPoint] mouseUp:[NSEvent mouseEventWithType:NSEventTypeRightMouseUp location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
+
+ isDone = false;
+ TestWebKitAPI::Util::run(&isDone);
+ EXPECT_TRUE(hasReceivedRedirect);
+
+ [TestProtocol unregister];
+}
+
#endif
#endif
};
WKPageSetPageNavigationClient(m_mainWebView->page(), &pageNavigationClient.base);
- WKContextDownloadClientV0 downloadClient = {
- { 0, this },
+ WKContextDownloadClientV1 downloadClient = {
+ { 1, this },
downloadDidStart,
0, // didReceiveAuthenticationChallenge
0, // didReceiveResponse
downloadDidFinish,
downloadDidFail,
downloadDidCancel,
- 0 // processDidCrash;
+ 0, // processDidCrash;
+ downloadDidReceiveServerRedirectToURL
};
WKContextSetDownloadClient(context(), &downloadClient.base);
static_cast<TestController*>(const_cast<void*>(clientInfo))->downloadDidCancel(context, download);
}
+void TestController::downloadDidReceiveServerRedirectToURL(WKContextRef context, WKDownloadRef download, WKURLRef url, const void* clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->downloadDidReceiveServerRedirectToURL(context, download, url);
+}
+
void TestController::downloadDidStart(WKContextRef context, WKDownloadRef download)
{
if (m_shouldLogDownloadCallbacks)
m_currentInvocation->notifyDownloadDone();
}
+void TestController::downloadDidReceiveServerRedirectToURL(WKContextRef, WKDownloadRef, WKURLRef url)
+{
+ if (m_shouldLogDownloadCallbacks) {
+ StringBuilder builder;
+ builder.appendLiteral("Download was redirected to \"");
+ WKRetainPtr<WKStringRef> urlStringWK = adoptWK(WKURLCopyString(url));
+ builder.append(toSTD(urlStringWK).c_str());
+ builder.appendLiteral("\".\n");
+ m_currentInvocation->outputText(builder.toString());
+ }
+}
+
void TestController::downloadDidFail(WKContextRef, WKDownloadRef, WKErrorRef error)
{
if (m_shouldLogDownloadCallbacks) {
void downloadDidFail(WKContextRef, WKDownloadRef, WKErrorRef);
static void downloadDidCancel(WKContextRef, WKDownloadRef, const void*);
void downloadDidCancel(WKContextRef, WKDownloadRef);
+ static void downloadDidReceiveServerRedirectToURL(WKContextRef, WKDownloadRef, WKURLRef, const void*);
+ void downloadDidReceiveServerRedirectToURL(WKContextRef, WKDownloadRef, WKURLRef);
static void processDidCrash(WKPageRef, const void* clientInfo);
void processDidCrash();