<!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>[207042] 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/207042">207042</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-10-10 22:28:44 -0700 (Mon, 10 Oct 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>NetworkSession: NetworkDataTask is leaked if download finishes in didReceiveResponse completion handler
https://bugs.webkit.org/show_bug.cgi?id=163204

Reviewed by Alex Christensen.

After the completion handler a reference of the NetworkDataTask is saved in m_downloadsAfterDestinationDecided.
If the download failed or was canceled DownloadManager::dataTaskBecameDownloadTask is never called and the data
task is kept in the download manager forever. This patch exposes NSURLSessionTask state property in
NetworkDataTask, so that the download manager can check the task state after the completion handler and return
early if the download finished or was cancelled.

* NetworkProcess/Downloads/DownloadManager.cpp:
(WebKit::DownloadManager::continueDecidePendingDownloadDestination):
* NetworkProcess/NetworkDataTask.h:
* NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
(WebKit::NetworkDataTask::state):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessDownloadsDownloadManagercpp">trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessNetworkDataTaskh">trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscocoaNetworkDataTaskCocoamm">trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (207041 => 207042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-10-11 04:43:26 UTC (rev 207041)
+++ trunk/Source/WebKit2/ChangeLog        2016-10-11 05:28:44 UTC (rev 207042)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2016-10-10  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        NetworkSession: NetworkDataTask is leaked if download finishes in didReceiveResponse completion handler
+        https://bugs.webkit.org/show_bug.cgi?id=163204
+
+        Reviewed by Alex Christensen.
+
+        After the completion handler a reference of the NetworkDataTask is saved in m_downloadsAfterDestinationDecided.
+        If the download failed or was canceled DownloadManager::dataTaskBecameDownloadTask is never called and the data
+        task is kept in the download manager forever. This patch exposes NSURLSessionTask state property in
+        NetworkDataTask, so that the download manager can check the task state after the completion handler and return
+        early if the download finished or was cancelled.
+
+        * NetworkProcess/Downloads/DownloadManager.cpp:
+        (WebKit::DownloadManager::continueDecidePendingDownloadDestination):
+        * NetworkProcess/NetworkDataTask.h:
+        * NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
+        (WebKit::NetworkDataTask::state):
+
</ins><span class="cx"> 2016-10-10  Konstantin Tokarev  &lt;annulen@yandex.ru&gt;
</span><span class="cx"> 
</span><span class="cx">         Added final specifier to WebInspectorServer and to its overridden methods
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessDownloadsDownloadManagercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.cpp (207041 => 207042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.cpp        2016-10-11 04:43:26 UTC (rev 207041)
+++ trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.cpp        2016-10-11 05:28:44 UTC (rev 207042)
</span><span class="lines">@@ -124,6 +124,8 @@
</span><span class="cx"> 
</span><span class="cx">         networkDataTask-&gt;setPendingDownloadLocation(destination, sandboxExtensionHandle, allowOverwrite);
</span><span class="cx">         completionHandler(PolicyDownload);
</span><ins>+        if (networkDataTask-&gt;state() == NetworkDataTask::State::Canceling || networkDataTask-&gt;state() == NetworkDataTask::State::Completed)
+            return;
</ins><span class="cx"> 
</span><span class="cx">         if (m_downloads.contains(downloadID)) {
</span><span class="cx">             // The completion handler already called dataTaskBecameDownloadTask().
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkDataTaskh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h (207041 => 207042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h        2016-10-11 04:43:26 UTC (rev 207041)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h        2016-10-11 05:28:44 UTC (rev 207042)
</span><span class="lines">@@ -93,7 +93,15 @@
</span><span class="cx">     void suspend();
</span><span class="cx">     void cancel();
</span><span class="cx">     void resume();
</span><del>-    
</del><ins>+
+    enum class State {
+        Running,
+        Suspended,
+        Canceling,
+        Completed
+    };
+    State state() const;
+
</ins><span class="cx">     typedef uint64_t TaskIdentifier;
</span><span class="cx">     
</span><span class="cx">     ~NetworkDataTask();
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscocoaNetworkDataTaskCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm (207041 => 207042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm        2016-10-11 04:43:26 UTC (rev 207041)
+++ trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm        2016-10-11 05:28:44 UTC (rev 207042)
</span><span class="lines">@@ -409,6 +409,23 @@
</span><span class="cx">     [m_task suspend];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+NetworkDataTask::State NetworkDataTask::state() const
+{
+    switch ([m_task state]) {
+    case NSURLSessionTaskStateRunning:
+        return State::Running;
+    case NSURLSessionTaskStateSuspended:
+        return State::Suspended;
+    case NSURLSessionTaskStateCanceling:
+        return State::Canceling;
+    case NSURLSessionTaskStateCompleted:
+        return State::Completed;
+    }
+
+    ASSERT_NOT_REACHED();
+    return State::Completed;
+}
+
</ins><span class="cx"> WebCore::Credential serverTrustCredential(const WebCore::AuthenticationChallenge&amp; challenge)
</span><span class="cx"> {
</span><span class="cx">     return WebCore::Credential([NSURLCredential credentialForTrust:challenge.nsURLAuthenticationChallenge().protectionSpace.serverTrust]);
</span></span></pre>
</div>
</div>

</body>
</html>