<!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>[194562] trunk/Source/WebKit2</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/194562">194562</a></dd>
<dt>Author</dt> <dd>achristensen@apple.com</dd>
<dt>Date</dt> <dd>2016-01-04 16:06:02 -0800 (Mon, 04 Jan 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Progress towards implementing downloads with NetworkSession
https://bugs.webkit.org/show_bug.cgi?id=152716

Reviewed by Brady Eidson.

* NetworkProcess/Downloads/Download.h:
* NetworkProcess/Downloads/DownloadID.h:
(WebKit::DownloadID::DownloadID):
(WebKit::DownloadID::operator==):
(WebKit::DownloadID::operator!=):
(WebKit::DownloadID::downloadID):
* NetworkProcess/Downloads/DownloadManager.cpp:
(WebKit::DownloadManager::startDownload):
* NetworkProcess/Downloads/DownloadManager.h:
(WebKit::DownloadManager::download):
(WebKit::DownloadManager::isDownloading):
* NetworkProcess/Downloads/cocoa/DownloadCocoa.mm:
(WebKit::Download::resume):
(WebKit::Download::platformInvalidate):
(WebKit::Download::platformDidFinish):
(WebKit::Download::start): Deleted.
* NetworkProcess/NetworkSession.h:
* NetworkProcess/cocoa/NetworkSessionCocoa.mm:
(-[WKNetworkSessionDelegate URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:]):
(-[WKNetworkSessionDelegate URLSession:task:didReceiveChallenge:completionHandler:]):
(-[WKNetworkSessionDelegate URLSession:task:didCompleteWithError:]):
(-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]):
(-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveData:]):
(-[WKNetworkSessionDelegate URLSession:downloadTask:didFinishDownloadingToURL:]):
(-[WKNetworkSessionDelegate URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:]):
(-[WKNetworkSessionDelegate URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:]):
(-[WKNetworkSessionDelegate URLSession:dataTask:didBecomeDownloadTask:]):

When using NSURLSession, a data task is converted to a download task after the connection has already
been established, the headers have been received, and WebCore looks at the response and decides that
this connection should become a download.  We call the didReceiveResponse to match the behavior of 
NSURLDownload, but this could be cleaned up later to match what is actually happening.  We also do not
need to tell the download to start because it has already started.

(WebKit::NetworkSession::dataTaskForIdentifier):
(WebKit::NetworkSession::addDownloadID):
(WebKit::NetworkSession::downloadID):
(WebKit::NetworkSession::takeDownloadID):
(WebKit::NetworkDataTask::NetworkDataTask):

