<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[166186] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/166186">166186</a></dd>
<dt>Author</dt> <dd>aestes@apple.com</dd>
<dt>Date</dt> <dd>2014-03-24 12:44:35 -0700 (Mon, 24 Mar 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[iOS] Download support by CFURLDownloadRef under USE(CFNETWORK).
https://bugs.webkit.org/show_bug.cgi?id=129322

Reviewed by Anders Carlsson.

Source/WebCore:

* platform/network/ResourceHandle.h:
* platform/network/cf/ResourceHandleCFNet.cpp:
(WebCore::ResourceHandle::releaseConnectionForDownload): Changed to
return a RetainPtr that adopts the connection's retain count.

Source/WebKit/mac:

* WebCoreSupport/WebFrameLoaderClient.mm:
(WebFrameLoaderClient::convertMainResourceLoadToDownload): Use the
RetainPtr returned by releaseConnectionForDownload() rather than
manually releasing.

Source/WebKit2:

Based on an original patch by Yongjun Zhang  &lt;yongjun_zhang@apple.com&gt;.

* Shared/Cocoa/APIObject.mm:
(API::Object::newObject):
* Shared/Downloads/ios/DownloadIOS.mm:
(WebKit::dispatchOnMainThread):
(WebKit::toDownload):
(WebKit::setUpDownloadClient):
(WebKit::Download::startWithHandle):
* UIProcess/API/APIDownloadClient.h:
(API::DownloadClient::~DownloadClient):
* UIProcess/API/C/WKContext.cpp:
(WKContextSetDownloadClient):
* UIProcess/API/Cocoa/WKProcessPool.mm:
(-[WKProcessPool _downloadDelegate]):
(-[WKProcessPool _setDownloadDelegate:]):
* UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
* UIProcess/API/Cocoa/_WKDownload.h: Added.
* UIProcess/API/Cocoa/_WKDownload.mm: Added.
(WebKit::wrapper):
(WebKit::createAPIDownloadClient):
(-[_WKDownload dealloc]):
(-[_WKDownload API::]):
* UIProcess/API/Cocoa/_WKDownloadDelegate.h: Added.
* UIProcess/API/Cocoa/_WKDownloadInternal.h: Added.
* UIProcess/Cocoa/DownloadClient.h: Added.
* UIProcess/Cocoa/DownloadClient.mm: Added.
* WebKit2.xcodeproj/project.pbxproj:

Tools:

Add an API test suite for _WKDownload.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit2Cocoa/Download.mm: Added.
(-[DownloadDelegate initWithSourceURL:]):
(-[DownloadDelegate sourceURL]):
(-[DownloadDelegate _downloadDidStart:]):
(-[DownloadDelegate _download:didReceiveResponse:]):
(-[DownloadDelegate _download:didReceiveData:]):
(-[DownloadDelegate _download:decideDestinationWithSuggestedFilename:allowOverwrite:]):
(-[DownloadDelegate _downloadDidFinish:]):
(TEST):
(runTestWithNavigationDelegate):
(-[DownloadNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
(-[ConvertResponseToDownloadNavigationDelegate webView:decidePolicyForNavigationResponse:decisionHandler:]):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkResourceHandleh">trunk/Source/WebCore/platform/network/ResourceHandle.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcfResourceHandleCFNetcpp">trunk/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp</a></li>
<li><a href="#trunkSourceWebKitmacChangeLog">trunk/Source/WebKit/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitmacWebCoreSupportWebFrameLoaderClientmm">trunk/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2SharedCocoaAPIObjectmm">trunk/Source/WebKit2/Shared/Cocoa/APIObject.mm</a></li>
<li><a href="#trunkSourceWebKit2SharedDownloadsiosDownloadIOSmm">trunk/Source/WebKit2/Shared/Downloads/ios/DownloadIOS.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIAPIDownloadClienth">trunk/Source/WebKit2/UIProcess/API/APIDownloadClient.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICWKContextcpp">trunk/Source/WebKit2/UIProcess/API/C/WKContext.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKProcessPoolmm">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKProcessPool.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKProcessPoolPrivateh">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKProcessPoolPrivate.h</a></li>
<li><a href="#trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj">trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj">trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoa_WKDownloadh">trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKDownload.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoa_WKDownloadmm">trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKDownload.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoa_WKDownloadDelegateh">trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKDownloadDelegate.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoa_WKDownloadInternalh">trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKDownloadInternal.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessCocoaDownloadClienth">trunk/Source/WebKit2/UIProcess/Cocoa/DownloadClient.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessCocoaDownloadClientmm">trunk/Source/WebKit2/UIProcess/Cocoa/DownloadClient.mm</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKit2CocoaDownloadmm">trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/Download.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (166185 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-03-24 19:31:08 UTC (rev 166185)
+++ trunk/Source/WebCore/ChangeLog        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2014-03-24  Andy Estes  &lt;aestes@apple.com&gt;
+
+        [iOS] Download support by CFURLDownloadRef under USE(CFNETWORK).
+        https://bugs.webkit.org/show_bug.cgi?id=129322
+
+        Reviewed by Anders Carlsson.
+
+        * platform/network/ResourceHandle.h:
+        * platform/network/cf/ResourceHandleCFNet.cpp:
+        (WebCore::ResourceHandle::releaseConnectionForDownload): Changed to
+        return a RetainPtr that adopts the connection's retain count.
+
</ins><span class="cx"> 2014-03-24  Enrica Casucci  &lt;enrica@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Update Hindi fallback font.
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkResourceHandleh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/ResourceHandle.h (166185 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/ResourceHandle.h        2014-03-24 19:31:08 UTC (rev 166185)
+++ trunk/Source/WebCore/platform/network/ResourceHandle.h        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -138,7 +138,7 @@
</span><span class="cx"> #if USE(CFNETWORK)
</span><span class="cx">     CFURLStorageSessionRef storageSession() const;
</span><span class="cx">     CFURLConnectionRef connection() const;
</span><del>-    CFURLConnectionRef releaseConnectionForDownload();
</del><ins>+    RetainPtr&lt;CFURLConnectionRef&gt; releaseConnectionForDownload();
</ins><span class="cx">     const ResourceRequest&amp; currentRequest() const;
</span><span class="cx">     static void setHostAllowsAnyHTTPSCertificate(const String&amp;);
</span><span class="cx">     static void setClientCertificate(const String&amp; host, CFDataRef);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcfResourceHandleCFNetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp (166185 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp        2014-03-24 19:31:08 UTC (rev 166185)
+++ trunk/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -460,10 +460,10 @@
</span><span class="cx">     return d-&gt;m_connection.get();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-CFURLConnectionRef ResourceHandle::releaseConnectionForDownload()
</del><ins>+RetainPtr&lt;CFURLConnectionRef&gt; ResourceHandle::releaseConnectionForDownload()
</ins><span class="cx"> {
</span><span class="cx">     LOG(Network, &quot;CFNet - Job %p releasing connection %p for download&quot;, this, d-&gt;m_connection.get());
</span><del>-    return d-&gt;m_connection.leakRef();
</del><ins>+    return std::move(d-&gt;m_connection);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> CFStringRef ResourceHandle::synchronousLoadRunLoopMode()
</span></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (166185 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2014-03-24 19:31:08 UTC (rev 166185)
+++ trunk/Source/WebKit/mac/ChangeLog        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2014-03-24  Andy Estes  &lt;aestes@apple.com&gt;
+
+        [iOS] Download support by CFURLDownloadRef under USE(CFNETWORK).
+        https://bugs.webkit.org/show_bug.cgi?id=129322
+
+        Reviewed by Anders Carlsson.
+
+        * WebCoreSupport/WebFrameLoaderClient.mm:
+        (WebFrameLoaderClient::convertMainResourceLoadToDownload): Use the
+        RetainPtr returned by releaseConnectionForDownload() rather than
+        manually releasing.
+
</ins><span class="cx"> 2014-03-24  Jon Lee  &lt;jonlee@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Build fixes.
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebFrameLoaderClientmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm (166185 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm        2014-03-24 19:31:08 UTC (rev 166185)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -330,22 +330,10 @@
</span><span class="cx"> 
</span><span class="cx"> #if USE(CFNETWORK)
</span><span class="cx">     ASSERT([WebDownload respondsToSelector:@selector(_downloadWithLoadingCFURLConnection:request:response:delegate:proxy:)]);
</span><del>-    CFURLConnectionRef connection = handle-&gt;connection();
-    [WebDownload _downloadWithLoadingCFURLConnection:connection
-                                                                     request:request.cfURLRequest(UpdateHTTPBody)
-                                                                    response:response.cfURLResponse()
-                                                                    delegate:[webView downloadDelegate]
-                                                                       proxy:nil];
-
-    // Release the connection since the NSURLDownload (actually CFURLDownload) will retain the connection and use it.
-    handle-&gt;releaseConnectionForDownload();
-    CFRelease(connection);
</del><ins>+    auto connection = handle-&gt;releaseConnectionForDownload();
+    [WebDownload _downloadWithLoadingCFURLConnection:connection.get() request:request.cfURLRequest(UpdateHTTPBody) response:response.cfURLResponse() delegate:[webView downloadDelegate] proxy:nil];
</ins><span class="cx"> #else
</span><del>-    [WebDownload _downloadWithLoadingConnection:handle-&gt;connection()
-                                                                request:request.nsURLRequest(UpdateHTTPBody)
-                                                               response:response.nsURLResponse()
-                                                               delegate:[webView downloadDelegate]
-                                                                  proxy:nil];
</del><ins>+    [WebDownload _downloadWithLoadingConnection:handle-&gt;connection() request:request.nsURLRequest(UpdateHTTPBody) response:response.nsURLResponse() delegate:[webView downloadDelegate] proxy:nil];
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (166185 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-03-24 19:31:08 UTC (rev 166185)
+++ trunk/Source/WebKit2/ChangeLog        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -1,3 +1,39 @@
</span><ins>+2014-03-24  Andy Estes  &lt;aestes@apple.com&gt;
+
+        [iOS] Download support by CFURLDownloadRef under USE(CFNETWORK).
+        https://bugs.webkit.org/show_bug.cgi?id=129322
+
+        Reviewed by Anders Carlsson.
+
+        Based on an original patch by Yongjun Zhang  &lt;yongjun_zhang@apple.com&gt;.
+
+        * Shared/Cocoa/APIObject.mm:
+        (API::Object::newObject):
+        * Shared/Downloads/ios/DownloadIOS.mm:
+        (WebKit::dispatchOnMainThread):
+        (WebKit::toDownload):
+        (WebKit::setUpDownloadClient):
+        (WebKit::Download::startWithHandle):
+        * UIProcess/API/APIDownloadClient.h:
+        (API::DownloadClient::~DownloadClient):
+        * UIProcess/API/C/WKContext.cpp:
+        (WKContextSetDownloadClient):
+        * UIProcess/API/Cocoa/WKProcessPool.mm:
+        (-[WKProcessPool _downloadDelegate]):
+        (-[WKProcessPool _setDownloadDelegate:]):
+        * UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
+        * UIProcess/API/Cocoa/_WKDownload.h: Added.
+        * UIProcess/API/Cocoa/_WKDownload.mm: Added.
+        (WebKit::wrapper):
+        (WebKit::createAPIDownloadClient):
+        (-[_WKDownload dealloc]):
+        (-[_WKDownload API::]):
+        * UIProcess/API/Cocoa/_WKDownloadDelegate.h: Added.
+        * UIProcess/API/Cocoa/_WKDownloadInternal.h: Added.
+        * UIProcess/Cocoa/DownloadClient.h: Added.
+        * UIProcess/Cocoa/DownloadClient.mm: Added.
+        * WebKit2.xcodeproj/project.pbxproj:
+
</ins><span class="cx"> 2014-03-24  Dániel Bátyai  &lt;dbatyai.u-szeged@partner.samsung.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [EFL][WK2] Buildfix after r166159.
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedCocoaAPIObjectmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/Cocoa/APIObject.mm (166185 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/Cocoa/APIObject.mm        2014-03-24 19:31:08 UTC (rev 166185)
+++ trunk/Source/WebKit2/Shared/Cocoa/APIObject.mm        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if WK_API_ENABLED
</span><span class="cx"> 
</span><ins>+#import &quot;_WKDownloadInternal.h&quot;
</ins><span class="cx"> #import &quot;WKBackForwardListInternal.h&quot;
</span><span class="cx"> #import &quot;WKBackForwardListItemInternal.h&quot;
</span><span class="cx"> #import &quot;WKBrowsingContextControllerInternal.h&quot;
</span><span class="lines">@@ -113,6 +114,10 @@
</span><span class="cx">         wrapper = [WKNSDictionary alloc];
</span><span class="cx">         break;
</span><span class="cx"> 
</span><ins>+    case Type::Download:
+        wrapper = [_WKDownload alloc];
+        break;
+
</ins><span class="cx">     case Type::Error:
</span><span class="cx">         wrapper = NSAllocateObject([WKNSError self], size, nullptr);
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedDownloadsiosDownloadIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/Downloads/ios/DownloadIOS.mm (166185 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/Downloads/ios/DownloadIOS.mm        2014-03-24 19:31:08 UTC (rev 166185)
+++ trunk/Source/WebKit2/Shared/Downloads/ios/DownloadIOS.mm        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -28,20 +28,110 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx"> 
</span><ins>+#import &quot;DataReference.h&quot;
+#import &lt;CFNetwork/CFURLDownload.h&gt;
</ins><span class="cx"> #import &lt;WebCore/NotImplemented.h&gt;
</span><ins>+#import &lt;WebCore/ResourceError.h&gt;
+#import &lt;WebCore/ResourceHandle.h&gt;
+#import &lt;WebCore/ResourceResponse.h&gt;
+#import &lt;wtf/RetainPtr.h&gt;
+#import &lt;wtf/RunLoop.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> using namespace WebCore;
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><del>-    
</del><ins>+
+// FIXME: If possible, we should consider moving some callbacks off the main thread or at least
+// making them asynchonous calls.
+static void dispatchOnMainThread(void(^block)())
+{
+    if (RunLoop::isMain()) {
+        block();
+        return;
+    }
+
+    dispatch_sync(dispatch_get_main_queue(), block);
+}
+
+static inline Download* toDownload(const void* clientInfo)
+{
+    return static_cast&lt;Download*&gt;(const_cast&lt;void*&gt;(clientInfo));
+}
+
+static void setUpDownloadClient(CFURLDownloadClient&amp; client, Download&amp; download)
+{
+    memset(&amp;client, 0, sizeof(client));
+    client.clientInfo = &amp;download;
+
+    client.didStart = [](CFURLDownloadRef, const void* clientInfo) {
+        dispatchOnMainThread(^{
+            toDownload(clientInfo)-&gt;didStart();
+        });
+    };
+
+    client.willSendRequest = [](CFURLDownloadRef, CFURLRequestRef request, CFURLResponseRef, const void*) -&gt; CFURLRequestRef {
+        return CFRetain(request);
+    };
+
+    client.didReceiveResponse = [](CFURLDownloadRef, CFURLResponseRef response, const void* clientInfo) {
+        dispatchOnMainThread(^{
+            toDownload(clientInfo)-&gt;didReceiveResponse(response);
+        });
+    };
+
+    client.didReceiveData = [](CFURLDownloadRef, CFIndex length, const void* clientInfo) {
+        dispatchOnMainThread(^{
+            toDownload(clientInfo)-&gt;didReceiveData(length);
+        });
+    };
+
+    client.shouldDecodeDataOfMIMEType = [](CFURLDownloadRef, CFStringRef encodingType, const void* clientInfo) -&gt; Boolean {
+        __block BOOL returnValue = NO;
+        dispatchOnMainThread(^{
+            returnValue = toDownload(clientInfo)-&gt;shouldDecodeSourceDataOfMIMEType(encodingType);
+        });
+        return returnValue;
+    };
+
+    client.decideDestinationWithSuggestedObjectName = [](CFURLDownloadRef downloadRef, CFStringRef objectName, const void* clientInfo) {
+        dispatchOnMainThread(^{
+            BOOL allowOverwrite;
+            String destination = toDownload(clientInfo)-&gt;decideDestinationWithSuggestedFilename(objectName, allowOverwrite);
+            if (!destination.isNull())
+                CFURLDownloadSetDestination(downloadRef, reinterpret_cast&lt;CFURLRef&gt;([NSURL fileURLWithPath:destination]), allowOverwrite);
+        });
+    };
+
+    client.didCreateDestination = [](CFURLDownloadRef, CFURLRef path, const void* clientInfo) {
+        dispatchOnMainThread(^{
+            toDownload(clientInfo)-&gt;didCreateDestination(CFURLGetString(path));
+        });
+    };
+
+    client.didFinish = [](CFURLDownloadRef, const void* clientInfo) {
+        dispatchOnMainThread(^{
+            toDownload(clientInfo)-&gt;didFinish();
+        });
+    };
+
+    client.didFail = [](CFURLDownloadRef downloadRef, CFErrorRef error, const void* clientInfo) {
+        dispatchOnMainThread(^{
+            auto resumeData = adoptCF(CFURLDownloadCopyResumeData(downloadRef));
+            toDownload(clientInfo)-&gt;didFail(error, IPC::DataReference(CFDataGetBytePtr(resumeData.get()), CFDataGetLength(resumeData.get())));
+        });
+    };
+}
+
</ins><span class="cx"> void Download::start()
</span><span class="cx"> {
</span><span class="cx">     notImplemented();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Download::startWithHandle(ResourceHandle*, const ResourceResponse&amp;)
</del><ins>+void Download::startWithHandle(ResourceHandle* handle, const ResourceResponse&amp; response)
</ins><span class="cx"> {
</span><del>-    notImplemented();
</del><ins>+    CFURLDownloadClient client;
+    setUpDownloadClient(client, *this);
+    m_download = adoptCF(CFURLDownloadCreateAndStartWithLoadingConnection(NULL, handle-&gt;releaseConnectionForDownload().get(), m_request.cfURLRequest(UpdateHTTPBody), response.cfURLResponse(), &amp;client));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Download::cancel()
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIAPIDownloadClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/APIDownloadClient.h (166185 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/APIDownloadClient.h        2014-03-24 19:31:08 UTC (rev 166185)
+++ trunk/Source/WebKit2/UIProcess/API/APIDownloadClient.h        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -29,31 +29,28 @@
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><del>-class ResourceResponse;
</del><span class="cx"> class ResourceError;
</span><ins>+class ResourceResponse;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="cx"> class AuthenticationChallengeProxy;
</span><del>-class WebContext;
</del><span class="cx"> class DownloadProxy;
</span><ins>+class WebContext;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> namespace API {
</span><span class="cx"> 
</span><span class="cx"> class DownloadClient {
</span><span class="cx"> public:
</span><del>-    virtual ~DownloadClient()   { }
</del><ins>+    virtual ~DownloadClient() { }
</ins><span class="cx"> 
</span><span class="cx">     virtual void didStart(WebKit::WebContext*, WebKit::DownloadProxy*) { }
</span><span class="cx">     virtual void didReceiveAuthenticationChallenge(WebKit::WebContext*, WebKit::DownloadProxy*, WebKit::AuthenticationChallengeProxy*) { }
</span><span class="cx">     virtual void didReceiveResponse(WebKit::WebContext*, WebKit::DownloadProxy*, const WebCore::ResourceResponse&amp;) { }
</span><span class="cx">     virtual void didReceiveData(WebKit::WebContext*, WebKit::DownloadProxy*, uint64_t length) { }
</span><span class="cx">     virtual bool shouldDecodeSourceDataOfMIMEType(WebKit::WebContext*, WebKit::DownloadProxy*, const WTF::String&amp; mimeType) { return true; }
</span><del>-    virtual WTF::String decideDestinationWithSuggestedFilename(WebKit::WebContext*, WebKit::DownloadProxy*, const WTF::String&amp; filename, bool&amp; allowOverwrite)
-    {
-        return WTF::String();
-    }
</del><ins>+    virtual WTF::String decideDestinationWithSuggestedFilename(WebKit::WebContext*, WebKit::DownloadProxy*, const WTF::String&amp; filename, bool&amp; allowOverwrite) { return {}; }
</ins><span class="cx">     virtual void didCreateDestination(WebKit::WebContext*, WebKit::DownloadProxy*, const WTF::String&amp; path) { }
</span><span class="cx">     virtual void didFinish(WebKit::WebContext*, WebKit::DownloadProxy*) { }
</span><span class="cx">     virtual void didFail(WebKit::WebContext*, WebKit::DownloadProxy*, const WebCore::ResourceError&amp;) { }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICWKContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/C/WKContext.cpp (166185 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/C/WKContext.cpp        2014-03-24 19:31:08 UTC (rev 166185)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKContext.cpp        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -170,7 +170,7 @@
</span><span class="cx">         virtual void didStart(WebContext* webContext, DownloadProxy* downloadProxy) override
</span><span class="cx">         {
</span><span class="cx">             if (!m_client.didStart)
</span><del>-            return;
</del><ins>+                return;
</ins><span class="cx"> 
</span><span class="cx">             m_client.didStart(toAPI(webContext), toAPI(downloadProxy), m_client.base.clientInfo);
</span><span class="cx">         }
</span><span class="lines">@@ -178,7 +178,7 @@
</span><span class="cx">         virtual void didReceiveAuthenticationChallenge(WebContext* webContext, DownloadProxy* downloadProxy, AuthenticationChallengeProxy* authenticationChallengeProxy) override
</span><span class="cx">         {
</span><span class="cx">             if (!m_client.didReceiveAuthenticationChallenge)
</span><del>-            return;
</del><ins>+                return;
</ins><span class="cx"> 
</span><span class="cx">             m_client.didReceiveAuthenticationChallenge(toAPI(webContext), toAPI(downloadProxy), toAPI(authenticationChallengeProxy), m_client.base.clientInfo);
</span><span class="cx">         }
</span><span class="lines">@@ -186,7 +186,7 @@
</span><span class="cx">         virtual void didReceiveResponse(WebContext* webContext, DownloadProxy* downloadProxy, const ResourceResponse&amp; response) override
</span><span class="cx">         {
</span><span class="cx">             if (!m_client.didReceiveResponse)
</span><del>-            return;
</del><ins>+                return;
</ins><span class="cx"> 
</span><span class="cx">             m_client.didReceiveResponse(toAPI(webContext), toAPI(downloadProxy), toAPI(API::URLResponse::create(response).get()), m_client.base.clientInfo);
</span><span class="cx">         }
</span><span class="lines">@@ -194,7 +194,7 @@
</span><span class="cx">         virtual void didReceiveData(WebContext* webContext, DownloadProxy* downloadProxy, uint64_t length) override
</span><span class="cx">         {
</span><span class="cx">             if (!m_client.didReceiveData)
</span><del>-            return;
</del><ins>+                return;
</ins><span class="cx"> 
</span><span class="cx">             m_client.didReceiveData(toAPI(webContext), toAPI(downloadProxy), length, m_client.base.clientInfo);
</span><span class="cx">         }
</span><span class="lines">@@ -202,7 +202,7 @@
</span><span class="cx">         virtual bool shouldDecodeSourceDataOfMIMEType(WebContext* webContext, DownloadProxy* downloadProxy, const String&amp; mimeType) override
</span><span class="cx">         {
</span><span class="cx">             if (!m_client.shouldDecodeSourceDataOfMIMEType)
</span><del>-            return true;
</del><ins>+                return true;
</ins><span class="cx"> 
</span><span class="cx">             return m_client.shouldDecodeSourceDataOfMIMEType(toAPI(webContext), toAPI(downloadProxy), toAPI(mimeType.impl()), m_client.base.clientInfo);
</span><span class="cx">         }
</span><span class="lines">@@ -210,7 +210,7 @@
</span><span class="cx">         virtual String decideDestinationWithSuggestedFilename(WebContext* webContext, DownloadProxy* downloadProxy, const String&amp; filename, bool&amp; allowOverwrite) override
</span><span class="cx">         {
</span><span class="cx">             if (!m_client.decideDestinationWithSuggestedFilename)
</span><del>-            return String();
</del><ins>+                return String();
</ins><span class="cx"> 
</span><span class="cx">             WKRetainPtr&lt;WKStringRef&gt; destination(AdoptWK, m_client.decideDestinationWithSuggestedFilename(toAPI(webContext), toAPI(downloadProxy), toAPI(filename.impl()), &amp;allowOverwrite, m_client.base.clientInfo));
</span><span class="cx">             return toWTFString(destination.get());
</span><span class="lines">@@ -219,7 +219,7 @@
</span><span class="cx">         virtual void didCreateDestination(WebContext* webContext, DownloadProxy* downloadProxy, const String&amp; path) override
</span><span class="cx">         {
</span><span class="cx">             if (!m_client.didCreateDestination)
</span><del>-            return;
</del><ins>+                return;
</ins><span class="cx"> 
</span><span class="cx">             m_client.didCreateDestination(toAPI(webContext), toAPI(downloadProxy), toAPI(path.impl()), m_client.base.clientInfo);
</span><span class="cx">         }
</span><span class="lines">@@ -227,7 +227,7 @@
</span><span class="cx">         virtual void didFinish(WebContext* webContext, DownloadProxy* downloadProxy) override
</span><span class="cx">         {
</span><span class="cx">             if (!m_client.didFinish)
</span><del>-            return;
</del><ins>+                return;
</ins><span class="cx"> 
</span><span class="cx">             m_client.didFinish(toAPI(webContext), toAPI(downloadProxy), m_client.base.clientInfo);
</span><span class="cx">         }
</span><span class="lines">@@ -235,7 +235,7 @@
</span><span class="cx">         virtual void didFail(WebContext* webContext, DownloadProxy* downloadProxy, const ResourceError&amp; error) override
</span><span class="cx">         {
</span><span class="cx">             if (!m_client.didFail)
</span><del>-            return;
</del><ins>+                return;
</ins><span class="cx"> 
</span><span class="cx">             m_client.didFail(toAPI(webContext), toAPI(downloadProxy), toAPI(error), m_client.base.clientInfo);
</span><span class="cx">         }
</span><span class="lines">@@ -243,7 +243,7 @@
</span><span class="cx">         virtual void didCancel(WebContext* webContext, DownloadProxy* downloadProxy) override
</span><span class="cx">         {
</span><span class="cx">             if (!m_client.didCancel)
</span><del>-            return;
</del><ins>+                return;
</ins><span class="cx">             
</span><span class="cx">             m_client.didCancel(toAPI(webContext), toAPI(downloadProxy), m_client.base.clientInfo);
</span><span class="cx">         }
</span><span class="lines">@@ -251,7 +251,7 @@
</span><span class="cx">         virtual void processDidCrash(WebContext* webContext, DownloadProxy* downloadProxy) override
</span><span class="cx">         {
</span><span class="cx">             if (!m_client.processDidCrash)
</span><del>-            return;
</del><ins>+                return;
</ins><span class="cx">             
</span><span class="cx">             m_client.processDidCrash(toAPI(webContext), toAPI(downloadProxy), m_client.base.clientInfo);
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKProcessPoolmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKProcessPool.mm (166185 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKProcessPool.mm        2014-03-24 19:31:08 UTC (rev 166185)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKProcessPool.mm        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -28,11 +28,14 @@
</span><span class="cx"> 
</span><span class="cx"> #if WK_API_ENABLED
</span><span class="cx"> 
</span><ins>+#import &quot;_WKDownloadDelegate.h&quot;
</ins><span class="cx"> #import &quot;CacheModel.h&quot;
</span><ins>+#import &quot;DownloadClient.h&quot;
</ins><span class="cx"> #import &quot;HistoryClient.h&quot;
</span><span class="cx"> #import &quot;ProcessModel.h&quot;
</span><span class="cx"> #import &quot;WKObject.h&quot;
</span><span class="cx"> #import &quot;WKProcessPoolConfigurationPrivate.h&quot;
</span><ins>+#import &quot;WeakObjCPtr.h&quot;
</ins><span class="cx"> #import &quot;WebCertificateInfo.h&quot;
</span><span class="cx"> #import &quot;WebContext.h&quot;
</span><span class="cx"> #import &quot;WebCookieManagerProxy.h&quot;
</span><span class="lines">@@ -58,7 +61,9 @@
</span><span class="cx"> @end
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-@implementation WKProcessPool
</del><ins>+@implementation WKProcessPool {
+    WebKit::WeakObjCPtr&lt;id &lt;_WKDownloadDelegate&gt;&gt; _downloadDelegate;
+}
</ins><span class="cx"> 
</span><span class="cx"> - (instancetype)init
</span><span class="cx"> {
</span><span class="lines">@@ -173,6 +178,17 @@
</span><span class="cx">     _context-&gt;sendToAllProcesses(Messages::WebProcess::SetInjectedBundleParameter(parameter, IPC::DataReference(static_cast&lt;const uint8_t*&gt;([data bytes]), [data length])));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (id &lt;_WKDownloadDelegate&gt;)_downloadDelegate
+{
+    return _downloadDelegate.getAutoreleased();
+}
+
+- (void)_setDownloadDelegate:(id &lt;_WKDownloadDelegate&gt;)downloadDelegate
+{
+    _downloadDelegate = downloadDelegate;
+    _context-&gt;setDownloadClient(std::make_unique&lt;WebKit::DownloadClient&gt;(downloadDelegate));
+}
+
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> #endif // WK_API_ENABLED
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKProcessPoolPrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKProcessPoolPrivate.h (166185 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKProcessPoolPrivate.h        2014-03-24 19:31:08 UTC (rev 166185)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKProcessPoolPrivate.h        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> #if WK_API_ENABLED
</span><span class="cx"> 
</span><span class="cx"> @class _WKProcessPoolConfiguration;
</span><ins>+@protocol _WKDownloadDelegate;
</ins><span class="cx"> 
</span><span class="cx"> @interface WKProcessPool (WKPrivate)
</span><span class="cx"> 
</span><span class="lines">@@ -41,6 +42,8 @@
</span><span class="cx"> - (id)_objectForBundleParameter:(NSString *)parameter;
</span><span class="cx"> - (void)_setObject:(id &lt;NSCopying, NSSecureCoding&gt;)object forBundleParameter:(NSString *)parameter;
</span><span class="cx"> 
</span><ins>+@property (nonatomic, weak, setter=_setDownloadDelegate:) id &lt;_WKDownloadDelegate&gt; _downloadDelegate;
+
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoa_WKDownloadhfromrev166185trunkSourceWebKit2UIProcessAPICocoaWKProcessPoolPrivateh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKDownload.h (from rev 166185, trunk/Source/WebKit2/UIProcess/API/Cocoa/WKProcessPoolPrivate.h) (0 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKDownload.h                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKDownload.h        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 &lt;WebKit2/WKFoundation.h&gt;
+
+#if WK_API_ENABLED
+
+#import &lt;Foundation/Foundation.h&gt;
+
+WK_API_CLASS
+@interface _WKDownload : NSObject
+
+@end
+
+#endif // WK_API_ENABLED
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoa_WKDownloadmmfromrev166185trunkSourceWebKit2UIProcessAPICocoaWKProcessPoolPrivateh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKDownload.mm (from rev 166185, trunk/Source/WebKit2/UIProcess/API/Cocoa/WKProcessPoolPrivate.h) (0 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKDownload.mm                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKDownload.mm        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -0,0 +1,53 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 &quot;config.h&quot;
+#import &quot;_WKDownloadInternal.h&quot;
+
+#if WK_API_ENABLED
+
+#import &quot;DownloadProxy.h&quot;
+
+@implementation _WKDownload {
+    API::ObjectStorage&lt;WebKit::DownloadProxy&gt; _download;
+}
+
+- (void)dealloc
+{
+    _download-&gt;~DownloadProxy();
+
+    [super dealloc];
+}
+
+#pragma mark WKObject protocol implementation
+
+- (API::Object&amp;)_apiObject
+{
+    return *_download;
+}
+
+@end
+
+#endif // WK_API_ENABLED
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoa_WKDownloadDelegatehfromrev166185trunkSourceWebKit2UIProcessAPICocoaWKProcessPoolPrivateh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKDownloadDelegate.h (from rev 166185, trunk/Source/WebKit2/UIProcess/API/Cocoa/WKProcessPoolPrivate.h) (0 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKDownloadDelegate.h                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKDownloadDelegate.h        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 &lt;WebKit2/WKFoundation.h&gt;
+
+#if WK_API_ENABLED
+
+#import &lt;Foundation/Foundation.h&gt;
+
+@class _WKDownload;
+
+@protocol _WKDownloadDelegate &lt;NSObject&gt;
+@optional
+- (void)_downloadDidStart:(_WKDownload *)download;
+- (void)_download:(_WKDownload *)download didReceiveResponse:(NSURLResponse *)response;
+- (void)_download:(_WKDownload *)download didReceiveData:(uint64_t)length;
+- (NSString *)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename allowOverwrite:(BOOL *)allowOverwrite;
+- (void)_downloadDidFinish:(_WKDownload *)download;
+@end
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoa_WKDownloadInternalhfromrev166185trunkSourceWebKit2UIProcessAPICocoaWKProcessPoolPrivateh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKDownloadInternal.h (from rev 166185, trunk/Source/WebKit2/UIProcess/API/Cocoa/WKProcessPoolPrivate.h) (0 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKDownloadInternal.h                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKDownloadInternal.h        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 &quot;_WKDownload.h&quot;
+
+#if WK_API_ENABLED
+
+#import &quot;WKObject.h&quot;
+
+@protocol _WKDownloadDelegate;
+
+namespace API {
+class DownloadClient;
+}
+
+namespace WebKit {
+std::unique_ptr&lt;API::DownloadClient&gt; createAPIDownloadClient(id &lt;_WKDownloadDelegate&gt;);
+}
+
+@interface _WKDownload () &lt;WKObject&gt;
+@end
+
+#endif // WK_API_ENABLED
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessCocoaDownloadClienthfromrev166185trunkSourceWebKit2UIProcessAPICocoaWKProcessPoolPrivateh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebKit2/UIProcess/Cocoa/DownloadClient.h (from rev 166185, trunk/Source/WebKit2/UIProcess/API/Cocoa/WKProcessPoolPrivate.h) (0 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Cocoa/DownloadClient.h                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/DownloadClient.h        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -0,0 +1,71 @@
</span><ins>+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef DownloadClient_h
+#define DownloadClient_h
+
+#import &quot;WKFoundation.h&quot;
+
+#if WK_API_ENABLED
+
+#import &quot;APIDownloadClient.h&quot;
+#import &quot;WeakObjCPtr.h&quot;
+
+@protocol _WKDownloadDelegate;
+
+namespace WebCore {
+class ResourceResponse;
+}
+
+namespace WebKit {
+    
+class DownloadClient final : public API::DownloadClient {
+public:
+    explicit DownloadClient(id &lt;_WKDownloadDelegate&gt;);
+    
+private:
+    // From API::DownloadClient
+    virtual void didStart(WebContext*, DownloadProxy*);
+    virtual void didReceiveResponse(WebContext*, DownloadProxy*, const WebCore::ResourceResponse&amp;);
+    virtual void didReceiveData(WebContext*, DownloadProxy*, uint64_t length);
+    virtual String decideDestinationWithSuggestedFilename(WebContext*, DownloadProxy*, const String&amp; filename, bool&amp; allowOverwriteParam);
+    virtual void didFinish(WebContext*, DownloadProxy*);
+
+    WeakObjCPtr&lt;id &lt;_WKDownloadDelegate&gt;&gt; m_delegate;
+
+    struct {
+        bool downloadDidStart : 1;            
+        bool downloadDidReceiveResponse : 1;
+        bool downloadDidReceiveData : 1;
+        bool downloadDecideDestinationWithSuggestedFilenameAllowOverwrite : 1;
+        bool downloadDidFinish : 1;
+    } m_delegateMethods;
+};
+
+} // namespace WebKit
+
+#endif
+
+#endif // DownloadClient_h
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessCocoaDownloadClientmm"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/Cocoa/DownloadClient.mm (0 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Cocoa/DownloadClient.mm                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/DownloadClient.mm        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -0,0 +1,91 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 &quot;config.h&quot;
+#import &quot;DownloadClient.h&quot;
+
+#if WK_API_ENABLED
+
+#import &quot;_WKDownloadDelegate.h&quot;
+#import &quot;_WKDownloadInternal.h&quot;
+#import &quot;DownloadProxy.h&quot;
+#import &lt;WebCore/ResourceResponse.h&gt;
+
+namespace WebKit {
+
+static inline _WKDownload *wrapper(DownloadProxy&amp; download)
+{
+    ASSERT([download.wrapper() isKindOfClass:[_WKDownload class]]);
+    return (_WKDownload *)download.wrapper();
+}
+
+DownloadClient::DownloadClient(id &lt;_WKDownloadDelegate&gt; delegate)
+    : m_delegate(delegate)
+{
+    m_delegateMethods.downloadDidStart = [delegate respondsToSelector:@selector(_downloadDidStart:)];
+    m_delegateMethods.downloadDidReceiveResponse = [delegate respondsToSelector:@selector(_download:didReceiveResponse:)];
+    m_delegateMethods.downloadDidReceiveData = [delegate respondsToSelector:@selector(_download:didReceiveData:)];
+    m_delegateMethods.downloadDecideDestinationWithSuggestedFilenameAllowOverwrite = [delegate respondsToSelector:@selector(_download:decideDestinationWithSuggestedFilename:allowOverwrite:)];
+    m_delegateMethods.downloadDidFinish = [delegate respondsToSelector:@selector(_downloadDidFinish:)];
+}
+
+void DownloadClient::didStart(WebContext*, DownloadProxy* downloadProxy)
+{
+    if (m_delegateMethods.downloadDidStart)
+        [m_delegate.get() _downloadDidStart:wrapper(*downloadProxy)];
+}
+
+void DownloadClient::didReceiveResponse(WebContext*, DownloadProxy* downloadProxy, const WebCore::ResourceResponse&amp; response)
+{
+    if (m_delegateMethods.downloadDidReceiveResponse)
+        [m_delegate.get() _download:wrapper(*downloadProxy) didReceiveResponse:response.nsURLResponse()];
+}
+
+void DownloadClient::didReceiveData(WebContext*, DownloadProxy* downloadProxy, uint64_t length)
+{
+    if (m_delegateMethods.downloadDidReceiveData)
+        [m_delegate.get() _download:wrapper(*downloadProxy) didReceiveData:length];
+}
+
+String DownloadClient::decideDestinationWithSuggestedFilename(WebContext*, DownloadProxy* downloadProxy, const String&amp; filename, bool&amp; allowOverwriteParam)
+{
+    if (!m_delegateMethods.downloadDecideDestinationWithSuggestedFilenameAllowOverwrite)
+        return String();
+    
+    BOOL allowOverwrite;
+    NSString *destination = [m_delegate.get() _download:wrapper(*downloadProxy) decideDestinationWithSuggestedFilename:filename allowOverwrite:&amp;allowOverwrite];
+    allowOverwriteParam = allowOverwrite;
+    return destination;
+}
+
+void DownloadClient::didFinish(WebContext*, DownloadProxy* downloadProxy)
+{
+    if (m_delegateMethods.downloadDidFinish)
+        [m_delegate.get() _downloadDidFinish:wrapper(*downloadProxy)];
+}
+
+} // namespace WebKit
+
+#endif // WK_API_ENABLED
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (166185 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2014-03-24 19:31:08 UTC (rev 166185)
+++ trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -986,6 +986,12 @@
</span><span class="cx">                 9F54F8951648AE0F007DF81A /* PluginProcessManagerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9F54F8941648AE0E007DF81A /* PluginProcessManagerMac.mm */; };
</span><span class="cx">                 9FB5F394169E6A80002C25BF /* WKContextPrivateMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9FB5F392169E6A80002C25BF /* WKContextPrivateMac.mm */; };
</span><span class="cx">                 9FB5F395169E6A80002C25BF /* WKContextPrivateMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 9FB5F393169E6A80002C25BF /* WKContextPrivateMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                A1A4FE5A18DCE9FA00B5EA8A /* _WKDownload.h in Headers */ = {isa = PBXBuildFile; fileRef = A1A4FE5718DCE9FA00B5EA8A /* _WKDownload.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                A1A4FE5B18DCE9FA00B5EA8A /* _WKDownload.mm in Sources */ = {isa = PBXBuildFile; fileRef = A1A4FE5818DCE9FA00B5EA8A /* _WKDownload.mm */; };
+                A1A4FE5C18DCE9FA00B5EA8A /* _WKDownloadInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A1A4FE5918DCE9FA00B5EA8A /* _WKDownloadInternal.h */; };
+                A1A4FE6118DD54A400B5EA8A /* _WKDownloadDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A1A4FE6018DD54A400B5EA8A /* _WKDownloadDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                A1DF631218E0B7C8003A3E2A /* DownloadClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = A1DF631018E0B7C8003A3E2A /* DownloadClient.mm */; };
+                A1DF631318E0B7C8003A3E2A /* DownloadClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A1DF631118E0B7C8003A3E2A /* DownloadClient.h */; };
</ins><span class="cx">                 A5EFD38C16B0E88C00B2F0E8 /* WKPageVisibilityTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = A5EFD38B16B0E88C00B2F0E8 /* WKPageVisibilityTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 A7D792D61767CB6E00881CBE /* ActivityAssertion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7D792D51767CB6E00881CBE /* ActivityAssertion.cpp */; };
</span><span class="cx">                 A7D792D81767CCA300881CBE /* ActivityAssertion.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D792D41767CB0900881CBE /* ActivityAssertion.h */; };
</span><span class="lines">@@ -2805,6 +2811,12 @@
</span><span class="cx">                 9F54F8941648AE0E007DF81A /* PluginProcessManagerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PluginProcessManagerMac.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9FB5F392169E6A80002C25BF /* WKContextPrivateMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKContextPrivateMac.mm; path = mac/WKContextPrivateMac.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9FB5F393169E6A80002C25BF /* WKContextPrivateMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKContextPrivateMac.h; path = mac/WKContextPrivateMac.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                A1A4FE5718DCE9FA00B5EA8A /* _WKDownload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKDownload.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                A1A4FE5818DCE9FA00B5EA8A /* _WKDownload.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKDownload.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
+                A1A4FE5918DCE9FA00B5EA8A /* _WKDownloadInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKDownloadInternal.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                A1A4FE6018DD54A400B5EA8A /* _WKDownloadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKDownloadDelegate.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                A1DF631018E0B7C8003A3E2A /* DownloadClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DownloadClient.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
+                A1DF631118E0B7C8003A3E2A /* DownloadClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DownloadClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 A1EDD2D91884ACE000BBFE98 /* All.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = All.xcconfig; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A1EDD2DB1884B96400BBFE98 /* PluginProcessShim.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = PluginProcessShim.xcconfig; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A1EDD2DC1884B9B500BBFE98 /* SecItemShim.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = SecItemShim.xcconfig; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4182,16 +4194,18 @@
</span><span class="cx">                 1ABC3DF21899E415004F0626 /* Cocoa */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><del>-                                2D7AAFD218C8640600A7ACD4 /* WKWebViewContentProvider.h */,
-                                2DC6D9C118C44A610043BAD4 /* WKWebViewContentProviderRegistry.h */,
-                                2DC6D9C218C44A610043BAD4 /* WKWebViewContentProviderRegistry.mm */,
-                                0F0C365918C0555800F607D7 /* LayerRepresentation.h */,
</del><ins>+                                A1DF631118E0B7C8003A3E2A /* DownloadClient.h */,
+                                A1DF631018E0B7C8003A3E2A /* DownloadClient.mm */,
</ins><span class="cx">                                 1A422F8D18B29C6400D8CD96 /* HistoryClient.h */,
</span><span class="cx">                                 1A422F8C18B29C6400D8CD96 /* HistoryClient.mm */,
</span><ins>+                                0F0C365918C0555800F607D7 /* LayerRepresentation.h */,
</ins><span class="cx">                                 1ABC3DF41899E437004F0626 /* NavigationState.h */,
</span><span class="cx">                                 1ABC3DF31899E437004F0626 /* NavigationState.mm */,
</span><span class="cx">                                 1AFE436418B6C081009C7A48 /* UIClient.h */,
</span><span class="cx">                                 1AFE436318B6C081009C7A48 /* UIClient.mm */,
</span><ins>+                                2D7AAFD218C8640600A7ACD4 /* WKWebViewContentProvider.h */,
+                                2DC6D9C118C44A610043BAD4 /* WKWebViewContentProviderRegistry.h */,
+                                2DC6D9C218C44A610043BAD4 /* WKWebViewContentProviderRegistry.mm */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = Cocoa;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -4543,6 +4557,10 @@
</span><span class="cx">                                 37A5E01218BBF937000A081E /* _WKActivatedElementInfo.h */,
</span><span class="cx">                                 37A5E01118BBF937000A081E /* _WKActivatedElementInfo.mm */,
</span><span class="cx">                                 379A873518BBFA4300588AF2 /* _WKActivatedElementInfoInternal.h */,
</span><ins>+                                A1A4FE5718DCE9FA00B5EA8A /* _WKDownload.h */,
+                                A1A4FE5818DCE9FA00B5EA8A /* _WKDownload.mm */,
+                                A1A4FE6018DD54A400B5EA8A /* _WKDownloadDelegate.h */,
+                                A1A4FE5918DCE9FA00B5EA8A /* _WKDownloadInternal.h */,
</ins><span class="cx">                                 379A873818BBFE0F00588AF2 /* _WKElementAction.h */,
</span><span class="cx">                                 379A873718BBFE0F00588AF2 /* _WKElementAction.mm */,
</span><span class="cx">                                 379A873B18BBFF0700588AF2 /* _WKElementActionInternal.h */,
</span><span class="lines">@@ -6555,6 +6573,7 @@
</span><span class="cx">                                 C517388112DF8F4F00EE3F47 /* DragControllerAction.h in Headers */,
</span><span class="cx">                                 BC8452A81162C80900CAB9B5 /* DrawingArea.h in Headers */,
</span><span class="cx">                                 378E1A4A18208CD60031007A /* WKNSString.h in Headers */,
</span><ins>+                                A1A4FE5C18DCE9FA00B5EA8A /* _WKDownloadInternal.h in Headers */,
</ins><span class="cx">                                 2D8949F1182044F600E898AA /* PlatformCALayerRemoteTiledBacking.h in Headers */,
</span><span class="cx">                                 0FB659231208B4DB0044816C /* DrawingAreaInfo.h in Headers */,
</span><span class="cx">                                 26F9A83B18A3468100AEB88A /* WKWebViewPrivate.h in Headers */,
</span><span class="lines">@@ -6660,6 +6679,7 @@
</span><span class="cx">                                 51FD18B61651FBAD00DBE1CE /* NetworkResourceLoader.h in Headers */,
</span><span class="cx">                                 E152551B17011819003D7ADB /* NetworkResourceLoaderMessages.h in Headers */,
</span><span class="cx">                                 51CBBA10165219B6005BE8FD /* NetworkResourceLoadParameters.h in Headers */,
</span><ins>+                                A1DF631318E0B7C8003A3E2A /* DownloadClient.h in Headers */,
</ins><span class="cx">                                 51829DA61637C70C000953D6 /* NetworkResourceLoadScheduler.h in Headers */,
</span><span class="cx">                                 31A2EC5614899C0900810D71 /* NotificationPermissionRequest.h in Headers */,
</span><span class="cx">                                 3131261F148FF82C00BA2A39 /* NotificationPermissionRequestManager.h in Headers */,
</span><span class="lines">@@ -7039,6 +7059,7 @@
</span><span class="cx">                                 7CF47FFF17276AE3008ACB91 /* WKBundlePageBannerMac.h in Headers */,
</span><span class="cx">                                 BC7B633D12A45D1200D174A4 /* WKBundlePageGroup.h in Headers */,
</span><span class="cx">                                 ED82A7F2128C6FAF004477B3 /* WKBundlePageOverlay.h in Headers */,
</span><ins>+                                A1A4FE5A18DCE9FA00B5EA8A /* _WKDownload.h in Headers */,
</ins><span class="cx">                                 BC1B419811D41D570011E8DD /* WKBundlePagePrivate.h in Headers */,
</span><span class="cx">                                 BCF049E711FE20F600F86A58 /* WKBundlePrivate.h in Headers */,
</span><span class="cx">                                 BC60C5791240A546008C5E29 /* WKBundleRangeHandle.h in Headers */,
</span><span class="lines">@@ -7063,6 +7084,7 @@
</span><span class="cx">                                 1AE00D5D182DADE100087DD7 /* KeyedEncoder.h in Headers */,
</span><span class="cx">                                 3309345B1315B9980097A7BC /* WKCookieManager.h in Headers */,
</span><span class="cx">                                 512F58FA12A88A5400629530 /* WKCredential.h in Headers */,
</span><ins>+                                A1A4FE6118DD54A400B5EA8A /* _WKDownloadDelegate.h in Headers */,
</ins><span class="cx">                                 0FCB4E4618BBE044000FCFC9 /* PageClientImplIOS.h in Headers */,
</span><span class="cx">                                 518ACF1112B015F800B04B83 /* WKCredentialTypes.h in Headers */,
</span><span class="cx">                                 1AFDD3171891C94700153970 /* WKPreferences.h in Headers */,
</span><span class="lines">@@ -8217,6 +8239,7 @@
</span><span class="cx">                                 37183D56182F4E700080C811 /* WKNSURLExtras.mm in Sources */,
</span><span class="cx">                                 374436881820E7240049579F /* WKObject.mm in Sources */,
</span><span class="cx">                                 1A0F29E3120B44420053D1B9 /* VisitedLinkProvider.cpp in Sources */,
</span><ins>+                                A1DF631218E0B7C8003A3E2A /* DownloadClient.mm in Sources */,
</ins><span class="cx">                                 1A0F29CB120B37160053D1B9 /* VisitedLinkTable.cpp in Sources */,
</span><span class="cx">                                 1AC1337F18590AE400F3EC05 /* RemoteObjectRegistry.mm in Sources */,
</span><span class="cx">                                 CEDA12E2152CD1AE00D9E08D /* WebAlternativeTextClient.cpp in Sources */,
</span><span class="lines">@@ -8404,6 +8427,7 @@
</span><span class="cx">                                 BC3066BE125A442100E71278 /* WebProcessMessageReceiver.cpp in Sources */,
</span><span class="cx">                                 BC111B11112F5E4F00337BAB /* WebProcessProxy.cpp in Sources */,
</span><span class="cx">                                 51032F18180F73BB00961BB7 /* WebToDatabaseProcessConnection.cpp in Sources */,
</span><ins>+                                A1A4FE5B18DCE9FA00B5EA8A /* _WKDownload.mm in Sources */,
</ins><span class="cx">                                 51D130581382F10500351EDD /* WebProcessProxyMac.mm in Sources */,
</span><span class="cx">                                 BCEE7AD012817988009827DA /* WebProcessProxyMessageReceiver.cpp in Sources */,
</span><span class="cx">                                 512F589C12A8838800629530 /* WebProtectionSpace.cpp in Sources */,
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (166185 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2014-03-24 19:31:08 UTC (rev 166185)
+++ trunk/Tools/ChangeLog        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -1,3 +1,26 @@
</span><ins>+2014-03-24  Andy Estes  &lt;aestes@apple.com&gt;
+
+        [iOS] Download support by CFURLDownloadRef under USE(CFNETWORK).
+        https://bugs.webkit.org/show_bug.cgi?id=129322
+
+        Reviewed by Anders Carlsson.
+
+        Add an API test suite for _WKDownload.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKit2Cocoa/Download.mm: Added.
+        (-[DownloadDelegate initWithSourceURL:]):
+        (-[DownloadDelegate sourceURL]):
+        (-[DownloadDelegate _downloadDidStart:]):
+        (-[DownloadDelegate _download:didReceiveResponse:]):
+        (-[DownloadDelegate _download:didReceiveData:]):
+        (-[DownloadDelegate _download:decideDestinationWithSuggestedFilename:allowOverwrite:]):
+        (-[DownloadDelegate _downloadDidFinish:]):
+        (TEST):
+        (runTestWithNavigationDelegate):
+        (-[DownloadNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
+        (-[ConvertResponseToDownloadNavigationDelegate webView:decidePolicyForNavigationResponse:decisionHandler:]):
+
</ins><span class="cx"> 2014-03-24  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         filter-build-webkit: reduce unfiltered output
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (166185 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2014-03-24 19:31:08 UTC (rev 166185)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -142,6 +142,7 @@
</span><span class="cx">                 9B26FCCA159D16DE00CC3765 /* HTMLFormCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B26FCB4159D15E700CC3765 /* HTMLFormCollectionNamedItem.html */; };
</span><span class="cx">                 9B4F8FA4159D52B1002D9F94 /* HTMLCollectionNamedItem.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */; };
</span><span class="cx">                 9B4F8FA7159D52DD002D9F94 /* HTMLCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */; };
</span><ins>+                A1A4FE5F18DD3DB700B5EA8A /* Download.mm in Sources */ = {isa = PBXBuildFile; fileRef = A1A4FE5D18DD3DB700B5EA8A /* Download.mm */; };
</ins><span class="cx">                 A57A34F016AF677200C2501F /* PageVisibilityStateWithWindowChanges.mm in Sources */ = {isa = PBXBuildFile; fileRef = A57A34EF16AF677200C2501F /* PageVisibilityStateWithWindowChanges.mm */; };
</span><span class="cx">                 A57A34F216AF6B2B00C2501F /* PageVisibilityStateWithWindowChanges.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = A57A34F116AF69E200C2501F /* PageVisibilityStateWithWindowChanges.html */; };
</span><span class="cx">                 A5E2027315B2181900C13E14 /* WindowlessWebViewWithMedia.mm in Sources */ = {isa = PBXBuildFile; fileRef = A5E2027215B2181900C13E14 /* WindowlessWebViewWithMedia.mm */; };
</span><span class="lines">@@ -469,6 +470,7 @@
</span><span class="cx">                 9B26FCB4159D15E700CC3765 /* HTMLFormCollectionNamedItem.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = HTMLFormCollectionNamedItem.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HTMLCollectionNamedItem.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = HTMLCollectionNamedItem.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                A1A4FE5D18DD3DB700B5EA8A /* Download.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Download.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 A57A34EF16AF677200C2501F /* PageVisibilityStateWithWindowChanges.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PageVisibilityStateWithWindowChanges.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A57A34F116AF69E200C2501F /* PageVisibilityStateWithWindowChanges.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = PageVisibilityStateWithWindowChanges.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A5E2027015B2180600C13E14 /* WindowlessWebViewWithMedia.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = WindowlessWebViewWithMedia.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -672,6 +674,7 @@
</span><span class="cx">                 1ABC3DEC1899BE55004F0626 /* WebKit2 Cocoa */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                A1A4FE5D18DD3DB700B5EA8A /* Download.mm */,
</ins><span class="cx">                                 1ABC3DED1899BE6D004F0626 /* Navigation.mm */,
</span><span class="cx">                         );
</span><span class="cx">                         name = &quot;WebKit2 Cocoa&quot;;
</span><span class="lines">@@ -1207,6 +1210,7 @@
</span><span class="cx">                                 14464013167A8305000BD218 /* LayoutUnit.cpp in Sources */,
</span><span class="cx">                                 2D640B5517875DFF00BFAF99 /* ScrollPinningBehaviors.cpp in Sources */,
</span><span class="cx">                                 26300B1816755CD90066886D /* ListHashSet.cpp in Sources */,
</span><ins>+                                A1A4FE5F18DD3DB700B5EA8A /* Download.mm in Sources */,
</ins><span class="cx">                                 52CB47411448FB9300873995 /* LoadAlternateHTMLStringWithNonDirectoryURL.cpp in Sources */,
</span><span class="cx">                                 33DC8911141953A300747EF7 /* LoadCanceledNoServerRedirectCallback.cpp in Sources */,
</span><span class="cx">                                 8AA28C1A16D2FA7B002FF4DB /* LoadPageOnCrash.cpp in Sources */,
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKit2CocoaDownloadmm"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/Download.mm (0 => 166186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/Download.mm                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/Download.mm        2014-03-24 19:44:35 UTC (rev 166186)
</span><span class="lines">@@ -0,0 +1,174 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 &quot;config.h&quot;
+#import &lt;WebKit2/WKFoundation.h&gt;
+
+#if WK_API_ENABLED
+
+#import &quot;PlatformUtilities.h&quot;
+#import &quot;Test.h&quot;
+#import &lt;WebCore/FileSystem.h&gt;
+#import &lt;WebKit2/_WKDownloadDelegate.h&gt;
+#import &lt;WebKit2/WKNavigationDelegate.h&gt;
+#import &lt;WebKit2/WKProcessPoolPrivate.h&gt;
+#import &lt;WebKit2/WKWebView.h&gt;
+#import &lt;WebKit2/WKWebViewConfiguration.h&gt;
+#import &lt;wtf/RetainPtr.h&gt;
+#import &lt;wtf/text/WTFString.h&gt;
+
+static bool isDone;
+
+@interface DownloadDelegate : NSObject &lt;_WKDownloadDelegate&gt;
+- (id)initWithSourceURL:(NSURL *)sourceURL;
+@property (nonatomic, readonly) NSURL *sourceURL;
+@end
+
+@implementation DownloadDelegate {
+    RetainPtr&lt;_WKDownload&gt; _download;
+    RetainPtr&lt;NSURL&gt; _sourceURL;
+    String _destinationPath;
+    long long _expectedContentLength;
+    uint64_t _receivedContentLength;
+}
+
+- (id)initWithSourceURL:(NSURL *)sourceURL
+{
+    if (!(self = [super init]))
+        return nil;
+    _sourceURL = sourceURL;
+    _expectedContentLength = 0;
+    _receivedContentLength = 0;
+    return self;
+}
+
+- (NSURL *)sourceURL
+{
+    return _sourceURL.get();
+}
+
+- (void)_downloadDidStart:(_WKDownload *)download
+{
+    EXPECT_NULL(_download);
+    EXPECT_NOT_NULL(download);
+    _download = download;
+}
+
+- (void)_download:(_WKDownload *)download didReceiveResponse:(NSURLResponse *)response
+{
+    EXPECT_EQ(_download, download);
+    EXPECT_TRUE(_expectedContentLength == 0);
+    EXPECT_TRUE(_receivedContentLength == 0);
+    EXPECT_TRUE([[response URL] isEqual:[self sourceURL]]);
+    _expectedContentLength = [response expectedContentLength];
+}
+
+- (void)_download:(_WKDownload *)download didReceiveData:(uint64_t)length
+{
+    EXPECT_EQ(_download, download);
+    _receivedContentLength += length;
+}
+
+- (NSString *)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename allowOverwrite:(BOOL *)allowOverwrite
+{
+    EXPECT_EQ(_download, download);
+
+    WebCore::PlatformFileHandle fileHandle;
+    _destinationPath = WebCore::openTemporaryFile(&quot;TestWebKitAPI&quot;, fileHandle);
+    EXPECT_TRUE(fileHandle != WebCore::invalidPlatformFileHandle);
+    WebCore::closeFile(fileHandle);
+
+    *allowOverwrite = YES;
+    return _destinationPath;
+}
+
+- (void)_downloadDidFinish:(_WKDownload *)download
+{
+    EXPECT_EQ(_download, download);
+    EXPECT_TRUE(_expectedContentLength == NSURLResponseUnknownLength || static_cast&lt;uint64_t&gt;(_expectedContentLength) == _receivedContentLength);
+    EXPECT_TRUE([[NSFileManager defaultManager] contentsEqualAtPath:_destinationPath andPath:[_sourceURL path]]);
+    WebCore::deleteFile(_destinationPath);
+    isDone = true;
+}
+
+@end
+
+TEST(_WKDownload, DownloadDelegate)
+{
+    RetainPtr&lt;WKProcessPool&gt; processPool = adoptNS([[WKProcessPool alloc] init]);
+    DownloadDelegate *downloadDelegate = [[DownloadDelegate alloc] init];
+    [processPool _setDownloadDelegate:downloadDelegate];
+
+    @autoreleasepool {
+        EXPECT_EQ(downloadDelegate, [processPool _downloadDelegate]);
+    }
+
+    [downloadDelegate release];
+    EXPECT_NULL([processPool _downloadDelegate]);
+}
+
+static void runTestWithNavigationDelegate(id &lt;WKNavigationDelegate&gt; navigationDelegate)
+{
+    RetainPtr&lt;WKWebView&gt; webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+    [webView setNavigationDelegate:navigationDelegate];
+
+    RetainPtr&lt;DownloadDelegate&gt; downloadDelegate = adoptNS([[DownloadDelegate alloc] initWithSourceURL:[[NSBundle mainBundle] URLForResource:@&quot;simple&quot; withExtension:@&quot;html&quot; subdirectory:@&quot;TestWebKitAPI.resources&quot;]]);
+    [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];
+
+    [webView loadRequest:[NSURLRequest requestWithURL:[downloadDelegate sourceURL]]];
+    TestWebKitAPI::Util::run(&amp;isDone);
+}
+
+@interface DownloadNavigationDelegate : NSObject &lt;WKNavigationDelegate&gt;
+@end
+
+@implementation DownloadNavigationDelegate
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationPolicyDecision))decisionHandler
+{
+    decisionHandler(WKNavigationPolicyDecisionDownload);
+}
+@end
+
+TEST(_WKDownload, DownloadRequest)
+{
+    runTestWithNavigationDelegate(adoptNS([[DownloadNavigationDelegate alloc] init]).get());
+}
+
+@interface ConvertResponseToDownloadNavigationDelegate : NSObject &lt;WKNavigationDelegate&gt;
+@end
+
+@implementation ConvertResponseToDownloadNavigationDelegate
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicyDecision))decisionHandler
+{
+    decisionHandler(WKNavigationResponsePolicyDecisionBecomeDownload);
+}
+@end
+
+TEST(_WKDownload, ConvertResponseToDownload)
+{
+    runTestWithNavigationDelegate(adoptNS([[ConvertResponseToDownloadNavigationDelegate alloc] init]).get());
+}
+
+#endif
</ins></span></pre>
</div>
</div>

</body>
</html>