/*
 * Copyright (C) 2014-2020 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 "config.h"
#import <WebKit/WKFoundation.h>

#import "HTTPServer.h"
#import "PlatformUtilities.h"
#import "Test.h"
#import "TestDownloadDelegate.h"
#import "TestLegacyDownloadDelegate.h"
#import "TestNavigationDelegate.h"
#import "TestProtocol.h"
#import "TestWKWebView.h"
#import <Foundation/NSURLResponse.h>
#import <WebKit/WKDownload.h>
#import <WebKit/WKErrorPrivate.h>
#import <WebKit/WKNavigationDelegatePrivate.h>
#import <WebKit/WKNavigationResponsePrivate.h>
#import <WebKit/WKProcessPoolPrivate.h>
#import <WebKit/WKUIDelegatePrivate.h>
#import <WebKit/WKWebView.h>
#import <WebKit/WKWebViewConfiguration.h>
#import <WebKit/WKWebViewConfigurationPrivate.h>
#import <WebKit/WKWebsiteDataStorePrivate.h>
#import <WebKit/_WKDownload.h>
#import <WebKit/_WKDownloadDelegate.h>
#import <WebKit/_WKProcessPoolConfiguration.h>
#import <WebKit/_WKWebsiteDataStoreConfiguration.h>
#import <wtf/BlockPtr.h>
#import <wtf/FileSystem.h>
#import <wtf/MainThread.h>
#import <wtf/MonotonicTime.h>
#import <wtf/RetainPtr.h>
#import <wtf/WeakObjCPtr.h>
#import <wtf/text/WTFString.h>

static bool isDone;
static unsigned redirectCount = 0;
static bool hasReceivedResponse;
static NSURL *sourceURL = [[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
static WKWebView* expectedOriginatingWebView;
static bool expectedUserInitiatedState = false;

@interface DownloadDelegate : NSObject <_WKDownloadDelegate>
@end

@implementation DownloadDelegate {
    RetainPtr<_WKDownload> _download;
    String _destinationPath;
    long long _expectedContentLength;
    uint64_t _receivedContentLength;
}

- (void)_downloadDidStart:(_WKDownload *)download
{
    EXPECT_NULL(_download);
    EXPECT_NOT_NULL(download);
    EXPECT_TRUE([[[[download request] URL] path] isEqualToString:[sourceURL path]]);
    EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
    _download = download;
}

- (void)_download:(_WKDownload *)download didReceiveResponse:(NSURLResponse *)response
{
    hasReceivedResponse = true;
    EXPECT_EQ(_download, download);
    EXPECT_TRUE(_expectedContentLength == 0);
    EXPECT_TRUE(_receivedContentLength == 0);
    EXPECT_TRUE([[[response URL] path] isEqualToString:[sourceURL path]]);
    _expectedContentLength = [response expectedContentLength];
}

- (void)_download:(_WKDownload *)download didReceiveData:(uint64_t)length
{
    EXPECT_EQ(_download, download);
    _receivedContentLength += length;
}

IGNORE_WARNINGS_BEGIN("deprecated-implementations")
- (NSString *)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename allowOverwrite:(BOOL *)allowOverwrite
IGNORE_WARNINGS_END
{
    EXPECT_TRUE(hasReceivedResponse);
    EXPECT_EQ(_download, download);

    FileSystem::PlatformFileHandle fileHandle;
    _destinationPath = FileSystem::openTemporaryFile("TestWebKitAPI", fileHandle);
    EXPECT_TRUE(fileHandle != FileSystem::invalidPlatformFileHandle);
    FileSystem::closeFile(fileHandle);

    *allowOverwrite = YES;
    return _destinationPath;
}

- (void)_downloadDidFinish:(_WKDownload *)download
{
    EXPECT_EQ(_download, download);
    EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
    EXPECT_TRUE(_expectedContentLength == NSURLResponseUnknownLength || static_cast<uint64_t>(_expectedContentLength) == _receivedContentLength);
    EXPECT_TRUE([[NSFileManager defaultManager] contentsEqualAtPath:_destinationPath andPath:[sourceURL path]]);
    FileSystem::deleteFile(_destinationPath);
    isDone = true;
}

@end

TEST(_WKDownload, DownloadDelegate)
{
    RetainPtr<WKProcessPool> processPool = adoptNS([[WKProcessPool alloc] init]);
    auto downloadDelegate = adoptNS([[DownloadDelegate alloc] init]);
    [processPool _setDownloadDelegate:downloadDelegate.get()];

    @autoreleasepool {
        EXPECT_EQ(downloadDelegate.get(), [processPool _downloadDelegate]);
    }

    downloadDelegate = nil;
    EXPECT_NULL([processPool _downloadDelegate]);
}

static void runTest(id <WKNavigationDelegate> navigationDelegate, id <_WKDownloadDelegate> downloadDelegate, NSURL *url)
{
    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
    [webView setNavigationDelegate:navigationDelegate];
    [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate];

    isDone = false;
    hasReceivedResponse = false;
    expectedUserInitiatedState = false;
    [webView loadRequest:[NSURLRequest requestWithURL:url]];
    TestWebKitAPI::Util::run(&isDone);
}

@interface DownloadNavigationDelegate : NSObject <WKNavigationDelegate>
@end

@implementation DownloadNavigationDelegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    decisionHandler(_WKNavigationActionPolicyDownload);
}
@end

TEST(_WKDownload, DownloadRequest)
{
    runTest(adoptNS([[DownloadNavigationDelegate alloc] init]).get(), adoptNS([[DownloadDelegate alloc] init]).get(), sourceURL);
}

@interface ConvertResponseToDownloadNavigationDelegate : NSObject <WKNavigationDelegate>
@end

@implementation ConvertResponseToDownloadNavigationDelegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
    decisionHandler(WKNavigationResponsePolicyDownload);
}
@end

TEST(_WKDownload, ConvertResponseToDownload)
{
    runTest(adoptNS([[ConvertResponseToDownloadNavigationDelegate alloc] init]).get(), adoptNS([[DownloadDelegate alloc] init]).get(), sourceURL);
}

@interface FailingDownloadDelegate : NSObject <_WKDownloadDelegate>
@end

@implementation FailingDownloadDelegate

- (void)_downloadDidFinish:(_WKDownload *)download
{
    EXPECT_TRUE(false);
    isDone = true;
}

- (void)_download:(_WKDownload *)download didFailWithError:(NSError *)error
{
    isDone = true;
}

- (void)_downloadDidCancel:(_WKDownload *)download
{
    EXPECT_TRUE(false);
    isDone = true;
}

@end

TEST(_WKDownload, DownloadMissingResource)
{
    runTest(adoptNS([[DownloadNavigationDelegate alloc] init]).get(), adoptNS([[FailingDownloadDelegate alloc] init]).get(), [NSURL URLWithString:@"non-existant-scheme://"]);
}

@interface CancelledDownloadDelegate : NSObject <_WKDownloadDelegate>
@end

@implementation CancelledDownloadDelegate

- (void)_downloadDidStart:(_WKDownload *)download
{
    [download cancel];
}

- (void)_downloadDidFinish:(_WKDownload *)download
{
    EXPECT_TRUE(false);
    isDone = true;
}

- (void)_download:(_WKDownload *)download didFailWithError:(NSError *)error
{
    EXPECT_TRUE(false);
    isDone = true;
}

- (void)_downloadDidCancel:(_WKDownload *)download
{
    isDone = true;
}

@end

TEST(_WKDownload, CancelDownload)
{
    runTest(adoptNS([[DownloadNavigationDelegate alloc] init]).get(), adoptNS([[CancelledDownloadDelegate alloc] init]).get(), sourceURL);
}

@interface OriginatingWebViewDownloadDelegate : NSObject <_WKDownloadDelegate>
- (instancetype)initWithWebView:(WKWebView *)webView;
@end

@implementation OriginatingWebViewDownloadDelegate {
    RetainPtr<WKWebView> _webView;
}

- (instancetype)initWithWebView:(WKWebView *)webView
{
    if (!(self = [super init]))
        return nil;

    _webView = webView;
    return self;
}

- (void)_downloadDidStart:(_WKDownload *)download
{
    EXPECT_EQ([download originatingWebView], _webView);
    [_webView _killWebContentProcessAndResetState];
    _webView = nullptr;

    WTF::callOnMainThread([download = retainPtr(download)] {
        EXPECT_NULL([download originatingWebView]);
        isDone = true;
    });
}

@end

TEST(_WKDownload, OriginatingWebView)
{
    RetainPtr<DownloadNavigationDelegate> navigationDelegate = adoptNS([[DownloadNavigationDelegate alloc] init]);                 
    RetainPtr<OriginatingWebViewDownloadDelegate> downloadDelegate;
    @autoreleasepool {
        RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
        [webView setNavigationDelegate:navigationDelegate.get()];
        downloadDelegate = adoptNS([[OriginatingWebViewDownloadDelegate alloc] initWithWebView:webView.get()]);
        [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];
        [webView loadRequest:[NSURLRequest requestWithURL:sourceURL]];
    }

    isDone = false;
    TestWebKitAPI::Util::run(&isDone);
}

@interface DownloadRequestOriginalURLDelegate : NSObject <_WKDownloadDelegate>
- (instancetype)initWithExpectedOriginalURL:(NSURL *)expectOriginalURL;
@end

@implementation DownloadRequestOriginalURLDelegate {
    NSURL *_expectedOriginalURL;
}

- (instancetype)initWithExpectedOriginalURL:(NSURL *)expectedOriginalURL
{
    if (!(self = [super init]))
        return nil;

    _expectedOriginalURL = expectedOriginalURL;
    return self;
}

- (void)_downloadDidStart:(_WKDownload *)download
{
    if ([_expectedOriginalURL isEqual:sourceURL])
        EXPECT_TRUE(!download.request.mainDocumentURL);
    else
        EXPECT_TRUE([_expectedOriginalURL isEqual:download.request.mainDocumentURL]);
    isDone = true;
}

@end

@interface DownloadRequestOriginalURLNavigationDelegate : NSObject <WKNavigationDelegate>
@end

@implementation DownloadRequestOriginalURLNavigationDelegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    if ([navigationAction.request.URL isEqual:sourceURL])
        decisionHandler(_WKNavigationActionPolicyDownload);
    else
        decisionHandler(WKNavigationActionPolicyAllow);
}
@end

TEST(_WKDownload, DownloadRequestOriginalURL)
{
    NSURL *originalURL = [[NSBundle mainBundle] URLForResource:@"DownloadRequestOriginalURL" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
    runTest(adoptNS([[DownloadRequestOriginalURLNavigationDelegate alloc] init]).get(), adoptNS([[DownloadRequestOriginalURLDelegate alloc] initWithExpectedOriginalURL:originalURL]).get(), originalURL);
}

TEST(_WKDownload, DownloadRequestOriginalURLFrame)
{
    NSURL *originalURL = [[NSBundle mainBundle] URLForResource:@"DownloadRequestOriginalURL2" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
    runTest(adoptNS([[DownloadRequestOriginalURLNavigationDelegate alloc] init]).get(), adoptNS([[DownloadRequestOriginalURLDelegate alloc] initWithExpectedOriginalURL:originalURL]).get(), originalURL);
}

TEST(_WKDownload, DownloadRequestOriginalURLDirectDownload)
{
    runTest(adoptNS([[DownloadRequestOriginalURLNavigationDelegate alloc] init]).get(), adoptNS([[DownloadRequestOriginalURLDelegate alloc] initWithExpectedOriginalURL:sourceURL]).get(), sourceURL);
}

TEST(_WKDownload, DownloadRequestOriginalURLDirectDownloadWithLoadedContent)
{
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
    auto navigationDelegate = adoptNS([[DownloadRequestOriginalURLNavigationDelegate alloc] init]);
    [webView setNavigationDelegate:navigationDelegate.get()];
    auto downloadDelegate = adoptNS([[DownloadRequestOriginalURLDelegate alloc] initWithExpectedOriginalURL:sourceURL]);
    [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];

    expectedUserInitiatedState = false;
    NSURL *contentURL = [[NSBundle mainBundle] URLForResource:@"simple2" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
    // Here is to test if the original URL can be set correctly when the current document
    // is completely unrelated to the download.
    [webView loadRequest:[NSURLRequest requestWithURL:contentURL]];
    [webView loadRequest:[NSURLRequest requestWithURL:sourceURL]];
    isDone = false;
    TestWebKitAPI::Util::run(&isDone);
}

@interface BlobDownloadDelegate : NSObject <_WKDownloadDelegate>
@end

@implementation BlobDownloadDelegate {
    RetainPtr<_WKDownload> _download;
    String _destinationPath;
    long long _expectedContentLength;
    uint64_t _receivedContentLength;
}

- (void)_downloadDidStart:(_WKDownload *)download
{
    EXPECT_NULL(_download);
    EXPECT_NOT_NULL(download);
    EXPECT_TRUE([[[[download request] URL] scheme] isEqualToString:@"blob"]);
    EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
    _download = download;
}

- (void)_download:(_WKDownload *)download didReceiveResponse:(NSURLResponse *)response
{
    hasReceivedResponse = true;
    EXPECT_EQ(_download, download);
    EXPECT_EQ(_expectedContentLength, 0U);
    EXPECT_EQ(_receivedContentLength, 0U);
    EXPECT_TRUE([[[response URL] scheme] isEqualToString:@"blob"]);
    _expectedContentLength = [response expectedContentLength];
}

- (void)_download:(_WKDownload *)download didReceiveData:(uint64_t)length
{
    EXPECT_EQ(_download, download);
    _receivedContentLength += length;
}

IGNORE_WARNINGS_BEGIN("deprecated-implementations")
- (NSString *)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename allowOverwrite:(BOOL *)allowOverwrite
IGNORE_WARNINGS_END
{
    EXPECT_TRUE(hasReceivedResponse);
    EXPECT_EQ(_download, download);

    FileSystem::PlatformFileHandle fileHandle;
    _destinationPath = FileSystem::openTemporaryFile("TestWebKitAPI", fileHandle);
    EXPECT_TRUE(fileHandle != FileSystem::invalidPlatformFileHandle);
    FileSystem::closeFile(fileHandle);

    *allowOverwrite = YES;
    return _destinationPath;
}

- (void)_downloadDidFinish:(_WKDownload *)download
{
    EXPECT_EQ(_download, download);
    EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
    EXPECT_TRUE(_expectedContentLength == NSURLResponseUnknownLength || static_cast<uint64_t>(_expectedContentLength) == _receivedContentLength);
    NSString* expectedContent = @"{\"x\":42,\"s\":\"hello, world\"}";
    NSData* expectedData = [expectedContent dataUsingEncoding:NSUTF8StringEncoding];
    EXPECT_TRUE([[[NSFileManager defaultManager] contentsAtPath:_destinationPath] isEqualToData:expectedData]);
    FileSystem::deleteFile(_destinationPath);
    isDone = true;
}

@end

@interface DownloadBlobURLNavigationDelegate : NSObject <WKNavigationDelegate>
@end

@implementation DownloadBlobURLNavigationDelegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    if ([navigationAction.request.URL.scheme isEqualToString:@"blob"])
        decisionHandler(_WKNavigationActionPolicyDownload);
    else
        decisionHandler(WKNavigationActionPolicyAllow);
}
@end

TEST(_WKDownload, DownloadRequestBlobURL)
{
    NSURL *originalURL = [[NSBundle mainBundle] URLForResource:@"DownloadRequestBlobURL" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
    runTest(adoptNS([[DownloadBlobURLNavigationDelegate alloc] init]).get(), adoptNS([[BlobDownloadDelegate alloc] init]).get(), originalURL);
}

@interface RedirectedDownloadDelegate : NSObject <_WKDownloadDelegate>
@end

@implementation RedirectedDownloadDelegate {
    String _destinationPath;
}

- (void)_downloadDidStart:(_WKDownload *)download
{
    EXPECT_NOT_NULL(download);
    EXPECT_EQ(expectedOriginatingWebView, download.originatingWebView);
    EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
}

IGNORE_WARNINGS_BEGIN("deprecated-implementations")
- (NSString *)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename allowOverwrite:(BOOL *)allowOverwrite
IGNORE_WARNINGS_END
{
    FileSystem::PlatformFileHandle fileHandle;
    _destinationPath = FileSystem::openTemporaryFile("TestWebKitAPI", fileHandle);
    EXPECT_TRUE(fileHandle != FileSystem::invalidPlatformFileHandle);
    FileSystem::closeFile(fileHandle);
    *allowOverwrite = YES;
    return _destinationPath;
}

- (void)_download:(_WKDownload *)download didReceiveServerRedirectToURL:(NSURL *)url
{
    if (!redirectCount)
        EXPECT_STREQ("http://redirect/?pass", [url.absoluteString UTF8String]);
    else
        EXPECT_STREQ("http://pass/", [url.absoluteString UTF8String]);
    ++redirectCount = true;
}

- (void)_downloadDidFinish:(_WKDownload *)download
{
    EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);

    NSArray<NSURL *> *redirectChain = download.redirectChain;
    EXPECT_EQ(3U, redirectChain.count);
    if (redirectChain.count > 0)
        EXPECT_STREQ("http://redirect/?redirect/?pass", [redirectChain[0].absoluteString UTF8String]);
    if (redirectChain.count > 1)
        EXPECT_STREQ("http://redirect/?pass", [redirectChain[1].absoluteString UTF8String]);
    if (redirectChain.count > 2)
        EXPECT_STREQ("http://pass/", [redirectChain[2].absoluteString UTF8String]);

    FileSystem::deleteFile(_destinationPath);
    isDone = true;
}

@end

TEST(_WKDownload, RedirectedDownload)
{
    [TestProtocol registerWithScheme:@"http"];

    redirectCount = 0;
    isDone = false;

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
    auto downloadDelegate = adoptNS([[RedirectedDownloadDelegate alloc] init]);
    [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];

    // Do 2 loads in the same view to make sure the redirect chain is properly cleared between loads.
    [webView synchronouslyLoadHTMLString:@"<div>First load</div>"];
    [webView synchronouslyLoadHTMLString:@"<a id='link' href='http://redirect/?redirect/?pass'>test</a>"];

    expectedOriginatingWebView = webView.get();
    expectedUserInitiatedState = true;

    auto navigationDelegate = adoptNS([[DownloadNavigationDelegate alloc] init]);
    [webView setNavigationDelegate:navigationDelegate.get()];
    [webView objectByEvaluatingJavaScriptWithUserGesture:@"document.getElementById('link').click();"];

    isDone = false;
    TestWebKitAPI::Util::run(&isDone);
    EXPECT_EQ(1U, redirectCount);

    [TestProtocol unregister];
}

TEST(_WKDownload, RedirectedLoadConvertedToDownload)
{
    [TestProtocol registerWithScheme:@"http"];

    auto navigationDelegate = adoptNS([[ConvertResponseToDownloadNavigationDelegate alloc] init]);
    auto downloadDelegate = adoptNS([[RedirectedDownloadDelegate alloc] init]);

    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
    [webView setNavigationDelegate:navigationDelegate.get()];
    [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];

    expectedOriginatingWebView = webView.get();
    expectedUserInitiatedState = false;
    isDone = false;
    redirectCount = 0;
    hasReceivedResponse = false;
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://redirect/?redirect/?pass"]]];
    TestWebKitAPI::Util::run(&isDone);
    EXPECT_EQ(0U, redirectCount);

    [TestProtocol unregister];
}

TEST(_WKDownload, RedirectedSubframeLoadConvertedToDownload)
{
    [TestProtocol registerWithScheme:@"http"];

    auto navigationDelegate = adoptNS([[ConvertResponseToDownloadNavigationDelegate alloc] init]);
    auto downloadDelegate = adoptNS([[RedirectedDownloadDelegate alloc] init]);

    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
    [webView setNavigationDelegate:navigationDelegate.get()];
    [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];

    expectedOriginatingWebView = webView.get();
    expectedUserInitiatedState = false;
    isDone = false;
    redirectCount = 0;
    hasReceivedResponse = false;
    [webView loadHTMLString:@"<body><iframe src='http://redirect/?redirect/?pass'></iframe></body>" baseURL:nil];
    TestWebKitAPI::Util::run(&isDone);
    EXPECT_EQ(0U, redirectCount);

    [TestProtocol unregister];
}

static bool downloadHasDecidedDestination;

@interface CancelDownloadWhileDecidingDestinationDelegate : NSObject <_WKDownloadDelegate>
@end

@implementation CancelDownloadWhileDecidingDestinationDelegate
- (void)_downloadDidFinish:(_WKDownload *)download
{
    EXPECT_TRUE(false);
    isDone = true;
}

- (void)_download:(_WKDownload *)download didFailWithError:(NSError *)error
{
    EXPECT_TRUE(false);
    isDone = true;
}

- (void)_downloadDidCancel:(_WKDownload *)download
{
    isDone = true;
}

- (void)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename completionHandler:(void (^)(BOOL allowOverwrite, NSString *destination))completionHandler
{
    [download cancel];
    TestWebKitAPI::Util::run(&isDone);
    completionHandler(YES, @"/tmp/WebKitAPITest/_WKDownload");
    downloadHasDecidedDestination = true;
}
@end

TEST(_WKDownload, DownloadCanceledWhileDecidingDestination)
{
    [TestProtocol registerWithScheme:@"http"];

    auto navigationDelegate = adoptNS([[DownloadNavigationDelegate alloc] init]);
    auto downloadDelegate = adoptNS([[CancelDownloadWhileDecidingDestinationDelegate alloc] init]);

    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
    [webView setNavigationDelegate:navigationDelegate.get()];
    [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];

    isDone = false;
    downloadHasDecidedDestination = false;
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://pass"]]];

    TestWebKitAPI::Util::run(&downloadHasDecidedDestination);

    [TestProtocol unregister];
}

@interface BlobWithUSDZExtensionDownloadDelegate : NSObject <_WKDownloadDelegate>
@end

@implementation BlobWithUSDZExtensionDownloadDelegate {
    String _destinationPath;
}

- (void)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename completionHandler:(void (^)(BOOL allowOverwrite, NSString *destination))completionHandler
{
    EXPECT_TRUE([filename hasSuffix:@".usdz"]);

    FileSystem::PlatformFileHandle fileHandle;
    _destinationPath = FileSystem::openTemporaryFile(filename, fileHandle);
    EXPECT_TRUE(fileHandle != FileSystem::invalidPlatformFileHandle);
    FileSystem::closeFile(fileHandle);

    completionHandler(YES, _destinationPath);
}

- (void)_downloadDidFinish:(_WKDownload *)download
{
    FileSystem::deleteFile(_destinationPath);
    isDone = true;
}

@end

TEST(_WKDownload, SystemPreviewUSDZBlobNaming)
{
    NSURL *originalURL = [[NSBundle mainBundle] URLForResource:@"SystemPreviewBlobNaming" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
    runTest(adoptNS([[DownloadBlobURLNavigationDelegate alloc] init]).get(), adoptNS([[BlobWithUSDZExtensionDownloadDelegate alloc] init]).get(), originalURL);
}

@interface DownloadAttributeTestDelegate : NSObject <WKNavigationDelegate, _WKDownloadDelegate>
@property (nonatomic, readonly) bool didFinishNavigation;
@property (nonatomic, readonly) bool didStartProvisionalNavigation;
@property (nonatomic, readonly) bool downloadDidStart;
@property (nonatomic) WKNavigationActionPolicy navigationActionPolicy;
@end

@implementation DownloadAttributeTestDelegate

- (instancetype)init
{
    if ((self = [super init]))
        _navigationActionPolicy = WKNavigationActionPolicyAllow;

    return self;
}

- (void)waitForDidFinishNavigation
{
    TestWebKitAPI::Util::run(&_didFinishNavigation);
    _didStartProvisionalNavigation = false;
    _didFinishNavigation = false;
}

- (void)waitForDownloadDidStart
{
    TestWebKitAPI::Util::run(&_downloadDidStart);
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    _didFinishNavigation = true;
}

- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
{
    _didStartProvisionalNavigation = true;
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    decisionHandler(_navigationActionPolicy);
}

- (void)_downloadDidStart:(_WKDownload *)download
{
    _downloadDidStart = true;
}

@end

TEST(_WKDownload, DownloadAttributeDoesNotStartDownloads)
{
    auto delegate = adoptNS([[DownloadAttributeTestDelegate alloc] init]);

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    configuration.get()._allowTopNavigationToDataURLs = YES;
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    [webView setNavigationDelegate:delegate.get()];
    [webView configuration].processPool._downloadDelegate = delegate.get();

    [webView loadHTMLString:@"<a id='link' href='data:,test' download>Click me!</a>" baseURL:nil];
    [delegate waitForDidFinishNavigation];

    [webView evaluateJavaScript:@"document.getElementById('link').click();" completionHandler:nil];
    [delegate waitForDidFinishNavigation];
    EXPECT_FALSE([delegate downloadDidStart]);
}

TEST(_WKDownload, StartDownloadWithDownloadAttribute)
{
    auto delegate = adoptNS([[DownloadAttributeTestDelegate alloc] init]);

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    configuration.get()._allowTopNavigationToDataURLs = YES;
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    [webView setNavigationDelegate:delegate.get()];
    [webView configuration].processPool._downloadDelegate = delegate.get();

    [webView loadHTMLString:@"<a id='link' href='data:,test' download>Click me!</a>" baseURL:nil];
    [delegate waitForDidFinishNavigation];

    [delegate setNavigationActionPolicy:_WKNavigationActionPolicyDownload];
    [webView evaluateJavaScript:@"document.getElementById('link').click();" completionHandler:nil];
    [delegate waitForDownloadDidStart];
    EXPECT_FALSE([delegate didStartProvisionalNavigation]);
}

static bool didDownloadStart;

@interface WaitUntilDownloadCanceledDelegate : NSObject <_WKDownloadDelegate>
@end

@implementation WaitUntilDownloadCanceledDelegate

- (void)_downloadDidStart:(_WKDownload *)download
{
    didDownloadStart = true;
    [download.originatingWebView _killWebContentProcessAndResetState];
}

- (void)_download:(_WKDownload *)download didFailWithError:(NSError *)error
{
    EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
    EXPECT_EQ(error.code, NSURLErrorCancelled);
    isDone = true;
}

@end

TEST(_WKDownload, CrashAfterDownloadDidFinishWhenDownloadProxyHoldsTheLastRefOnWebProcessPool)
{
    auto navigationDelegate = adoptNS([[DownloadNavigationDelegate alloc] init]);
    auto downloadDelegate = adoptNS([[WaitUntilDownloadCanceledDelegate alloc] init]);
    WeakObjCPtr<WKProcessPool> processPool;
    @autoreleasepool {
        RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
        [webView setNavigationDelegate:navigationDelegate.get()];
        processPool = [webView configuration].processPool;
        [webView configuration].processPool._downloadDelegate = downloadDelegate.get();
        [webView loadRequest:[NSURLRequest requestWithURL:sourceURL]];

        didDownloadStart = false;
        TestWebKitAPI::Util::run(&didDownloadStart);
    }

    isDone = false;
    TestWebKitAPI::Util::run(&isDone);
    EXPECT_NULL(processPool.get());
}

static bool receivedData;
static RetainPtr<NSString> destination;

@interface DownloadMonitorTestDelegate : NSObject <_WKDownloadDelegate>
- (void)waitForDidFail;
- (void)stopWaitingForDidFail;
@end

@implementation DownloadMonitorTestDelegate {
    bool didFail;
}

- (void)_downloadDidStart:(_WKDownload *)download
{
    didDownloadStart = true;
}

- (void)_download:(_WKDownload *)download didFailWithError:(NSError *)error
{
    EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
    EXPECT_EQ(error.code, NSURLErrorCancelled);
    didFail = true;
}

- (void)waitForDidFail
{
    didFail = false;
    while (!didFail)
        TestWebKitAPI::Util::spinRunLoop();
}

- (void)stopWaitingForDidFail
{
    EXPECT_FALSE(didFail);
    didFail = true;
}

- (void)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename completionHandler:(void (^)(BOOL allowOverwrite, NSString *destination))completionHandler
{
    EXPECT_TRUE([filename isEqualToString:@"filename.dat"]);
    destination = [NSTemporaryDirectory() stringByAppendingPathComponent:filename];
    completionHandler(YES, destination.get());
}

- (void)_download:(_WKDownload *)download didReceiveData:(uint64_t)length
{
    receivedData = true;
}

@end

namespace TestWebKitAPI {

void respondSlowly(const Connection& connection, double kbps)
{
    EXPECT_TRUE(isMainThread());

    const double writesPerSecond = 100;
    Vector<uint8_t> writeBuffer(static_cast<size_t>(1024 * kbps / writesPerSecond));
    auto before = MonotonicTime::now();
    connection.send(WTFMove(writeBuffer), [=] {
        double writeDuration = (MonotonicTime::now() - before).seconds();
        double desiredSleep = 1.0 / writesPerSecond;
        if (writeDuration < desiredSleep)
            usleep(USEC_PER_SEC * (desiredSleep - writeDuration));
        respondSlowly(connection, kbps);
    });
}

static RetainPtr<DownloadMonitorTestDelegate> monitorDelegate()
{
    static auto delegate = adoptNS([DownloadMonitorTestDelegate new]);
    return delegate;
}

RetainPtr<WKWebView> webViewWithDownloadMonitorSpeedMultiplier(size_t multiplier)
{
    static auto navigationDelegate = adoptNS([DownloadNavigationDelegate new]);
    auto processPoolConfiguration = adoptNS([_WKProcessPoolConfiguration new]);
    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
    auto dataStoreConfiguration = adoptNS([_WKWebsiteDataStoreConfiguration new]);
    [dataStoreConfiguration setTestSpeedMultiplier:multiplier];
    auto webViewConfiguration = adoptNS([WKWebViewConfiguration new]);
    [webViewConfiguration setWebsiteDataStore:adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:dataStoreConfiguration.get()]).get()];
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
    [webView setNavigationDelegate:navigationDelegate.get()];
    [webView configuration].processPool._downloadDelegate = monitorDelegate().get();
    return webView;
}

enum class AppReturnsToForeground { No, Yes };
    
void downloadAtRate(double desiredKbps, unsigned speedMultiplier, AppReturnsToForeground returnToForeground = AppReturnsToForeground::No)
{
    HTTPServer server([=](const Connection& connection) {
        connection.receiveHTTPRequest([=](Vector<char>&&) {
            const char* responseHeader =
            "HTTP/1.1 200 OK\r\n"
            "Content-Disposition: attachment; filename=\"filename.dat\"\r\n"
            "Content-Length: 100000000\r\n\r\n";
            connection.send(responseHeader, [=] {
                respondSlowly(connection, desiredKbps);
            });
        });
    });
    
    auto webView = webViewWithDownloadMonitorSpeedMultiplier(speedMultiplier);
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/", server.port()]]]];
    receivedData = false;
    Util::run(&receivedData);
    // Start the DownloadMonitor's timer.
    [[webView configuration].websiteDataStore _synthesizeAppIsBackground:YES];
    if (returnToForeground == AppReturnsToForeground::Yes)
        [[webView configuration].websiteDataStore _synthesizeAppIsBackground:NO];
    [monitorDelegate() waitForDidFail];
    [[NSFileManager defaultManager] removeItemAtURL:[NSURL fileURLWithPath:destination.get() isDirectory:NO] error:nil];
}

TEST(_WKDownload, DownloadMonitorCancel)
{
    downloadAtRate(0.5, 120); // Should cancel in ~0.5 seconds
    downloadAtRate(1.5, 120); // Should cancel in ~2.5 seconds
}

TEST(_WKDownload, DISABLED_DownloadMonitorSurvive)
{
    __block BOOL timeoutReached = NO;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2.5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [monitorDelegate() stopWaitingForDidFail];
        timeoutReached = YES;
    });

    // Simulates an hour of downloading 150kb/s in 1 second.
    // Timeout should be reached before this is cancelled because the download rate is high enough.
    downloadAtRate(150.0, 3600);
    EXPECT_TRUE(timeoutReached);
}

TEST(_WKDownload, DownloadMonitorReturnToForeground)
{
    __block BOOL timeoutReached = NO;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2.5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [monitorDelegate() stopWaitingForDidFail];
        timeoutReached = YES;
    });
    downloadAtRate(0.5, 120, AppReturnsToForeground::Yes);
    EXPECT_TRUE(timeoutReached);
}

} // namespace TestWebKitAPI

@interface TestDownloadNavigationResponseFromMemoryCacheDelegate : NSObject <WKNavigationDelegate, _WKDownloadDelegate>
@property (nonatomic) WKNavigationResponsePolicy responsePolicy;
@property (nonatomic, readonly) BOOL didFailProvisionalNavigation;
@property (nonatomic, readonly) BOOL didFinishNavigation;
@property (nonatomic, readonly) BOOL didStartDownload;
@end

@implementation TestDownloadNavigationResponseFromMemoryCacheDelegate

- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
{
    _didFailProvisionalNavigation = NO;
    _didFinishNavigation = NO;
    _didStartDownload = NO;
}

- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
    EXPECT_EQ(_WKErrorCodeFrameLoadInterruptedByPolicyChange, error.code);
    EXPECT_FALSE(_didFinishNavigation);
    EXPECT_WK_STREQ(_WKLegacyErrorDomain, error.domain);
    _didFailProvisionalNavigation = YES;
    if (_responsePolicy != WKNavigationResponsePolicyDownload || _didStartDownload)
        isDone = true;
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    EXPECT_FALSE(_didFailProvisionalNavigation);
    _didFinishNavigation = YES;
    if (_responsePolicy != WKNavigationResponsePolicyDownload || _didStartDownload)
        isDone = true;
}

- (void)_downloadDidStart:(_WKDownload *)download
{
    _didStartDownload = YES;
    if (_didFailProvisionalNavigation || _didFinishNavigation)
        isDone = true;
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
    decisionHandler(_responsePolicy);
}

@end

TEST(WebKit, DownloadNavigationResponseFromMemoryCache)
{
    [TestProtocol registerWithScheme:@"http"];
    TestProtocol.additionalResponseHeaders = @{ @"Cache-Control" : @"max-age=3600" };

    auto delegate = adoptNS([[TestDownloadNavigationResponseFromMemoryCacheDelegate alloc] init]);
    auto webView = adoptNS([[WKWebView alloc] init]);
    [webView setNavigationDelegate:delegate.get()];
    [webView configuration].processPool._downloadDelegate = delegate.get();

    NSURL *firstURL = [NSURL URLWithString:@"http://bundle-file/simple.html"];
    [delegate setResponsePolicy:WKNavigationResponsePolicyAllow];
    [webView loadRequest:[NSURLRequest requestWithURL:firstURL]];
    isDone = false;
    TestWebKitAPI::Util::run(&isDone);
    EXPECT_FALSE([delegate didFailProvisionalNavigation]);
    EXPECT_FALSE([delegate didStartDownload]);
    EXPECT_TRUE([delegate didFinishNavigation]);
    EXPECT_WK_STREQ(firstURL.absoluteString, [webView URL].absoluteString);

    NSURL *secondURL = [NSURL URLWithString:@"http://bundle-file/simple2.html"];
    [delegate setResponsePolicy:WKNavigationResponsePolicyDownload];
    [webView loadRequest:[NSURLRequest requestWithURL:secondURL]];
    isDone = false;
    TestWebKitAPI::Util::run(&isDone);
    EXPECT_FALSE([delegate didFinishNavigation]);
    EXPECT_TRUE([delegate didFailProvisionalNavigation]);
    EXPECT_TRUE([delegate didStartDownload]);
    EXPECT_WK_STREQ(firstURL.absoluteString, [webView URL].absoluteString);

    [delegate setResponsePolicy:WKNavigationResponsePolicyAllow];
    [webView loadRequest:[NSURLRequest requestWithURL:secondURL]];
    isDone = false;
    TestWebKitAPI::Util::run(&isDone);
    EXPECT_FALSE([delegate didFailProvisionalNavigation]);
    EXPECT_FALSE([delegate didStartDownload]);
    EXPECT_TRUE([delegate didFinishNavigation]);
    EXPECT_WK_STREQ(secondURL.absoluteString, [webView URL].absoluteString);

    [delegate setResponsePolicy:WKNavigationResponsePolicyAllow];
    [webView goBack];
    isDone = false;
    TestWebKitAPI::Util::run(&isDone);
    EXPECT_FALSE([delegate didFailProvisionalNavigation]);
    EXPECT_FALSE([delegate didStartDownload]);
    EXPECT_TRUE([delegate didFinishNavigation]);
    EXPECT_WK_STREQ(firstURL.absoluteString, [webView URL].absoluteString);

    [delegate setResponsePolicy:WKNavigationResponsePolicyDownload];
    [webView loadRequest:[NSURLRequest requestWithURL:secondURL]];
    isDone = false;
    TestWebKitAPI::Util::run(&isDone);
    EXPECT_FALSE([delegate didFinishNavigation]);
    EXPECT_TRUE([delegate didFailProvisionalNavigation]);
    EXPECT_TRUE([delegate didStartDownload]);
    EXPECT_WK_STREQ(firstURL.absoluteString, [webView URL].absoluteString);

    TestProtocol.additionalResponseHeaders = nil;
    [TestProtocol unregister];
}

@interface DownloadCancelingDelegate : NSObject <_WKDownloadDelegate>
@property (readonly) RetainPtr<NSData> resumeData;
@property (readonly) RetainPtr<NSString> path;
@end

@implementation DownloadCancelingDelegate

- (void)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename completionHandler:(void (^)(BOOL allowOverwrite, NSString *destination))completionHandler
{
    FileSystem::PlatformFileHandle fileHandle;
    _path = FileSystem::openTemporaryFile("TestWebKitAPI", fileHandle);
    EXPECT_TRUE(fileHandle != FileSystem::invalidPlatformFileHandle);
    FileSystem::closeFile(fileHandle);
    completionHandler(YES, _path.get());
}

- (void)_download:(_WKDownload *)download didReceiveData:(uint64_t)length
{
    EXPECT_EQ(length, 5000ULL);
    [download cancel];
}

- (void)_downloadDidCancel:(_WKDownload *)download
{
    EXPECT_NOT_NULL(download.resumeData);
    _resumeData = download.resumeData;
    isDone = true;
}

@end

@interface AuthenticationChallengeHandlingDelegate : NSObject <_WKDownloadDelegate>
@end

@implementation AuthenticationChallengeHandlingDelegate {
    bool _didReceiveAuthenticationChallenge;
}

- (void)_download:(_WKDownload *)download didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential*))completionHandler
{
    _didReceiveAuthenticationChallenge = true;
    completionHandler(NSURLSessionAuthChallengeUseCredential, nil);
}

- (void)_downloadDidFinish:(_WKDownload *)download
{
    EXPECT_TRUE(_didReceiveAuthenticationChallenge);
    isDone = true;
}

@end

TEST(_WKDownload, ResumedDownloadCanHandleAuthenticationChallenge)
{
    using namespace TestWebKitAPI;

    HTTPServer server([receivedFirstConnection = false] (Connection connection) mutable {
        if (!std::exchange(receivedFirstConnection, true)) {
            connection.receiveHTTPRequest([=](Vector<char>&&) {
                const char* responseHeader =
                "HTTP/1.1 200 OK\r\n"
                "ETag: test\r\n"
                "Content-Length: 10000\r\n\r\n";
                connection.send(responseHeader, [=] {
                    connection.send(Vector<uint8_t>(5000, 0));
                });
            });
            return;
        }
        connection.receiveHTTPRequest([=](Vector<char>&&) {
            const char* challengeHeader =
            "HTTP/1.1 401 Unauthorized\r\n"
            "Date: Sat, 23 Mar 2019 06:29:01 GMT\r\n"
            "Content-Length: 0\r\n"
            "WWW-Authenticate: Basic realm=\"testrealm\"\r\n\r\n";
            connection.send(challengeHeader, [=] {
                connection.receiveHTTPRequest([=](Vector<char>&&) {
                    const char* responseHeader =
                    "HTTP/1.1 206 Partial Content\r\n"
                    "ETag: test\r\n"
                    "Content-Range: bytes 5000-9999/10000\r\n"
                    "Content-Length: 5000\r\n\r\n";
                    connection.send(responseHeader, [=] {
                        connection.send(Vector<uint8_t>(5000, 1));
                    });
                });
            });
        });
    });

    auto processPool = adoptNS([[WKProcessPool alloc] init]);
    auto websiteDataStore = [WKWebsiteDataStore defaultDataStore];

    auto delegate1 = adoptNS([[DownloadCancelingDelegate alloc] init]);
    [processPool _setDownloadDelegate:delegate1.get()];

    isDone = false;
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/", server.port()]]];
    [processPool _downloadURLRequest:request websiteDataStore:websiteDataStore originatingWebView:nil];

    Util::run(&isDone);

    isDone = false;
    auto delegate2 = adoptNS([[AuthenticationChallengeHandlingDelegate alloc] init]);
    [processPool _setDownloadDelegate:delegate2.get()];
    [processPool _resumeDownloadFromData:[delegate1 resumeData].get() websiteDataStore:websiteDataStore path:[delegate1 path].get() originatingWebView:nil];

    Util::run(&isDone);
}

template<size_t length>
String longString(LChar c)
{
    Vector<LChar> vector(length, c);
    return String(vector.data(), length);
}

enum class IncludeETag : bool { No, Yes };
enum class TerminateAfterFirstReply : bool { No, Yes };

static TestWebKitAPI::HTTPServer downloadTestServer(IncludeETag includeETag = IncludeETag::Yes, Function<void(TestWebKitAPI::Connection)>&& terminator = nullptr)
{
    return { [includeETag, terminator = WTFMove(terminator), connectionCount = 0](TestWebKitAPI::Connection connection) mutable {
        switch (++connectionCount) {
        case 1:
            connection.receiveHTTPRequest([includeETag, connection, terminator = WTFMove(terminator)] (Vector<char>&&) mutable {
                auto response = makeString(
                    "HTTP/1.1 200 OK\r\n",
                    includeETag == IncludeETag::Yes ? "ETag: test\r\n" : "",
                    "Content-Length: 10000\r\n"
                    "Content-Disposition: attachment; filename=\"example.txt\"\r\n"
                    "\r\n", longString<5000>('a')
                );
                connection.send(WTFMove(response), [connection, terminator = WTFMove(terminator)] () mutable {
                    if (terminator)
                        terminator(connection);
                });
            });
            break;
        case 2:
            connection.receiveHTTPRequest([=](Vector<char>&& request) {
                EXPECT_TRUE(strnstr(request.data(), "Range: bytes=5000-\r\n", request.size()));
                connection.send(makeString(
                    "HTTP/1.1 206 Partial Content\r\n"
                    "ETag: test\r\n"
                    "Content-Length: 5000\r\n"
                    "Content-Range: bytes 5000-9999/10000\r\n"
                    "\r\n", longString<5000>('b')
                ));
            });
            break;
        default:
            ASSERT_NOT_REACHED();
        }
    }};
}

static void checkResumedDownloadContents(NSURL *file)
{
    NSData *fileContents = [NSData dataWithContentsOfURL:file];
    EXPECT_EQ(fileContents.length, 10000u);
    EXPECT_TRUE(fileContents.bytes);
    if (fileContents.bytes && fileContents.length == 10000u) {
        for (size_t i = 0; i < 5000; i++)
            EXPECT_EQ(static_cast<const char*>(fileContents.bytes)[i], 'a');
        for (size_t i = 5000; i < 10000; i++)
            EXPECT_EQ(static_cast<const char*>(fileContents.bytes)[i], 'b');
    }
}

static TestWebKitAPI::HTTPServer simpleDownloadTestServer()
{
    return { [](TestWebKitAPI::Connection connection) {
        connection.receiveHTTPRequest([connection](Vector<char>&&) {
            connection.send(makeString(
                "HTTP/1.1 200 OK\r\n"
                "ETag: test\r\n"
                "Content-Length: 5000\r\n"
                "Content-Disposition: attachment; filename=\"example.txt\"\r\n"
                "\r\n", longString<5000>('a')
            ));
        });
    }};
}

static void checkFileContents(NSURL *file, const String& expectedContents)
{
    NSData *fileContents = [NSData dataWithContentsOfURL:file];
    EXPECT_EQ(fileContents.length, expectedContents.length());
    for (size_t i = 0; i < fileContents.length; i++)
        EXPECT_EQ(static_cast<const char*>(fileContents.bytes)[i], expectedContents[i]);
}

static NSURL *tempFileThatDoesNotExist()
{
    NSURL *tempDir = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"DownloadTest"] isDirectory:YES];
    [[NSFileManager defaultManager] createDirectoryAtURL:tempDir withIntermediateDirectories:YES attributes:nil error:nil];
    NSURL *file = [tempDir URLByAppendingPathComponent:@"example.txt"];
    [[NSFileManager defaultManager] removeItemAtURL:file error:nil];
    return file;
}

TEST(_WKDownload, Resume)
{
    using namespace TestWebKitAPI;
    auto server = downloadTestServer();

    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();

    auto navigationDelegate = adoptNS([TestNavigationDelegate new]);
    navigationDelegate.get().decidePolicyForNavigationResponse = ^(WKNavigationResponse *, void (^completionHandler)(WKNavigationResponsePolicy)) {
        completionHandler(WKNavigationResponsePolicyDownload);
    };

    enum class Callback : uint8_t { Start, WriteData, DecideDestination, CreateDestination, Cancel, Finish };
    __block Vector<Callback> callbacks;
    __block bool didCancel = false;
    __block bool didFinish = false;
    __block bool receivedData = false;
    __block RetainPtr<_WKDownload> download;
    __block RetainPtr<NSData> resumeData;

    auto downloadDelegate = adoptNS([TestLegacyDownloadDelegate new]);
    downloadDelegate.get().decideDestinationWithSuggestedFilename = ^(_WKDownload *, NSString *suggestedFilename, void (^completionHandler)(BOOL, NSString *)) {
        callbacks.append(Callback::DecideDestination);
        EXPECT_WK_STREQ("example.txt", suggestedFilename);
        completionHandler(YES, expectedDownloadFile.path);
    };
    downloadDelegate.get().didWriteData = ^(_WKDownload *download, uint64_t bytesWritten, uint64_t totalBytesWritten, uint64_t totalBytesExpectedToWrite) {
        callbacks.append(Callback::WriteData);
        EXPECT_EQ(bytesWritten, 5000u);
        EXPECT_EQ(totalBytesWritten, didCancel ? 10000u : 5000u);
        EXPECT_EQ(totalBytesExpectedToWrite, 10000u);
        receivedData = true;
    };
    downloadDelegate.get().downloadDidStart = ^(_WKDownload *downloadFromDelegate) {
        callbacks.append(Callback::Start);
        download = downloadFromDelegate;
    };
    downloadDelegate.get().didCreateDestination = ^(_WKDownload *, NSString *destination) {
        callbacks.append(Callback::CreateDestination);
        EXPECT_WK_STREQ(destination, expectedDownloadFile.path);
    };
    downloadDelegate.get().downloadDidCancel = ^(_WKDownload *download) {
        callbacks.append(Callback::Cancel);
        resumeData = download.resumeData;
        didCancel = true;
    };
    downloadDelegate.get().downloadDidFinish = ^(_WKDownload *) {
        callbacks.append(Callback::Finish);
        didFinish = true;
    };

    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:navigationDelegate.get()];
    [webView configuration].processPool._downloadDelegate = downloadDelegate.get();
    [webView loadRequest:server.request()];
    Util::run(&receivedData);
    [download cancel];
    Util::run(&didCancel);

    [[webView configuration].processPool _resumeDownloadFromData:resumeData.get() websiteDataStore:[WKWebsiteDataStore defaultDataStore] path:expectedDownloadFile.path originatingWebView:webView.get()];
    Util::run(&didFinish);
    
    EXPECT_EQ(callbacks.size(), 7u);
    EXPECT_EQ(callbacks[0], Callback::Start);
    EXPECT_EQ(callbacks[1], Callback::DecideDestination);
    EXPECT_EQ(callbacks[2], Callback::CreateDestination);
    EXPECT_EQ(callbacks[3], Callback::WriteData);
    EXPECT_EQ(callbacks[4], Callback::Cancel);
    EXPECT_EQ(callbacks[5], Callback::WriteData);
    EXPECT_EQ(callbacks[6], Callback::Finish);

    // Give CFNetwork enough time to unlink the downloaded file if it would have.
    // This makes failures like https://bugs.webkit.org/show_bug.cgi?id=211786 more reliable.
    usleep(10000);
    Util::spinRunLoop(10);
    usleep(10000);

    checkResumedDownloadContents(expectedDownloadFile);
}

@interface DownloadTestSchemeDelegate : NSObject <WKNavigationDelegate>
@end

@implementation DownloadTestSchemeDelegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
    if ([navigationResponse.response.URL.absoluteString hasSuffix:@"/download"])
        decisionHandler(WKNavigationResponsePolicyDownload);
    else
        decisionHandler(WKNavigationResponsePolicyAllow);
}
@end

@interface DownloadSecurityOriginDelegate : NSObject <_WKDownloadDelegate>
@end

@implementation DownloadSecurityOriginDelegate {
@public
    uint16_t _serverPort;
    WKWebView *_webView;
}

- (void)_downloadDidStart:(_WKDownload *)download
{
    EXPECT_TRUE([download.originatingFrame.securityOrigin.protocol isEqualToString:@"http"]);
    EXPECT_TRUE([download.originatingFrame.securityOrigin.host isEqualToString:@"127.0.0.1"]);
    EXPECT_EQ(download.originatingFrame.securityOrigin.port, _serverPort);
    EXPECT_FALSE(download.originatingFrame.mainFrame);
    EXPECT_EQ(download.originatingFrame.webView, _webView);
    isDone = true;
}

@end

static const char* documentText = R"DOCDOCDOC(
<script>
function loaded()
{
    document.getElementById("thelink").click();
}
</script>
<body onload="loaded();">
<a id="thelink" href="download">Click me</a>
</body>
)DOCDOCDOC";

TEST(_WKDownload, SubframeSecurityOrigin)
{
    auto navigationDelegate = adoptNS([[DownloadTestSchemeDelegate alloc] init]);
    auto downloadDelegate = adoptNS([[DownloadSecurityOriginDelegate alloc] init]);

    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
    [webView setNavigationDelegate:navigationDelegate.get()];
    [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];

    TestWebKitAPI::HTTPServer server({
        { "/page", { documentText } },
        { "/download", { documentText } },
    });
    downloadDelegate->_serverPort = server.port();
    downloadDelegate->_webView = webView.get();

    isDone = false;
    [webView loadHTMLString:[NSString stringWithFormat:@"<body><iframe src='http://127.0.0.1:%d/page'></iframe></body>", server.port()] baseURL:nil];
    TestWebKitAPI::Util::run(&isDone);
}

@interface DownloadObserver : NSObject
@property (nonatomic, copy) void (^progressChangeCallback)(int64_t, int64_t);
@end

@implementation DownloadObserver

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *, id> *)change context:(void *)context
{
    if (self.progressChangeCallback) {
        NSProgress *progress = (NSProgress *)object;
        self.progressChangeCallback(progress.completedUnitCount, progress.totalUnitCount);
    }
}

@end

namespace TestWebKitAPI {

static void checkCallbackRecord(TestDownloadDelegate *delegate, Vector<DownloadCallback> expectedCallbacks)
{
    auto actualCallbacks = delegate.takeCallbackRecord;
    EXPECT_EQ(actualCallbacks.size(), expectedCallbacks.size());
    for (size_t i = 0; i < std::min(actualCallbacks.size(), expectedCallbacks.size()); i++)
        EXPECT_EQ(actualCallbacks[i], expectedCallbacks[i]);
}

TEST(WKDownload, FinishSuccessfully)
{
    auto server = simpleDownloadTestServer();
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];

    delegate.get().navigationResponseDidBecomeDownload = ^(WKWebView *, WKNavigationResponse *, WKDownload *download) {
        download.delegate = delegate.get();
        delegate.get().decideDestinationUsingResponse = ^(WKDownload *download, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {
            EXPECT_NULL(download.progress.fileURL);
            completionHandler(expectedDownloadFile);
            EXPECT_NOT_NULL(download.progress.fileURL);
            EXPECT_WK_STREQ(download.progress.fileURL.absoluteString, expectedDownloadFile.absoluteString);
        };
    };
    [webView loadRequest:server.request()];
    [delegate waitForDownloadDidFinish];

    checkFileContents(expectedDownloadFile, longString<5000>('a'));

    checkCallbackRecord(delegate.get(), {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationResponseBecameDownload,
        DownloadCallback::DecideDestination,
        DownloadCallback::DidFinish
    });
}

static void resumeAndFinishDownload(NSData *resumeData, NSURL *destination)
{
    __block RetainPtr<WKDownload> retainedDownload;
    @autoreleasepool {
        checkFileContents(destination, longString<5000>('a'));

        auto delegate = adoptNS([TestDownloadDelegate new]);
        auto webView = adoptNS([WKWebView new]);

        [webView resumeDownloadFromResumeData:resumeData completionHandler:^(WKDownload *download) {
            retainedDownload = download;
            EXPECT_NULL(download.delegate);
        }];
        while (!retainedDownload)
            Util::spinRunLoop();
        
        __block bool downloadedSecond5k = false;
        EXPECT_NULL(retainedDownload.get().delegate);
        retainedDownload.get().delegate = delegate.get();
        delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {
            ASSERT_NOT_REACHED();
        };

        auto observer = adoptNS([DownloadObserver new]);
        observer.get().progressChangeCallback = ^(int64_t bytesWritten, int64_t totalByteCount) {
            if (bytesWritten == 10000) {
                EXPECT_EQ(totalByteCount, 10000);
                downloadedSecond5k = true;
            }
        };
        [retainedDownload.get().progress addObserver:observer.get() forKeyPath:@"completedUnitCount" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial context:nil];

        __block bool didFinish = false;
        delegate.get().downloadDidFinish = ^(WKDownload *download) {
            EXPECT_EQ(retainedDownload.get(), download);
            EXPECT_TRUE(downloadedSecond5k);
            didFinish = true;
        };

        Util::run(&didFinish);

        [retainedDownload.get().progress removeObserver:observer.get() forKeyPath:@"completedUnitCount" context:nil];

        checkResumedDownloadContents(destination);
        checkCallbackRecord(delegate.get(), {
            DownloadCallback::DidFinish
        });
        EXPECT_EQ(retainedDownload.get().webView, webView.get());
        EXPECT_NOT_NULL(retainedDownload.get().webView);
    }
    EXPECT_NOT_NULL(retainedDownload.get());
    EXPECT_NULL(retainedDownload.get().webView);
}

static void waitForFirst5k(RetainPtr<WKDownload>& download)
{
    __block bool downloadedFirst5k = false;
    
    auto observer = adoptNS([DownloadObserver new]);
    observer.get().progressChangeCallback = ^(int64_t bytesWritten, int64_t totalByteCount) {
        if (bytesWritten == 5000) {
            EXPECT_EQ(totalByteCount, 10000);
            downloadedFirst5k = true;
        }
    };
    while (!download)
        Util::spinRunLoop();
    [download.get().progress addObserver:observer.get() forKeyPath:@"completedUnitCount" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial context:nil];
    Util::run(&downloadedFirst5k);
    [download.get().progress removeObserver:observer.get() forKeyPath:@"completedUnitCount" context:nil];
}

TEST(WKDownload, CancelAndResume)
{
    auto server = downloadTestServer();
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];

    __block RetainPtr<WKDownload> retainedDownload;
    delegate.get().navigationResponseDidBecomeDownload = ^(WKWebView *, WKNavigationResponse *, WKDownload *download) {
        retainedDownload = download;
        download.delegate = delegate.get();
        delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {
            completionHandler(expectedDownloadFile);
        };
    };

    [webView loadRequest:server.request()];
    waitForFirst5k(retainedDownload);

    __block RetainPtr<NSData> retainedResumeData;
    [retainedDownload cancel:^(NSData *resumeData) {
        retainedResumeData = resumeData;
    }];

    while (!retainedResumeData)
        Util::spinRunLoop();
    resumeAndFinishDownload(retainedResumeData.get(), expectedDownloadFile);
    checkCallbackRecord(delegate.get(), {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationResponseBecameDownload,
        DownloadCallback::DecideDestination,
    });
}

TEST(WKDownload, FailAndResume)
{
    auto delegate = adoptNS([TestDownloadDelegate new]);
    RetainPtr<WKDownload> retainedDownload;
    auto server = downloadTestServer(IncludeETag::Yes, [&] (TestWebKitAPI::Connection connection) {
        waitForFirst5k(retainedDownload);
        connection.terminate();
    });
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];

    RetainPtr<NSData> retainedResumeData;
    delegate.get().navigationResponseDidBecomeDownload = makeBlockPtr([&](WKWebView *, WKNavigationResponse *, WKDownload *download) {
        retainedDownload = download;
        download.delegate = delegate.get();
        delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {
            completionHandler(expectedDownloadFile);
        };
        delegate.get().didFailWithError = ^(WKDownload *download, NSError *error, NSData *resumeData) {
            EXPECT_EQ(download, retainedDownload.get());
            EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
            EXPECT_EQ(error.code, NSURLErrorNetworkConnectionLost);
            retainedResumeData = resumeData;
        };
    }).get();

    [webView loadRequest:server.request()];

    while (!retainedResumeData)
        Util::spinRunLoop();
    resumeAndFinishDownload(retainedResumeData.get(), expectedDownloadFile);
    checkCallbackRecord(delegate.get(), {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationResponseBecameDownload,
        DownloadCallback::DecideDestination,
        DownloadCallback::DidFailWithError,
    });
}

TEST(WKDownload, CancelNoResumeData)
{
    auto server = downloadTestServer(IncludeETag::No);
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];

    __block RetainPtr<WKDownload> retainedDownload;
    delegate.get().navigationResponseDidBecomeDownload = ^(WKWebView *, WKNavigationResponse *, WKDownload *download) {
        retainedDownload = download;
        download.delegate = delegate.get();
        delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {
            completionHandler(expectedDownloadFile);
        };
    };
    [webView loadRequest:server.request()];
    waitForFirst5k(retainedDownload);

    __block bool done = false;
    [retainedDownload cancel:^(NSData *resumeData) {
        EXPECT_NULL(resumeData);
        done = true;
    }];
    Util::run(&done);
    checkFileContents(expectedDownloadFile, longString<5000>('a'));
    checkCallbackRecord(delegate.get(), {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationResponseBecameDownload,
        DownloadCallback::DecideDestination,
    });
}

TEST(WKDownload, FailNoResumeData)
{
    auto delegate = adoptNS([TestDownloadDelegate new]);
    RetainPtr<WKDownload> retainedDownload;
    auto server = downloadTestServer(IncludeETag::No, [&] (TestWebKitAPI::Connection connection) {
        waitForFirst5k(retainedDownload);
        connection.terminate();
    });
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];

    bool done = false;
    delegate.get().navigationResponseDidBecomeDownload = makeBlockPtr([&](WKWebView *, WKNavigationResponse *, WKDownload *download) {
        retainedDownload = download;
        download.delegate = delegate.get();
        delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {
            completionHandler(expectedDownloadFile);
        };
        delegate.get().didFailWithError = makeBlockPtr([&](WKDownload *, NSError *error, NSData *resumeData) {
            EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
            EXPECT_EQ(error.code, NSURLErrorNetworkConnectionLost);
            EXPECT_NULL(resumeData);
            done = true;
        }).get();
    }).get();
    [webView loadRequest:server.request()];
    Util::run(&done);
    checkFileContents(expectedDownloadFile, longString<5000>('a'));
    checkCallbackRecord(delegate.get(), {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationResponseBecameDownload,
        DownloadCallback::DecideDestination,
        DownloadCallback::DidFailWithError
    });
}

// FIXME: Make this work in CFNetwork.
#if HAVE(CFNET_RESPONSE_CALLBACK_WITH_NO_CONTENT)

TEST(WKDownload, ResumeAfterZeroBytesReceived)
{
    std::optional<TestWebKitAPI::Connection> serverConnection;
    HTTPServer server([connectionCount = 0, &serverConnection](TestWebKitAPI::Connection connection) mutable {
        switch (++connectionCount) {
        case 1:
            serverConnection = connection;
            connection.receiveHTTPRequest([=](Vector<char>&&) {
                connection.send(
                    "HTTP/1.1 200 OK\r\n"
                    "ETag: test\r\n"
                    "Content-Disposition: attachment; filename=\"example.txt\"\r\n"
                    "\r\n"
                );
            });
            break;
        case 2:
            connection.receiveHTTPRequest([=](Vector<char>&& request) {
                EXPECT_TRUE(strnstr(request.data(), "Range: bytes=5000-\r\n", request.size()));
                connection.send(makeString(
                    "HTTP/1.1 200 OK\r\n"
                    "ETag: test\r\n"
                    "Content-Length: 100\r\n"
                    "\r\n", longString<100>('x')
                ));
            });
            break;
        default:
            ASSERT_NOT_REACHED();
        }
    });

    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    webView.navigationDelegate = delegate.get();

    delegate.get().navigationResponseDidBecomeDownload = ^(WKWebView *, WKNavigationResponse *, WKDownload *download) {
        download.delegate = delegate.get();
    };
    delegate.get().decideDestinationUsingResponse = [&](WKDownload *, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {
        completionHandler(expectedDownloadFile);
        serverConnection->terminate();
    };
    __block RetainPtr<NSData> retainedResumeData;
    delegate.get().didFailWithError = ^(WKDownload *, NSError *error, NSData *resumeData) {
        EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
        EXPECT_EQ(error.code, NSURLErrorNetworkConnectionLost);
        retainedResumeData = resumeData;
    };
    __block bool downloadFinished = false;
    delegate.get().downloadDidFinish = ^(WKDownload *) {
        downloadFinished = true;
    };

    [webView loadRequest:server.request()];
    while (!retainedResumeData)
        Util::spinRunLoop();
    
    EXPECT_FALSE([[NSFileManager defaultManager] fileExistsAtPath:expectedDownloadFile.path]);
    EXPECT_FALSE(downloadFinished);
    [webView resumeDownloadFromResumeData:retainedResumeData.get() completionHandler:^(WKDownload *download) {
        download.delegate = delegate.get();
    }];
    Util::run(&downloadFinished);
    checkFileContents(expectedDownloadFile, longString<100>('x'));

    checkCallbackRecord(delegate.get(), {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationResponseBecameDownload,
        DownloadCallback::DecideDestination,
        DownloadCallback::DidFailWithError,
        DownloadCallback::DidFinish
    });
}

#endif

void testResumeAfterMutatingDisk(NSURLRequest *serverRequest, NSURL *expectedDownloadFile, void(^mutateFile)(void))
{
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];

    __block RetainPtr<WKDownload> retainedDownload;
    delegate.get().navigationResponseDidBecomeDownload = ^(WKWebView *, WKNavigationResponse *, WKDownload *download) {
        retainedDownload = download;
        download.delegate = delegate.get();
        delegate.get().decideDestinationUsingResponse = ^(WKDownload *download, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {
            completionHandler(expectedDownloadFile);
        };
    };

    [webView loadRequest:serverRequest];
    waitForFirst5k(retainedDownload);

    __block RetainPtr<NSData> retainedResumeData;
    [retainedDownload cancel:^(NSData *resumeData) {
        retainedResumeData = resumeData;
    }];

    while (!retainedResumeData)
        Util::spinRunLoop();

    checkFileContents(expectedDownloadFile, longString<5000>('a'));

    mutateFile();

    __block bool didFinish = false;
    [webView resumeDownloadFromResumeData:retainedResumeData.get() completionHandler:^(WKDownload *download) {
        download.delegate = delegate.get();
        delegate.get().downloadDidFinish = ^(WKDownload *) {
            didFinish = true;
        };
    }];
    Util::run(&didFinish);
    checkCallbackRecord(delegate.get(), {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationResponseBecameDownload,
        DownloadCallback::DecideDestination,
        DownloadCallback::DidFinish
    });
}

TEST(WKDownload, ResumeWithoutInitialDataOnDisk)
{
    HTTPServer server([connectionCount = 0](TestWebKitAPI::Connection connection) mutable {
        switch (++connectionCount) {
        case 1:
            connection.receiveHTTPRequest([=](Vector<char>&&) {
                connection.send(makeString(
                    "HTTP/1.1 200 OK\r\n"
                    "ETag: test\r\n"
                    "Content-Length: 10000\r\n"
                    "Content-Disposition: attachment; filename=\"example.txt\"\r\n"
                    "\r\n",
                    longString<5000>('a')
                ));
            });
            break;
        case 2:
            connection.receiveHTTPRequest([=](Vector<char>&& request) {
                EXPECT_FALSE(strnstr(request.data(), "Range", request.size()));
                connection.send(makeString(
                    "HTTP/1.1 200 OK\r\n"
                    "ETag: test\r\n"
                    "Content-Length: 10000\r\n"
                    "\r\n",
                    longString<10000>('x')
                ));
            });
            break;
        default:
            ASSERT_NOT_REACHED();
        }
    });
    
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    testResumeAfterMutatingDisk(server.request(), expectedDownloadFile, ^{
        NSError *error = nil;
        [[NSFileManager defaultManager] removeItemAtURL:expectedDownloadFile error:&error];
        EXPECT_NULL(error);
    });

    checkFileContents(expectedDownloadFile, longString<10000>('x'));
}

TEST(WKDownload, ResumeWithExtraInitialDataOnDisk)
{
    HTTPServer server([connectionCount = 0](TestWebKitAPI::Connection connection) mutable {
        switch (++connectionCount) {
        case 1:
            connection.receiveHTTPRequest([=](Vector<char>&&) {
                connection.send(makeString(
                    "HTTP/1.1 200 OK\r\n"
                    "ETag: test\r\n"
                    "Content-Length: 10000\r\n"
                    "Content-Disposition: attachment; filename=\"example.txt\"\r\n"
                    "\r\n",
                    longString<5000>('a')
                ));
            });
            break;
        case 2:
            connection.receiveHTTPRequest([=](Vector<char>&& request) {
                EXPECT_TRUE(strnstr(request.data(), "Range: bytes=5000-\r\n", request.size()));
                connection.send(makeString(
                    "HTTP/1.1 206 Partial Content\r\n"
                    "ETag: test\r\n"
                    "Content-Range: bytes 5000-9999/10000\r\n"
                    "Content-Length: 5000\r\n"
                    "\r\n",
                    longString<10000>('d')
                ));
            });
            break;
        default:
            ASSERT_NOT_REACHED();
        }
    });
    
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    testResumeAfterMutatingDisk(server.request(), expectedDownloadFile, ^{
        NSError *error = nil;
        [[NSFileManager defaultManager] removeItemAtURL:expectedDownloadFile error:&error];
        EXPECT_NULL(error);
        EXPECT_TRUE([[(NSString *)makeString(longString<3000>('b'), longString<3000>('c')) dataUsingEncoding:NSUTF8StringEncoding] writeToURL:expectedDownloadFile atomically:YES]);
    });

    checkFileContents(expectedDownloadFile, makeString(longString<3000>('b'), longString<3000>('c'), longString<5000>('d')));
}

TEST(WKDownload, ResumeWithInvalidResumeData)
{
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    EXPECT_TRUE([[@"initial data on disk" dataUsingEncoding:NSUTF8StringEncoding] writeToURL:expectedDownloadFile atomically:YES]);
    auto webView = adoptNS([WKWebView new]);
    bool caughtException = false;
    @try {
        [webView resumeDownloadFromResumeData:[@"invalid resume data" dataUsingEncoding:NSUTF8StringEncoding] completionHandler:^(WKDownload *download) {
            ASSERT_NOT_REACHED();
        }];
    } @catch (NSException *e) {
        EXPECT_WK_STREQ(e.name, NSInvalidArgumentException);
        caughtException = true;
    }
    EXPECT_TRUE(caughtException);
}

TEST(WKDownload, ResumeCantReconnect)
{
    auto server = downloadTestServer();
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];

    __block RetainPtr<WKDownload> retainedDownload;
    delegate.get().navigationResponseDidBecomeDownload = ^(WKWebView *, WKNavigationResponse *, WKDownload *download) {
        retainedDownload = download;
        download.delegate = delegate.get();
        delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {
            completionHandler(expectedDownloadFile);
        };
    };
    [webView loadRequest:server.request()];
    waitForFirst5k(retainedDownload);

    checkFileContents(expectedDownloadFile, longString<5000>('a'));

    __block RetainPtr<NSData> retainedResumeData;
    [retainedDownload cancel:^(NSData *resumeData) {
        retainedResumeData = resumeData;
    }];
    while (!retainedResumeData)
        Util::spinRunLoop();

    server.cancel();
    
    retainedDownload = nil;
    [webView resumeDownloadFromResumeData:retainedResumeData.get() completionHandler:^(WKDownload *download) {
        retainedDownload = download;
        EXPECT_NULL(download.delegate);
    }];
    while (!retainedDownload)
        Util::spinRunLoop();

    retainedDownload.get().delegate = delegate.get();
    __block bool done = false;
    delegate.get().didFailWithError = ^(WKDownload *, NSError *error, NSData *resumeData) {
        EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
        EXPECT_EQ(error.code, NSURLErrorCannotConnectToHost);
        EXPECT_NOT_NULL(resumeData);
        done = true;
    };
    Util::run(&done);
    checkCallbackRecord(delegate.get(), {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationResponseBecameDownload,
        DownloadCallback::DecideDestination,
        DownloadCallback::DidFailWithError
    });
}

TEST(WKDownload, UnknownContentLength)
{
    HTTPServer server([](Connection connection) {
        connection.receiveHTTPRequest([=](Vector<char>&&) {
            connection.send(makeString("HTTP/1.1 200 OK\r\n\r\n", longString<5000>('a')));
        });
    });
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];

    __block bool done = false;
    auto observer = adoptNS([DownloadObserver new]);
    observer.get().progressChangeCallback = ^(int64_t bytesWritten, int64_t totalByteCount) {
        EXPECT_EQ(totalByteCount, -1);
        if (bytesWritten == 5000)
            done = true;
    };

    __block RetainPtr<WKDownload> retainedDownload;
    delegate.get().navigationResponseDidBecomeDownload = ^(WKWebView *, WKNavigationResponse *, WKDownload *download) {
        download.delegate = delegate.get();
        retainedDownload = download;
        delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {
            completionHandler(expectedDownloadFile);
        };
        [download.progress addObserver:observer.get() forKeyPath:@"completedUnitCount" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial context:nil];
    };
    [webView loadRequest:server.request()];
    Util::run(&done);
    [retainedDownload.get().progress removeObserver:observer.get() forKeyPath:@"completedUnitCount" context:nil];
    checkFileContents(expectedDownloadFile, longString<5000>('a'));

    checkCallbackRecord(delegate.get(), {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationResponseBecameDownload,
        DownloadCallback::DecideDestination,
    });
}

TEST(WKDownload, InvalidArguments)
{
    auto webView = adoptNS([WKWebView new]);
    __block bool caughtException = false;
    auto server = downloadTestServer();
    auto delegate = adoptNS([TestDownloadDelegate new]);
    [webView startDownloadUsingRequest:server.request() completionHandler:^(WKDownload *download) {
        download.delegate = delegate.get();
        delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {
            @try {
                completionHandler([NSURL URLWithString:@"https://webkit.org/"]);
            } @catch (NSException *e) {
                EXPECT_WK_STREQ(e.name, NSInvalidArgumentException);
                caughtException = true;
            }
        };
    }];
    Util::run(&caughtException);
    checkCallbackRecord(delegate.get(), {
        DownloadCallback::DecideDestination,
    });
}

static HTTPServer redirectServer()
{
    return {{
        { "/", { 301, {{ "Location", "/redirectTarget" }, { "Custom-Name", "Custom-Value" }} } },
        { "/redirectTarget", { "hi" } },
    }};
}

TEST(WKDownload, RedirectAllow)
{
    auto server = redirectServer();
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];

    auto serverRequest = adoptNS([server.request() mutableCopy]);
    [serverRequest setHTTPBody:[@"body" dataUsingEncoding:NSUTF8StringEncoding]];
    
    __block bool finishedDownload = false;
    [webView startDownloadUsingRequest:serverRequest.get() completionHandler:^(WKDownload *download) {
        download.delegate = delegate.get();
        delegate.get().willPerformHTTPRedirection = ^(WKDownload *, NSHTTPURLResponse *response, NSURLRequest *request, void (^completionHandler)(WKDownloadRedirectPolicy)) {
            EXPECT_NULL(request.HTTPBody); // FIXME: We probably want to make this non-null.
            EXPECT_WK_STREQ(response.URL.absoluteString, [serverRequest URL].absoluteString);
            EXPECT_EQ(response.statusCode, 301);
            EXPECT_WK_STREQ(response.allHeaderFields[@"Custom-Name"], "Custom-Value");
            EXPECT_WK_STREQ(request.URL.absoluteString, [[serverRequest URL] URLByAppendingPathComponent:@"redirectTarget"].absoluteString);
            completionHandler(WKDownloadRedirectPolicyAllow);
        };
        delegate.get().decideDestinationUsingResponse = ^(WKDownload *download, NSURLResponse *response, NSString *suggestedFilename, void (^completionHandler)(NSURL *)) {
            EXPECT_WK_STREQ(suggestedFilename, "redirectTarget.txt");
            EXPECT_WK_STREQ(response.URL.path, "/redirectTarget");
            EXPECT_WK_STREQ(download.originalRequest.URL.path, "/");
            EXPECT_WK_STREQ(download.originalRequest.URL.absoluteString, [serverRequest URL].absoluteString);
            completionHandler(expectedDownloadFile);
        };
        delegate.get().downloadDidFinish = ^(WKDownload *) {
            finishedDownload = true;
        };
    }];
    Util::run(&finishedDownload);

    checkFileContents(expectedDownloadFile, "hi");
    
    EXPECT_EQ(server.totalRequests(), 2u);

    checkCallbackRecord(delegate.get(), {
        DownloadCallback::WillRedirect,
        DownloadCallback::DecideDestination,
        DownloadCallback::DidFinish
    });
}

TEST(WKDownload, RedirectCancel)
{
    auto server = redirectServer();
    NSURLRequest *serverRequest = server.request();
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];

    __block bool cancelled = false;
    [webView startDownloadUsingRequest:server.request() completionHandler:^(WKDownload *download) {
        download.delegate = delegate.get();
        delegate.get().willPerformHTTPRedirection = ^(WKDownload *, NSHTTPURLResponse *response, NSURLRequest *request, void (^completionHandler)(WKDownloadRedirectPolicy)) {
            EXPECT_WK_STREQ(response.URL.absoluteString, serverRequest.URL.absoluteString);
            EXPECT_EQ(response.statusCode, 301);
            EXPECT_WK_STREQ(response.allHeaderFields[@"Custom-Name"], "Custom-Value");
            EXPECT_WK_STREQ(request.URL.absoluteString, [serverRequest.URL URLByAppendingPathComponent:@"redirectTarget"].absoluteString);
            completionHandler(WKDownloadRedirectPolicyCancel);
        };
        delegate.get().didFailWithError = ^(WKDownload *, NSError *error, NSData *resumeData) {
            EXPECT_NULL(resumeData);
            EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
            EXPECT_EQ(error.code, NSURLErrorCancelled);
            cancelled = true;
        };
    }];
    Util::run(&cancelled);
    checkCallbackRecord(delegate.get(), {
        DownloadCallback::WillRedirect,
        DownloadCallback::DidFailWithError
    });
    EXPECT_EQ(server.totalRequests(), 1u);
}

TEST(WKDownload, DownloadRequestFailure)
{
    HTTPServer server({ });
    NSURLRequest *serverRequest = server.request();
    server.cancel();
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];

    __block bool failed = false;
    [webView startDownloadUsingRequest:serverRequest completionHandler:^(WKDownload *download) {
        download.delegate = delegate.get();
        delegate.get().didFailWithError = ^(WKDownload *download, NSError *error, NSData *resumeData) {
            EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
            EXPECT_EQ(error.code, NSURLErrorCannotConnectToHost);
            failed = true;
        };
    }];
    Util::run(&failed);

    checkCallbackRecord(delegate.get(), {
        DownloadCallback::DidFailWithError,
    });
}

TEST(WKDownload, DownloadRequest404)
{
    HTTPServer server({
        { "/", { 404, { }, "http body" } }
    });
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];

    __block bool didFinish = false;
    [webView startDownloadUsingRequest:server.request() completionHandler:^(WKDownload *download) {
        download.delegate = delegate.get();
        delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {
            completionHandler(expectedDownloadFile);
        };
        delegate.get().downloadDidFinish = ^(WKDownload *download) {
            didFinish = true;
        };
    }];
    Util::run(&didFinish);

    checkFileContents(expectedDownloadFile, "http body");

    checkCallbackRecord(delegate.get(), {
        DownloadCallback::DecideDestination,
        DownloadCallback::DidFinish,
    });
}

TEST(WKDownload, NetworkProcessCrash)
{
    auto server = downloadTestServer();
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];

    __block RetainPtr<WKDownload> retainedDownload;
    delegate.get().navigationResponseDidBecomeDownload = ^(WKWebView *, WKNavigationResponse *, WKDownload *download) {
        retainedDownload = download;
        download.delegate = delegate.get();
        delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {
            completionHandler(expectedDownloadFile);
        };
    };
    [webView loadRequest:server.request()];
    waitForFirst5k(retainedDownload);
    
    __block bool terminated = false;
    delegate.get().didFailWithError = ^(WKDownload *, NSError *error, NSData *) {
        EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
        EXPECT_EQ(error.code, NSURLErrorNetworkConnectionLost);
        terminated = true;
    };
    [[webView configuration].websiteDataStore _terminateNetworkProcess];
    Util::run(&terminated);
    checkCallbackRecord(delegate.get(), {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationResponseBecameDownload,
        DownloadCallback::DecideDestination,
        DownloadCallback::DidFailWithError
    });
}

TEST(WKDownload, SuggestedFilenameFromHost)
{
    HTTPServer server({
        { "/", { "download content" } }
    });
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];

    delegate.get().navigationResponseDidBecomeDownload = ^(WKWebView *, WKNavigationResponse *, WKDownload *download) {
        download.delegate = delegate.get();
        delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *response, NSString *suggestedFilename, void (^completionHandler)(NSURL *)) {
            EXPECT_WK_STREQ(suggestedFilename, "127.0.0.1.txt");
            EXPECT_WK_STREQ(response.suggestedFilename, "127.0.0.1.txt");
            completionHandler(expectedDownloadFile);
        };
    };
    [webView loadRequest:server.request()];
    [delegate waitForDownloadDidFinish];

    checkFileContents(expectedDownloadFile, "download content");
    checkCallbackRecord(delegate.get(), {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationResponseBecameDownload,
        DownloadCallback::DecideDestination,
        DownloadCallback::DidFinish
    });
}

TEST(WKDownload, RequestHTTPBody)
{
    auto server = downloadTestServer();
    auto webView = adoptNS([WKWebView new]);
    __block bool done = false;
    auto request = adoptNS([server.request() mutableCopy]);
    [request setHTTPBody:[@"body" dataUsingEncoding:NSUTF8StringEncoding]];
    [webView startDownloadUsingRequest:request.get() completionHandler:^(WKDownload *download) {
        EXPECT_NULL(download.originalRequest.HTTPBody); // FIXME: We probably want to make this non-null.
        done = true;
    }];
    Util::run(&done);
}

TEST(WKDownload, PathMustExist)
{
    NSURL *tempDir = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"DownloadTest"] isDirectory:YES];
    [[NSFileManager defaultManager] removeItemAtURL:tempDir error:nil];
    NSURL *expectedDownloadFile = [tempDir URLByAppendingPathComponent:@"example.txt"];

    auto server = downloadTestServer();
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];

    __block bool failed = false;
    delegate.get().navigationResponseDidBecomeDownload = ^(WKWebView *, WKNavigationResponse *, WKDownload *download) {
        download.delegate = delegate.get();
        delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {
            completionHandler(expectedDownloadFile);
        };
        delegate.get().didFailWithError = ^(WKDownload *, NSError *error, NSData *) {
            EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
            EXPECT_EQ(error.code, NSURLErrorCannotCreateFile);
            failed = true;
        };
    };
    [webView loadRequest:server.request()];
    Util::run(&failed);
    checkCallbackRecord(delegate.get(), {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationResponseBecameDownload,
        DownloadCallback::DecideDestination,
        DownloadCallback::DidFailWithError
    });
}

TEST(WKDownload, FileMustNotExist)
{
    auto server = downloadTestServer();
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    __block auto retainedDelegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:retainedDelegate.get()];

    EXPECT_TRUE([[@"initial data on disk" dataUsingEncoding:NSUTF8StringEncoding] writeToURL:expectedDownloadFile atomically:YES]);

    __block bool failed = false;
    retainedDelegate.get().navigationResponseDidBecomeDownload = ^(WKWebView *, WKNavigationResponse *, WKDownload *download) {
        download.delegate = retainedDelegate.get();
        retainedDelegate.get().decideDestinationUsingResponse = ^(WKDownload *download, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {

            retainedDelegate = adoptNS([TestDownloadDelegate new]);
            download.delegate = retainedDelegate.get();

            retainedDelegate.get().didFailWithError = ^(WKDownload *, NSError *error, NSData *) {
                EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
                EXPECT_EQ(error.code, NSURLErrorCannotCreateFile);
                failed = true;
            };

            completionHandler(expectedDownloadFile);
        };
    };
    [webView loadRequest:server.request()];
    Util::run(&failed);

    checkCallbackRecord(retainedDelegate.get(), {
        DownloadCallback::DidFailWithError,
    });
}

TEST(WKDownload, DestinationNullString)
{
    auto server = downloadTestServer();
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];

    __block bool failed = false;
    delegate.get().navigationResponseDidBecomeDownload = ^(WKWebView *, WKNavigationResponse *, WKDownload *download) {
        download.delegate = delegate.get();
        delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {
            completionHandler(nil);
        };
        delegate.get().didFailWithError = ^(WKDownload *, NSError *error, NSData *) {
            EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
            EXPECT_EQ(error.code, NSURLErrorCancelled);
            failed = true;
        };
    };
    [webView loadRequest:server.request()];
    Util::run(&failed);
    checkCallbackRecord(delegate.get(), {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationResponseBecameDownload,
        DownloadCallback::DecideDestination,
        DownloadCallback::DidFailWithError
    });
}

TEST(WKDownload, ChallengeSuccess)
{
    HTTPServer server({{ "/", { "download content" }}}, HTTPServer::Protocol::Https);
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    __block bool finished = false;
    delegate.get().downloadDidFinish = ^(WKDownload *download) {
        finished = true;
    };
    __block bool receivedChallenge = false;
    delegate.get().didReceiveAuthenticationChallenge = ^(WKDownload *, NSURLAuthenticationChallenge *challenge, void (^completionHandler)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
        EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
        completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
        receivedChallenge = true;
    };
    delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) {
        completionHandler(expectedDownloadFile);
    };
    [webView startDownloadUsingRequest:server.request() completionHandler:^(WKDownload *download) {
        download.delegate = delegate.get();
    }];
    Util::run(&finished);
    EXPECT_TRUE(receivedChallenge);
    checkFileContents(expectedDownloadFile, "download content");
    checkCallbackRecord(delegate.get(), {
        DownloadCallback::AuthenticationChallenge,
        DownloadCallback::DecideDestination,
        DownloadCallback::DidFinish
    });
}

TEST(WKDownload, ChallengeFailure)
{
    HTTPServer server({ }, HTTPServer::Protocol::Https);
    auto delegate = adoptNS([TestDownloadDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    __block bool failed = false;
    delegate.get().didFailWithError = ^(WKDownload *download, NSError *error, NSData *resumeData) {
        EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
        EXPECT_EQ(error.code, NSURLErrorCancelled);
        failed = true;
    };
    __block bool receivedChallenge = false;
    delegate.get().didReceiveAuthenticationChallenge = ^(WKDownload *, NSURLAuthenticationChallenge *challenge, void (^completionHandler)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
        EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
        completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
        receivedChallenge = true;
    };
    [webView startDownloadUsingRequest:server.request() completionHandler:^(WKDownload *download) {
        download.delegate = delegate.get();
    }];
    Util::run(&failed);
    EXPECT_TRUE(receivedChallenge);
    checkCallbackRecord(delegate.get(), {
        DownloadCallback::AuthenticationChallenge,
        DownloadCallback::DidFailWithError
    });
}

void blobTest(bool downloadFromNavigationAction, std::initializer_list<DownloadCallback> expectedCallbacks)
{
    NSString *html = @"<script>"
    "function downloadBlob() {"
    "    var a = document.createElement('a');"
    "    var b = new Blob([1,2,3]);"
    "    a.href = URL.createObjectURL(b);"
    "    a.download = 'downloadFilename';"
    "    a.click();"
    "}"
    "</script><body onload='downloadBlob()'></body>";
    NSURL *expectedDownloadFile = tempFileThatDoesNotExist();
    auto webView = adoptNS([WKWebView new]);
    [webView loadHTMLString:html baseURL:nil];
    auto delegate = adoptNS([TestDownloadDelegate new]);
    [webView setNavigationDelegate:delegate.get()];
    delegate.get().decidePolicyForNavigationAction = ^(WKNavigationAction *action, void (^completionHandler)(WKNavigationActionPolicy)) {
        if ([action.request.URL.absoluteString isEqualToString:@"about:blank"])
            EXPECT_FALSE(action.shouldPerformDownload);
        else {
            EXPECT_WK_STREQ(action.request.URL.scheme, "blob");
            EXPECT_TRUE(action.shouldPerformDownload);
            if (downloadFromNavigationAction) {
                completionHandler(WKNavigationActionPolicyDownload);
                return;
            }
        }
        completionHandler(WKNavigationActionPolicyAllow);
    };
    delegate.get().navigationActionDidBecomeDownload = ^(WKWebView *, WKNavigationAction *action, WKDownload *download) {
        EXPECT_WK_STREQ(action.request.URL.scheme, "blob");
        EXPECT_WK_STREQ(download.originalRequest.URL.scheme, "blob");
        download.delegate = delegate.get();
    };
    delegate.get().navigationResponseDidBecomeDownload = ^(WKWebView *, WKNavigationResponse *response, WKDownload *download) {
        EXPECT_WK_STREQ(response.response.URL.scheme, "blob");
        EXPECT_WK_STREQ(download.originalRequest.URL.scheme, "blob");
        download.delegate = delegate.get();
    };
    delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *response, NSString *suggestedFilename, void (^completionHandler)(NSURL *)) {
        EXPECT_WK_STREQ(response.URL.scheme, "blob");
        EXPECT_WK_STREQ(suggestedFilename, "downloadFilename");
        completionHandler(expectedDownloadFile);
    };
    __block bool done = false;
    delegate.get().downloadDidFinish = ^(WKDownload *) {
        done = true;
    };
    Util::run(&done);

    checkFileContents(expectedDownloadFile, "123");
    checkCallbackRecord(delegate.get(), expectedCallbacks);
}

TEST(WKDownload, BlobResponse)
{
    blobTest(false, {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationResponseBecameDownload,
        DownloadCallback::DecideDestination,
        DownloadCallback::DidFinish
    });

    blobTest(true, {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationActionBecameDownload,
        DownloadCallback::DecideDestination,
        DownloadCallback::DidFinish
    });
}

TEST(WKDownload, BlobResponseNoFilename)
{
    NSString *html = @"<script>"
    "function downloadBlob() {"
    "    var a = document.createElement('a');"
    "    var b = new Blob([1,2,3]);"
    "    a.href = URL.createObjectURL(b);"
    "    a.click();"
    "}"
    "</script><body onload='downloadBlob()'></body>";
    auto webView = adoptNS([WKWebView new]);
    [webView loadHTMLString:html baseURL:[NSURL URLWithString:@"https://webkit.org/"]];
    auto delegate = adoptNS([TestDownloadDelegate new]);
    [webView setNavigationDelegate:delegate.get()];
    delegate.get().decidePolicyForNavigationAction = ^(WKNavigationAction *action, void (^completionHandler)(WKNavigationActionPolicy)) {
        EXPECT_FALSE(action.shouldPerformDownload);
        completionHandler(WKNavigationActionPolicyAllow);
    };
    delegate.get().navigationResponseDidBecomeDownload = ^(WKWebView *, WKNavigationResponse *response, WKDownload *download) {
        EXPECT_WK_STREQ(response.response.URL.scheme, "blob");
        EXPECT_WK_STREQ(response._frame.securityOrigin.host, "webkit.org");
        download.delegate = delegate.get();
    };
    __block bool done = false;
    delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *response, NSString *suggestedFilename, void (^completionHandler)(NSURL *)) {
        EXPECT_WK_STREQ(response.URL.scheme, "blob");
        EXPECT_WK_STREQ(suggestedFilename, "Unknown");
        completionHandler(nil);
        done = true;
    };
    Util::run(&done);
    checkCallbackRecord(delegate.get(), {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationResponseBecameDownload,
        DownloadCallback::DecideDestination
    });
}

TEST(WKDownload, SubframeOriginator)
{
    const char* grandchildFrameHTML = "<script>"
    "function downloadBlob() {"
    "    var a = document.createElement('a');"
    "    var b = new Blob([1,2,3]);"
    "    a.href = URL.createObjectURL(b);"
    "    a.click();"
    "}"
    "</script><body onload='downloadBlob()'></body>";
    HTTPServer grandchildFrameServer({
        { "/", { grandchildFrameHTML } }
    });
    HTTPServer childFrameServer({
        { "/", { [NSString stringWithFormat:@"<iframe src='http://127.0.0.1:%d/'></iframe>", grandchildFrameServer.port()] } }
    });
    NSURLRequest *grandchildFrameServerRequest = grandchildFrameServer.request();
    NSURLRequest *childFrameServerRequest = childFrameServer.request();
    uint16_t grandchildFrameServerPort = grandchildFrameServer.port();

    NSString *mainHTML = [NSString stringWithFormat:@"<iframe src='http://127.0.0.1:%d/'></iframe>", childFrameServer.port()];

    auto webView = adoptNS([WKWebView new]);
    [webView loadHTMLString:mainHTML baseURL:[NSURL URLWithString:@"http://webkit.org/"]];

    auto delegate = adoptNS([TestDownloadDelegate new]);
    [webView setNavigationDelegate:delegate.get()];
    delegate.get().decidePolicyForNavigationResponse = ^(WKNavigationResponse *response, void (^completionHandler)(WKNavigationResponsePolicy)) {
        if ([response.response.URL.absoluteString isEqualToString:@"http://webkit.org/"]
            || [response.response.URL.absoluteString isEqualToString:childFrameServerRequest.URL.absoluteString]
            || [response.response.URL.absoluteString isEqualToString:grandchildFrameServerRequest.URL.absoluteString])
            completionHandler(WKNavigationResponsePolicyAllow);
        else
            completionHandler(WKNavigationResponsePolicyDownload);
    };
    delegate.get().navigationResponseDidBecomeDownload = ^(WKWebView *, WKNavigationResponse *response, WKDownload *download) {
        EXPECT_WK_STREQ(response.response.URL.scheme, "blob");
        EXPECT_WK_STREQ(response._frame.securityOrigin.host, "127.0.0.1");
        EXPECT_EQ(response._frame.securityOrigin.port, grandchildFrameServerPort);
        download.delegate = delegate.get();
    };
    __block bool done = false;
    delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *response, NSString *suggestedFilename, void (^completionHandler)(NSURL *)) {
        EXPECT_WK_STREQ(response.URL.scheme, "blob");
        EXPECT_WK_STREQ(suggestedFilename, "Unknown");
        completionHandler(nil);
        done = true;
    };
    Util::run(&done);
    checkCallbackRecord(delegate.get(), {
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationAction,
        DownloadCallback::NavigationResponse,
        DownloadCallback::NavigationResponseBecameDownload,
        DownloadCallback::DecideDestination
    });
}

}