NSURLSessionDownloadTask taskIdentifiers are unique to that NSURLSession, but we have one global DownloadManager
in the NetworkProcess.  We need to have each NetworkSession keep a map of taskIdentifiers to global DownloadID.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessDownloadsDownloadh">trunk/Source/WebKit2/NetworkProcess/Downloads/Download.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessDownloadsDownloadIDh">trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadID.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessDownloadsDownloadManagercpp">trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessDownloadsDownloadManagerh">trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessDownloadscocoaDownloadCocoamm">trunk/Source/WebKit2/NetworkProcess/Downloads/cocoa/DownloadCocoa.mm</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessNetworkSessionh">trunk/Source/WebKit2/NetworkProcess/NetworkSession.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscocoaNetworkSessionCocoamm">trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (194561 => 194562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-01-04 23:08:32 UTC (rev 194561)
+++ trunk/Source/WebKit2/ChangeLog        2016-01-05 00:06:02 UTC (rev 194562)
</span><span class="lines">@@ -1,3 +1,53 @@
</span><ins>+2016-01-04  Alex Christensen  &lt;achristensen@webkit.org&gt;
+
+        Progress towards implementing downloads with NetworkSession
+        https://bugs.webkit.org/show_bug.cgi?id=152716
+
+        Reviewed by Brady Eidson.
+
+        * NetworkProcess/Downloads/Download.h:
+        * NetworkProcess/Downloads/DownloadID.h:
+        (WebKit::DownloadID::DownloadID):
+        (WebKit::DownloadID::operator==):
+        (WebKit::DownloadID::operator!=):
+        (WebKit::DownloadID::downloadID):
+        * NetworkProcess/Downloads/DownloadManager.cpp:
+        (WebKit::DownloadManager::startDownload):
+        * NetworkProcess/Downloads/DownloadManager.h:
+        (WebKit::DownloadManager::download):
+        (WebKit::DownloadManager::isDownloading):
+        * NetworkProcess/Downloads/cocoa/DownloadCocoa.mm:
+        (WebKit::Download::resume):
+        (WebKit::Download::platformInvalidate):
+        (WebKit::Download::platformDidFinish):
+        (WebKit::Download::start): Deleted.
+        * NetworkProcess/NetworkSession.h:
+        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+        (-[WKNetworkSessionDelegate URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:]):
+        (-[WKNetworkSessionDelegate URLSession:task:didReceiveChallenge:completionHandler:]):
+        (-[WKNetworkSessionDelegate URLSession:task:didCompleteWithError:]):
+        (-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]):
+        (-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveData:]):
+        (-[WKNetworkSessionDelegate URLSession:downloadTask:didFinishDownloadingToURL:]):
+        (-[WKNetworkSessionDelegate URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:]):
+        (-[WKNetworkSessionDelegate URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:]):
+        (-[WKNetworkSessionDelegate URLSession:dataTask:didBecomeDownloadTask:]):
+
+        When using NSURLSession, a data task is converted to a download task after the connection has already
+        been established, the headers have been received, and WebCore looks at the response and decides that
+        this connection should become a download.  We call the didReceiveResponse to match the behavior of 
+        NSURLDownload, but this could be cleaned up later to match what is actually happening.  We also do not
+        need to tell the download to start because it has already started.
+
+        (WebKit::NetworkSession::dataTaskForIdentifier):
+        (WebKit::NetworkSession::addDownloadID):
+        (WebKit::NetworkSession::downloadID):
+        (WebKit::NetworkSession::takeDownloadID):
+        (WebKit::NetworkDataTask::NetworkDataTask):
+
+        NSURLSessionDownloadTask taskIdentifiers are unique to that NSURLSession, but we have one global DownloadManager
+        in the NetworkProcess.  We need to have each NetworkSession keep a map of taskIdentifiers to global DownloadID.
+
</ins><span class="cx"> 2016-01-04  Tim Horton  &lt;timothy_horton@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Turn on gesture events when building for Yosemite
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessDownloadsDownloadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/Downloads/Download.h (194561 => 194562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/Downloads/Download.h        2016-01-04 23:08:32 UTC (rev 194561)
+++ trunk/Source/WebKit2/NetworkProcess/Downloads/Download.h        2016-01-05 00:06:02 UTC (rev 194562)
</span><span class="lines">@@ -83,10 +83,10 @@
</span><span class="cx"> #endif
</span><span class="cx">     ~Download();
</span><span class="cx"> 
</span><del>-    void start();
</del><span class="cx"> #if USE(NETWORK_SESSION) &amp;&amp; PLATFORM(COCOA)
</span><span class="cx">     void dataTaskDidBecomeDownloadTask(const NetworkSession&amp;, RetainPtr&lt;NSURLSessionDownloadTask&gt;&amp;&amp;);
</span><span class="cx"> #else
</span><ins>+    void start();
</ins><span class="cx">     void startWithHandle(WebCore::ResourceHandle*, const WebCore::ResourceResponse&amp;);
</span><span class="cx"> #endif
</span><span class="cx">     void resume(const IPC::DataReference&amp; resumeData, const String&amp; path, const SandboxExtension::Handle&amp;);
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessDownloadsDownloadIDh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadID.h (194561 => 194562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadID.h        2016-01-04 23:08:32 UTC (rev 194561)
+++ trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadID.h        2016-01-05 00:06:02 UTC (rev 194562)
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     bool operator==(DownloadID other) const { return m_downloadID == other.m_downloadID; }
</span><ins>+    bool operator!=(DownloadID other) const { return m_downloadID != other.m_downloadID; }
</ins><span class="cx"> 
</span><span class="cx">     uint64_t downloadID() const { return m_downloadID; }
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessDownloadsDownloadManagercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.cpp (194561 => 194562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.cpp        2016-01-04 23:08:32 UTC (rev 194561)
+++ trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.cpp        2016-01-05 00:06:02 UTC (rev 194562)
</span><span class="lines">@@ -51,8 +51,8 @@
</span><span class="cx">     download-&gt;didStart(request);
</span><span class="cx"> #else
</span><span class="cx">     auto download = std::make_unique&lt;Download&gt;(*this, downloadID, request);
</span><ins>+    download-&gt;start();
</ins><span class="cx"> #endif
</span><del>-    download-&gt;start();
</del><span class="cx"> 
</span><span class="cx">     ASSERT(!m_downloads.contains(downloadID));
</span><span class="cx">     m_downloads.add(downloadID, WTFMove(download));
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessDownloadsDownloadManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.h (194561 => 194562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.h        2016-01-04 23:08:32 UTC (rev 194561)
+++ trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.h        2016-01-05 00:06:02 UTC (rev 194562)
</span><span class="lines">@@ -80,6 +80,8 @@
</span><span class="cx">     void resumeDownload(WebCore::SessionID, DownloadID, const IPC::DataReference&amp; resumeData, const String&amp; path, const SandboxExtension::Handle&amp;);
</span><span class="cx"> 
</span><span class="cx">     void cancelDownload(DownloadID);
</span><ins>+    
+    Download* download(DownloadID downloadID) { return m_downloads.get(downloadID); }
</ins><span class="cx"> 
</span><span class="cx">     void downloadFinished(Download*);
</span><span class="cx">     bool isDownloading() const { return !m_downloads.isEmpty(); }
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessDownloadscocoaDownloadCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/Downloads/cocoa/DownloadCocoa.mm (194561 => 194562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/Downloads/cocoa/DownloadCocoa.mm        2016-01-04 23:08:32 UTC (rev 194561)
+++ trunk/Source/WebKit2/NetworkProcess/Downloads/cocoa/DownloadCocoa.mm        2016-01-05 00:06:02 UTC (rev 194562)
</span><span class="lines">@@ -32,11 +32,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><del>-void Download::start()
-{
-    notImplemented();
-}
-
</del><span class="cx"> void Download::resume(const IPC::DataReference&amp; resumeData, const String&amp; path, const SandboxExtension::Handle&amp; sandboxExtensionHandle)
</span><span class="cx"> {
</span><span class="cx">     notImplemented();
</span><span class="lines">@@ -52,6 +47,10 @@
</span><span class="cx">     notImplemented();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Download::platformDidFinish()
+{
</ins><span class="cx"> }
</span><ins>+    
+}
</ins><span class="cx"> 
</span><span class="cx"> #endif // USE(NETWORK_SESSION)
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkSessionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkSession.h (194561 => 194562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkSession.h        2016-01-04 23:08:32 UTC (rev 194561)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkSession.h        2016-01-05 00:06:02 UTC (rev 194562)
</span><span class="lines">@@ -127,6 +127,10 @@
</span><span class="cx"> 
</span><span class="cx">     NetworkDataTask* dataTaskForIdentifier(NetworkDataTask::TaskIdentifier);
</span><span class="cx"> 
</span><ins>+    void addDownloadID(NetworkDataTask::TaskIdentifier, DownloadID);
+    DownloadID downloadID(NetworkDataTask::TaskIdentifier);
+    DownloadID takeDownloadID(NetworkDataTask::TaskIdentifier);
+    
</ins><span class="cx"> private:
</span><span class="cx">     WebCore::SessionID m_sessionID;
</span><span class="cx">     HashMap&lt;NetworkDataTask::TaskIdentifier, NetworkDataTask*&gt; m_dataTaskMap;
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscocoaNetworkSessionCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm (194561 => 194562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm        2016-01-04 23:08:32 UTC (rev 194561)
+++ trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm        2016-01-05 00:06:02 UTC (rev 194562)
</span><span class="lines">@@ -94,8 +94,6 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest *))completionHandler
</span><span class="cx"> {
</span><del>-    UNUSED_PARAM(session);
-
</del><span class="cx">     if (auto* networkingTask = _session-&gt;dataTaskForIdentifier(task.taskIdentifier)) {
</span><span class="cx">         if (auto* client = networkingTask-&gt;client()) {
</span><span class="cx">             auto completionHandlerCopy = Block_copy(completionHandler);
</span><span class="lines">@@ -111,8 +109,6 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
</span><span class="cx"> {
</span><del>-    UNUSED_PARAM(session);
-
</del><span class="cx">     if (auto* networkingTask = _session-&gt;dataTaskForIdentifier(task.taskIdentifier)) {
</span><span class="cx">         if (auto* client = networkingTask-&gt;client()) {
</span><span class="cx">             auto completionHandlerCopy = Block_copy(completionHandler);
</span><span class="lines">@@ -128,8 +124,6 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
</span><span class="cx"> {
</span><del>-    UNUSED_PARAM(session);
-
</del><span class="cx">     if (auto* networkingTask = _session-&gt;dataTaskForIdentifier(task.taskIdentifier)) {
</span><span class="cx">         if (auto* client = networkingTask-&gt;client())
</span><span class="cx">             client-&gt;didCompleteWithError(error);
</span><span class="lines">@@ -138,8 +132,6 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
</span><span class="cx"> {
</span><del>-    UNUSED_PARAM(session);
-
</del><span class="cx">     if (auto* networkingTask = _session-&gt;dataTaskForIdentifier(dataTask.taskIdentifier)) {
</span><span class="cx">         if (auto* client = networkingTask-&gt;client()) {
</span><span class="cx">             ASSERT(isMainThread());
</span><span class="lines">@@ -158,8 +150,6 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
</span><span class="cx"> {
</span><del>-    UNUSED_PARAM(session);
-
</del><span class="cx">     if (auto* networkingTask = _session-&gt;dataTaskForIdentifier(dataTask.taskIdentifier)) {
</span><span class="cx">         if (auto* client = networkingTask-&gt;client())
</span><span class="cx">             client-&gt;didReceiveData(WebCore::SharedBuffer::wrapNSData(data));
</span><span class="lines">@@ -168,13 +158,19 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
</span><span class="cx"> {
</span><ins>+    auto downloadID = _session-&gt;takeDownloadID([downloadTask taskIdentifier]);
</ins><span class="cx">     notImplemented();
</span><ins>+    if (auto* download = WebKit::NetworkProcess::singleton().downloadManager().download(downloadID))
+        download-&gt;didFinish();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
</span><span class="cx"> {
</span><span class="cx">     ASSERT_WITH_MESSAGE(!_session-&gt;dataTaskForIdentifier([downloadTask taskIdentifier]), &quot;The NetworkDataTask should be destroyed immediately after didBecomeDownloadTask returns&quot;);
</span><del>-    notImplemented();
</del><ins>+
+    auto downloadID = _session-&gt;downloadID([downloadTask taskIdentifier]);
+    if (auto* download = WebKit::NetworkProcess::singleton().downloadManager().download(downloadID))
+        download-&gt;didReceiveData(bytesWritten);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
</span><span class="lines">@@ -189,10 +185,13 @@
</span><span class="cx">         auto&amp; downloadManager = WebKit::NetworkProcess::singleton().downloadManager();
</span><span class="cx">         auto download = std::make_unique&lt;WebKit::Download&gt;(downloadManager, *_session, downloadID);
</span><span class="cx">         download-&gt;didStart([downloadTask currentRequest]);
</span><ins>+        download-&gt;didReceiveResponse([downloadTask response]);
</ins><span class="cx">         downloadManager.dataTaskBecameDownloadTask(downloadID, WTFMove(download));
</span><span class="cx"> 
</span><span class="cx">         if (auto* client = networkDataTask-&gt;client())
</span><span class="cx">             client-&gt;didBecomeDownload();
</span><ins>+
+        _session-&gt;addDownloadID([downloadTask taskIdentifier], downloadID);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -253,6 +252,29 @@
</span><span class="cx">     return m_dataTaskMap.get(taskIdentifier);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void NetworkSession::addDownloadID(NetworkDataTask::TaskIdentifier taskIdentifier, DownloadID downloadID)
+{
+#ifndef NDEBUG
+    ASSERT(!m_downloadMap.contains(taskIdentifier));
+    for (auto idInMap : m_downloadMap.values())
+        ASSERT(idInMap != downloadID);
+#endif
+    m_downloadMap.add(taskIdentifier, downloadID);
+}
+
+DownloadID NetworkSession::downloadID(NetworkDataTask::TaskIdentifier taskIdentifier)
+{
+    ASSERT(m_downloadMap.get(taskIdentifier).downloadID());
+    return m_downloadMap.get(taskIdentifier);
+}
+
+DownloadID NetworkSession::takeDownloadID(NetworkDataTask::TaskIdentifier taskIdentifier)
+{
+    auto downloadID = m_downloadMap.take(taskIdentifier);
+    ASSERT(downloadID.downloadID());
+    return downloadID;
+}
+
</ins><span class="cx"> NetworkDataTask::NetworkDataTask(NetworkSession&amp; session, NetworkSessionTaskClient&amp; client, RetainPtr&lt;NSURLSessionDataTask&gt;&amp;&amp; task)
</span><span class="cx">     : m_session(session)
</span><span class="cx">     , m_client(&amp;client)
</span></span></pre>
</div>
</div>

</body>
</html>