<!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>[207586] 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/207586">207586</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-10-19 23:42:24 -0700 (Wed, 19 Oct 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[SOUP] Add NetworkSession implementation and switch to use it
https://bugs.webkit.org/show_bug.cgi?id=163597

Reviewed by Alex Christensen.

Basically move the ResourceHandle implementation to the network process, but modernized, cleaned up, and adapted
to the NetworkSession model.

* CMakeLists.txt: Add new files to compilation.
* NetworkProcess/Downloads/Download.cpp:
(WebKit::Download::Download): Use the same code for all ports using NetworkSession and add missing
initialization of m_sessionID.
* NetworkProcess/Downloads/Download.h:
(WebKit::Download::Download): Define PlatformDownloadTaskRef on every platform to make the constructor common to
all ports using NetworkSession.
* NetworkProcess/Downloads/soup/DownloadSoup.cpp:
(WebKit::Download::cancelNetworkLoad):
(WebKit::Download::platformDidFinish):
* NetworkProcess/NetworkDataTask.h:
(WebKit::NetworkDataTask::pendingDownloadID): Make const.
(WebKit::NetworkDataTask::pendingDownload): Ditto.
(WebKit::NetworkDataTask::pendingDownloadLocation): Ditto.
(WebKit::NetworkDataTask::isDownload): Helper to check if the task is a download.
* NetworkProcess/NetworkLoad.cpp:
(WebKit::NetworkLoad::didReceiveResponseNetworkSession): Use NetworkDataTask::isDownload().
* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::NetworkProcess): NetworkSession::setCustomProtocolManager() is Cocoa only.
* NetworkProcess/NetworkSession.h:
* NetworkProcess/cocoa/NetworkSessionCocoa.mm:
(WebKit::NetworkSession::networkStorageSession): Make const.
* NetworkProcess/soup/NetworkDataTaskSoup.cpp: Added.
(WebKit::NetworkDataTask::NetworkDataTask):
(WebKit::NetworkDataTask::~NetworkDataTask):
(WebKit::NetworkDataTask::scheduleFailure):
(WebKit::NetworkDataTask::failureTimerFired):
(WebKit::NetworkDataTask::suggestedFilename):
(WebKit::NetworkDataTask::setSuggestedFilename):
(WebKit::NetworkDataTask::setPendingDownloadLocation):
(WebKit::NetworkDataTask::allowsSpecificHTTPSCertificateForHost):
(WebKit::NetworkDataTask::createRequest):
(WebKit::NetworkDataTask::clearRequest):
(WebKit::NetworkDataTask::resume):
(WebKit::NetworkDataTask::suspend):
(WebKit::NetworkDataTask::cancel):
(WebKit::NetworkDataTask::invalidateAndCancel):
(WebKit::NetworkDataTask::state):
(WebKit::NetworkDataTask::timeoutFired):
(WebKit::NetworkDataTask::startTimeout):
(WebKit::NetworkDataTask::stopTimeout):
(WebKit::NetworkDataTask::sendRequestCallback):
(WebKit::NetworkDataTask::didSendRequest):
(WebKit::NetworkDataTask::didReceiveResponse):
(WebKit::NetworkDataTask::tlsErrorsChangedCallback):
(WebKit::NetworkDataTask::tlsErrorsChanged):
(WebKit::NetworkDataTask::applyAuthenticationToRequest):
(WebKit::NetworkDataTask::authenticateCallback):
(WebKit::isAuthenticationFailureStatusCode):
(WebKit::NetworkDataTask::authenticate):
(WebKit::NetworkDataTask::continueAuthenticate):
(WebKit::NetworkDataTask::skipInputStreamForRedirectionCallback):
(WebKit::NetworkDataTask::skipInputStreamForRedirection):
(WebKit::NetworkDataTask::didFinishSkipInputStreamForRedirection):
(WebKit::shouldRedirectAsGET):
(WebKit::NetworkDataTask::shouldStartHTTPRedirection):
(WebKit::NetworkDataTask::continueHTTPRedirection):
(WebKit::NetworkDataTask::readCallback):
(WebKit::NetworkDataTask::read):
(WebKit::NetworkDataTask::didRead):
(WebKit::NetworkDataTask::didFinishRead):
(WebKit::NetworkDataTask::requestNextPartCallback):
(WebKit::NetworkDataTask::requestNextPart):
(WebKit::NetworkDataTask::didRequestNextPart):
(WebKit::NetworkDataTask::didFinishRequestNextPart):
(WebKit::NetworkDataTask::gotHeadersCallback):
(WebKit::NetworkDataTask::didGetHeaders):
(WebKit::NetworkDataTask::wroteBodyDataCallback):
(WebKit::NetworkDataTask::didWriteBodyData):
(WebKit::NetworkDataTask::download):
(WebKit::NetworkDataTask::writeDownloadCallback):
(WebKit::NetworkDataTask::writeDownload):
(WebKit::NetworkDataTask::didWriteDownload):
(WebKit::NetworkDataTask::didFinishDownload):
(WebKit::NetworkDataTask::didFailDownload):
(WebKit::NetworkDataTask::cleanDownloadFiles):
(WebKit::NetworkDataTask::didFail):
(WebKit::NetworkDataTask::networkEventCallback):
(WebKit::NetworkDataTask::networkEvent):
(WebKit::NetworkDataTask::startingCallback):
(WebKit::NetworkDataTask::requestStartedCallback):
(WebKit::NetworkDataTask::didStartRequest):
(WebKit::NetworkDataTask::restartedCallback):
(WebKit::NetworkDataTask::didRestart):
* NetworkProcess/soup/NetworkSessionSoup.cpp:
(WebKit::NetworkSession::create):
(WebKit::NetworkSession::defaultSession):
(WebKit::NetworkSession::networkStorageSession):
(WebKit::NetworkSession::NetworkSession):
(WebKit::NetworkSession::~NetworkSession):
(WebKit::NetworkSession::soupSession):
(WebKit::NetworkSession::invalidateAndCancel):
(WebKit::NetworkSession::clearCredentials):
* NetworkProcess/soup/RemoteNetworkingContextSoup.cpp:
(WebKit::RemoteNetworkingContext::ensurePrivateBrowsingSession): Add implementation matching
WebFrameNetworkingContext::ensurePrivateBrowsingSession().
(WebKit::RemoteNetworkingContext::storageSession): Do not always return the default session if the given one is
in the global map.
* PlatformEfl.cmake: Ad new files to compilation.
* PlatformGTK.cmake: Ditto.
* WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp:
(WebKit::WebFrameNetworkingContext::ensurePrivateBrowsingSession): Also create a NetworkSession.
* config.h: Enable NetworkSession unconditionally for Soup based ports.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2CMakeListstxt">trunk/Source/WebKit2/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessDownloadsDownloadcpp">trunk/Source/WebKit2/NetworkProcess/Downloads/Download.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessDownloadsDownloadh">trunk/Source/WebKit2/NetworkProcess/Downloads/Download.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessDownloadssoupDownloadSoupcpp">trunk/Source/WebKit2/NetworkProcess/Downloads/soup/DownloadSoup.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessNetworkDataTaskh">trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessNetworkLoadcpp">trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessNetworkProcesscpp">trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessNetworkSessionh">trunk/Source/WebKit2/NetworkProcess/NetworkSession.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessPingLoadh">trunk/Source/WebKit2/NetworkProcess/PingLoad.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscocoaNetworkDataTaskCocoamm">trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscocoaNetworkSessionCocoamm">trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesssoupRemoteNetworkingContextSoupcpp">trunk/Source/WebKit2/NetworkProcess/soup/RemoteNetworkingContextSoup.cpp</a></li>
<li><a href="#trunkSourceWebKit2PlatformEflcmake">trunk/Source/WebKit2/PlatformEfl.cmake</a></li>
<li><a href="#trunkSourceWebKit2PlatformGTKcmake">trunk/Source/WebKit2/PlatformGTK.cmake</a></li>
<li><a href="#trunkSourceWebKit2SharedAuthenticationAuthenticationManagerh">trunk/Source/WebKit2/Shared/Authentication/AuthenticationManager.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebCoreSupportsoupWebFrameNetworkingContextcpp">trunk/Source/WebKit2/WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebProcesscpp">trunk/Source/WebKit2/WebProcess/WebProcess.cpp</a></li>
<li><a href="#trunkSourceWebKit2configh">trunk/Source/WebKit2/config.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2NetworkProcesssoupNetworkDataTaskSoupcpp">trunk/Source/WebKit2/NetworkProcess/soup/NetworkDataTaskSoup.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesssoupNetworkSessionSoupcpp">trunk/Source/WebKit2/NetworkProcess/soup/NetworkSessionSoup.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2CMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/CMakeLists.txt (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/CMakeLists.txt        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/CMakeLists.txt        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -217,6 +217,7 @@
</span><span class="cx">     NetworkProcess/Downloads/BlobDownloadClient.cpp
</span><span class="cx">     NetworkProcess/Downloads/Download.cpp
</span><span class="cx">     NetworkProcess/Downloads/DownloadManager.cpp
</span><ins>+    NetworkProcess/Downloads/PendingDownload.cpp
</ins><span class="cx"> 
</span><span class="cx">     Platform/Logging.cpp
</span><span class="cx">     Platform/Module.cpp
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/ChangeLog        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -1,3 +1,117 @@
</span><ins>+2016-10-19  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        [SOUP] Add NetworkSession implementation and switch to use it
+        https://bugs.webkit.org/show_bug.cgi?id=163597
+
+        Reviewed by Alex Christensen.
+
+        Basically move the ResourceHandle implementation to the network process, but modernized, cleaned up, and adapted
+        to the NetworkSession model.
+
+        * CMakeLists.txt: Add new files to compilation.
+        * NetworkProcess/Downloads/Download.cpp:
+        (WebKit::Download::Download): Use the same code for all ports using NetworkSession and add missing
+        initialization of m_sessionID.
+        * NetworkProcess/Downloads/Download.h:
+        (WebKit::Download::Download): Define PlatformDownloadTaskRef on every platform to make the constructor common to
+        all ports using NetworkSession.
+        * NetworkProcess/Downloads/soup/DownloadSoup.cpp:
+        (WebKit::Download::cancelNetworkLoad):
+        (WebKit::Download::platformDidFinish):
+        * NetworkProcess/NetworkDataTask.h:
+        (WebKit::NetworkDataTask::pendingDownloadID): Make const.
+        (WebKit::NetworkDataTask::pendingDownload): Ditto.
+        (WebKit::NetworkDataTask::pendingDownloadLocation): Ditto.
+        (WebKit::NetworkDataTask::isDownload): Helper to check if the task is a download.
+        * NetworkProcess/NetworkLoad.cpp:
+        (WebKit::NetworkLoad::didReceiveResponseNetworkSession): Use NetworkDataTask::isDownload().
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::NetworkProcess): NetworkSession::setCustomProtocolManager() is Cocoa only.
+        * NetworkProcess/NetworkSession.h:
+        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+        (WebKit::NetworkSession::networkStorageSession): Make const.
+        * NetworkProcess/soup/NetworkDataTaskSoup.cpp: Added.
+        (WebKit::NetworkDataTask::NetworkDataTask):
+        (WebKit::NetworkDataTask::~NetworkDataTask):
+        (WebKit::NetworkDataTask::scheduleFailure):
+        (WebKit::NetworkDataTask::failureTimerFired):
+        (WebKit::NetworkDataTask::suggestedFilename):
+        (WebKit::NetworkDataTask::setSuggestedFilename):
+        (WebKit::NetworkDataTask::setPendingDownloadLocation):
+        (WebKit::NetworkDataTask::allowsSpecificHTTPSCertificateForHost):
+        (WebKit::NetworkDataTask::createRequest):
+        (WebKit::NetworkDataTask::clearRequest):
+        (WebKit::NetworkDataTask::resume):
+        (WebKit::NetworkDataTask::suspend):
+        (WebKit::NetworkDataTask::cancel):
+        (WebKit::NetworkDataTask::invalidateAndCancel):
+        (WebKit::NetworkDataTask::state):
+        (WebKit::NetworkDataTask::timeoutFired):
+        (WebKit::NetworkDataTask::startTimeout):
+        (WebKit::NetworkDataTask::stopTimeout):
+        (WebKit::NetworkDataTask::sendRequestCallback):
+        (WebKit::NetworkDataTask::didSendRequest):
+        (WebKit::NetworkDataTask::didReceiveResponse):
+        (WebKit::NetworkDataTask::tlsErrorsChangedCallback):
+        (WebKit::NetworkDataTask::tlsErrorsChanged):
+        (WebKit::NetworkDataTask::applyAuthenticationToRequest):
+        (WebKit::NetworkDataTask::authenticateCallback):
+        (WebKit::isAuthenticationFailureStatusCode):
+        (WebKit::NetworkDataTask::authenticate):
+        (WebKit::NetworkDataTask::continueAuthenticate):
+        (WebKit::NetworkDataTask::skipInputStreamForRedirectionCallback):
+        (WebKit::NetworkDataTask::skipInputStreamForRedirection):
+        (WebKit::NetworkDataTask::didFinishSkipInputStreamForRedirection):
+        (WebKit::shouldRedirectAsGET):
+        (WebKit::NetworkDataTask::shouldStartHTTPRedirection):
+        (WebKit::NetworkDataTask::continueHTTPRedirection):
+        (WebKit::NetworkDataTask::readCallback):
+        (WebKit::NetworkDataTask::read):
+        (WebKit::NetworkDataTask::didRead):
+        (WebKit::NetworkDataTask::didFinishRead):
+        (WebKit::NetworkDataTask::requestNextPartCallback):
+        (WebKit::NetworkDataTask::requestNextPart):
+        (WebKit::NetworkDataTask::didRequestNextPart):
+        (WebKit::NetworkDataTask::didFinishRequestNextPart):
+        (WebKit::NetworkDataTask::gotHeadersCallback):
+        (WebKit::NetworkDataTask::didGetHeaders):
+        (WebKit::NetworkDataTask::wroteBodyDataCallback):
+        (WebKit::NetworkDataTask::didWriteBodyData):
+        (WebKit::NetworkDataTask::download):
+        (WebKit::NetworkDataTask::writeDownloadCallback):
+        (WebKit::NetworkDataTask::writeDownload):
+        (WebKit::NetworkDataTask::didWriteDownload):
+        (WebKit::NetworkDataTask::didFinishDownload):
+        (WebKit::NetworkDataTask::didFailDownload):
+        (WebKit::NetworkDataTask::cleanDownloadFiles):
+        (WebKit::NetworkDataTask::didFail):
+        (WebKit::NetworkDataTask::networkEventCallback):
+        (WebKit::NetworkDataTask::networkEvent):
+        (WebKit::NetworkDataTask::startingCallback):
+        (WebKit::NetworkDataTask::requestStartedCallback):
+        (WebKit::NetworkDataTask::didStartRequest):
+        (WebKit::NetworkDataTask::restartedCallback):
+        (WebKit::NetworkDataTask::didRestart):
+        * NetworkProcess/soup/NetworkSessionSoup.cpp:
+        (WebKit::NetworkSession::create):
+        (WebKit::NetworkSession::defaultSession):
+        (WebKit::NetworkSession::networkStorageSession):
+        (WebKit::NetworkSession::NetworkSession):
+        (WebKit::NetworkSession::~NetworkSession):
+        (WebKit::NetworkSession::soupSession):
+        (WebKit::NetworkSession::invalidateAndCancel):
+        (WebKit::NetworkSession::clearCredentials):
+        * NetworkProcess/soup/RemoteNetworkingContextSoup.cpp:
+        (WebKit::RemoteNetworkingContext::ensurePrivateBrowsingSession): Add implementation matching
+        WebFrameNetworkingContext::ensurePrivateBrowsingSession().
+        (WebKit::RemoteNetworkingContext::storageSession): Do not always return the default session if the given one is
+        in the global map.
+        * PlatformEfl.cmake: Ad new files to compilation.
+        * PlatformGTK.cmake: Ditto.
+        * WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp:
+        (WebKit::WebFrameNetworkingContext::ensurePrivateBrowsingSession): Also create a NetworkSession.
+        * config.h: Enable NetworkSession unconditionally for Soup based ports.
+
</ins><span class="cx"> 2016-10-19  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Revert r207151
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessDownloadsDownloadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/Downloads/Download.cpp (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/Downloads/Download.cpp        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/NetworkProcess/Downloads/Download.cpp        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;DownloadManager.h&quot;
</span><span class="cx"> #include &quot;DownloadProxyMessages.h&quot;
</span><span class="cx"> #include &quot;Logging.h&quot;
</span><ins>+#include &quot;NetworkDataTask.h&quot;
</ins><span class="cx"> #include &quot;SandboxExtension.h&quot;
</span><span class="cx"> #include &quot;WebCoreArgumentCoders.h&quot;
</span><span class="cx"> #include &lt;WebCore/NotImplemented.h&gt;
</span><span class="lines">@@ -43,11 +44,12 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><del>-#if USE(NETWORK_SESSION) &amp;&amp; PLATFORM(COCOA)
-Download::Download(DownloadManager&amp; downloadManager, DownloadID downloadID, NSURLSessionDownloadTask* download, const WebCore::SessionID&amp; sessionID, const String&amp; suggestedName)
</del><ins>+#if USE(NETWORK_SESSION)
+Download::Download(DownloadManager&amp; downloadManager, DownloadID downloadID, PlatformDownloadTaskRef download, const WebCore::SessionID&amp; sessionID, const String&amp; suggestedName)
</ins><span class="cx">     : m_downloadManager(downloadManager)
</span><span class="cx">     , m_downloadID(downloadID)
</span><span class="cx">     , m_download(download)
</span><ins>+    , m_sessionID(sessionID)
</ins><span class="cx">     , m_suggestedName(suggestedName)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_downloadID.downloadID());
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessDownloadsDownloadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/Downloads/Download.h (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/Downloads/Download.h        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/NetworkProcess/Downloads/Download.h        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -35,17 +35,24 @@
</span><span class="cx"> #include &lt;WebCore/SessionID.h&gt;
</span><span class="cx"> #include &lt;memory&gt;
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><del>-
-#if PLATFORM(COCOA)
</del><span class="cx"> #include &lt;wtf/RetainPtr.h&gt;
</span><span class="cx"> 
</span><span class="cx"> #if USE(NETWORK_SESSION)
</span><ins>+#if PLATFORM(COCOA)
</ins><span class="cx"> OBJC_CLASS NSURLSessionDownloadTask;
</span><del>-#else
</del><ins>+typedef NSURLSessionDownloadTask* PlatformDownloadTaskRef;
+#elif USE(SOUP)
+namespace WebKit {
+class NetworkDataTask;
+}
+typedef WebKit::NetworkDataTask* PlatformDownloadTaskRef;
+#endif
+#else // USE(NETWORK_SESSION)
+#if PLATFORM(COCOA)
</ins><span class="cx"> OBJC_CLASS NSURLDownload;
</span><span class="cx"> OBJC_CLASS WKDownloadAsDelegate;
</span><span class="cx"> #endif
</span><del>-#endif
</del><ins>+#endif // USE(NETWORK_SESSION)
</ins><span class="cx"> 
</span><span class="cx"> #if USE(CFURLCONNECTION)
</span><span class="cx"> #include &lt;CFNetwork/CFURLDownloadPriv.h&gt;
</span><span class="lines">@@ -72,8 +79,8 @@
</span><span class="cx"> class Download : public IPC::MessageSender {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(Download); WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><del>-#if USE(NETWORK_SESSION) &amp;&amp; PLATFORM(COCOA)
-    Download(DownloadManager&amp;, DownloadID, NSURLSessionDownloadTask*, const WebCore::SessionID&amp; sessionID, const String&amp; suggestedFilename = { });
</del><ins>+#if USE(NETWORK_SESSION)
+    Download(DownloadManager&amp;, DownloadID, PlatformDownloadTaskRef, const WebCore::SessionID&amp; sessionID, const String&amp; suggestedFilename = { });
</ins><span class="cx"> #endif
</span><span class="cx">     Download(DownloadManager&amp;, DownloadID, const WebCore::ResourceRequest&amp;, const String&amp; suggestedFilename = { });
</span><span class="cx"> 
</span><span class="lines">@@ -130,15 +137,19 @@
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;SandboxExtension&gt; m_sandboxExtension;
</span><span class="cx"> 
</span><ins>+#if USE(NETWORK_SESSION)
</ins><span class="cx"> #if PLATFORM(COCOA)
</span><del>-#if USE(NETWORK_SESSION)
</del><span class="cx">     RetainPtr&lt;NSURLSessionDownloadTask&gt; m_download;
</span><ins>+#elif USE(SOUP)
+    RefPtr&lt;NetworkDataTask&gt; m_download;
+#endif
</ins><span class="cx">     WebCore::SessionID m_sessionID;
</span><del>-#else
</del><ins>+#else // USE(NETWORK_SESSION)
+#if PLATFORM(COCOA)
</ins><span class="cx">     RetainPtr&lt;NSURLDownload&gt; m_nsURLDownload;
</span><span class="cx">     RetainPtr&lt;WKDownloadAsDelegate&gt; m_delegate;
</span><span class="cx"> #endif
</span><del>-#endif
</del><ins>+#endif // USE(NETWORK_SESSION)
</ins><span class="cx"> #if USE(CFURLCONNECTION)
</span><span class="cx">     RetainPtr&lt;CFURLDownloadRef&gt; m_download;
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessDownloadssoupDownloadSoupcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/Downloads/soup/DownloadSoup.cpp (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/Downloads/soup/DownloadSoup.cpp        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/NetworkProcess/Downloads/soup/DownloadSoup.cpp        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -28,204 +28,13 @@
</span><span class="cx"> #include &quot;Download.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;DataReference.h&quot;
</span><del>-#include &quot;DownloadSoupErrors.h&quot;
</del><ins>+#include &quot;NetworkDataTask.h&quot;
</ins><span class="cx"> #include &lt;WebCore/NotImplemented.h&gt;
</span><del>-#include &lt;WebCore/ResourceHandleInternal.h&gt;
-#include &lt;gio/gio.h&gt;
-#include &lt;wtf/RunLoop.h&gt;
-#include &lt;wtf/glib/GRefPtr.h&gt;
-#include &lt;wtf/glib/GUniquePtr.h&gt;
-#include &lt;wtf/text/CString.h&gt;
</del><span class="cx"> 
</span><del>-#if PLATFORM(GTK)
-#include &lt;glib/gi18n-lib.h&gt;
-#endif
-
</del><span class="cx"> using namespace WebCore;
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><del>-class DownloadClient final : public ResourceHandleClient {
-    WTF_MAKE_NONCOPYABLE(DownloadClient);
-public:
-    DownloadClient(Download&amp; download)
-        : m_download(download)
-        , m_handleResponseLater(RunLoop::main(), this, &amp;DownloadClient::handleResponse)
-        , m_allowOverwrite(false)
-    {
-    }
-
-    ~DownloadClient()
-    {
-    }
-
-    void deleteFilesIfNeeded()
-    {
-        if (m_destinationFile)
-            g_file_delete(m_destinationFile.get(), nullptr, nullptr);
-
-        if (m_intermediateFile) {
-            ASSERT(m_destinationFile);
-            g_file_delete(m_intermediateFile.get(), nullptr, nullptr);
-        }
-    }
-
-    void downloadFailed(const ResourceError&amp; error)
-    {
-        deleteFilesIfNeeded();
-        m_download.didFail(error, IPC::DataReference());
-    }
-
-    void didReceiveResponse(ResourceHandle*, ResourceResponse&amp;&amp; response) override
-    {
-        m_response = WTFMove(response);
-        m_download.didReceiveResponse(m_response);
-
-        if (m_response.httpStatusCode() &gt;= 400) {
-            downloadFailed(platformDownloadNetworkError(m_response.httpStatusCode(), m_response.url(), m_response.httpStatusText()));
-            return;
-        }
-
-        String suggestedFilename = m_response.suggestedFilename();
-        if (suggestedFilename.isEmpty()) {
-            URL url = m_response.url();
-            url.setQuery(String());
-            url.removeFragmentIdentifier();
-            suggestedFilename = decodeURLEscapeSequences(url.lastPathComponent());
-        }
-
-        String destinationURI = m_download.decideDestinationWithSuggestedFilename(suggestedFilename, m_allowOverwrite);
-        if (destinationURI.isEmpty()) {
-#if PLATFORM(GTK)
-            GUniquePtr&lt;char&gt; buffer(g_strdup_printf(_(&quot;Cannot determine destination URI for download with suggested filename %s&quot;), suggestedFilename.utf8().data()));
-            String errorMessage = String::fromUTF8(buffer.get());
-#else
-            String errorMessage = makeString(&quot;Cannot determine destination URI for download with suggested filename &quot;, suggestedFilename);
-#endif
-            downloadFailed(platformDownloadDestinationError(m_response, errorMessage));
-            return;
-        }
-
-        m_destinationFile = adoptGRef(g_file_new_for_uri(destinationURI.utf8().data()));
-        GRefPtr&lt;GFileOutputStream&gt; outputStream;
-        GUniqueOutPtr&lt;GError&gt; error;
-        if (m_allowOverwrite)
-            outputStream = adoptGRef(g_file_replace(m_destinationFile.get(), nullptr, FALSE, G_FILE_CREATE_NONE, nullptr, &amp;error.outPtr()));
-        else
-            outputStream = adoptGRef(g_file_create(m_destinationFile.get(), G_FILE_CREATE_NONE, nullptr, &amp;error.outPtr()));
-        if (!outputStream) {
-            m_destinationFile.clear();
-            downloadFailed(platformDownloadDestinationError(m_response, error-&gt;message));
-            return;
-        }
-
-        String intermediateURI = destinationURI + &quot;.wkdownload&quot;;
-        m_intermediateFile = adoptGRef(g_file_new_for_uri(intermediateURI.utf8().data()));
-        m_outputStream = adoptGRef(g_file_replace(m_intermediateFile.get(), 0, TRUE, G_FILE_CREATE_NONE, 0, &amp;error.outPtr()));
-        if (!m_outputStream) {
-            downloadFailed(platformDownloadDestinationError(m_response, error-&gt;message));
-            return;
-        }
-
-        m_download.didCreateDestination(destinationURI);
-    }
-
-    void didReceiveData(ResourceHandle*, const char* data, unsigned length, int /*encodedDataLength*/) override
-    {
-        if (m_handleResponseLater.isActive()) {
-            m_handleResponseLater.stop();
-            handleResponse();
-        }
-
-        gsize bytesWritten;
-        GUniqueOutPtr&lt;GError&gt; error;
-        g_output_stream_write_all(G_OUTPUT_STREAM(m_outputStream.get()), data, length, &amp;bytesWritten, 0, &amp;error.outPtr());
-        if (error) {
-            downloadFailed(platformDownloadDestinationError(m_response, error-&gt;message));
-            return;
-        }
-        m_download.didReceiveData(bytesWritten);
-    }
-
-    void didFinishLoading(ResourceHandle*, double) override
-    {
-        m_outputStream = nullptr;
-
-        ASSERT(m_destinationFile);
-        ASSERT(m_intermediateFile);
-        GUniqueOutPtr&lt;GError&gt; error;
-        if (!g_file_move(m_intermediateFile.get(), m_destinationFile.get(), G_FILE_COPY_OVERWRITE, nullptr, nullptr, nullptr, &amp;error.outPtr())) {
-            downloadFailed(platformDownloadDestinationError(m_response, error-&gt;message));
-            return;
-        }
-
-        GRefPtr&lt;GFileInfo&gt; info = adoptGRef(g_file_info_new());
-        CString uri = m_response.url().string().utf8();
-        g_file_info_set_attribute_string(info.get(), &quot;metadata::download-uri&quot;, uri.data());
-        g_file_info_set_attribute_string(info.get(), &quot;xattr::xdg.origin.url&quot;, uri.data());
-        g_file_set_attributes_async(m_destinationFile.get(), info.get(), G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT, nullptr, nullptr, nullptr);
-
-        m_download.didFinish();
-    }
-
-    void didFail(ResourceHandle*, const ResourceError&amp; error) override
-    {
-        downloadFailed(platformDownloadNetworkError(error.errorCode(), error.failingURL(), error.localizedDescription()));
-    }
-
-    void cancel(ResourceHandle* handle)
-    {
-        handle-&gt;cancel();
-        deleteFilesIfNeeded();
-        m_download.didCancel(IPC::DataReference());
-    }
-
-    void handleResponse()
-    {
-        didReceiveResponse(nullptr, WTFMove(m_delayedResponse));
-    }
-
-    void handleResponseLater(const ResourceResponse&amp; response)
-    {
-        ASSERT(m_response.isNull());
-        ASSERT(!m_handleResponseLater.isActive());
-
-        m_delayedResponse = response;
-
-        // Call didReceiveResponse in an idle to make sure the download is added
-        // to the DownloadManager downloads map.
-        m_handleResponseLater.startOneShot(0);
-    }
-
-    Download&amp; m_download;
-    GRefPtr&lt;GFileOutputStream&gt; m_outputStream;
-    ResourceResponse m_response;
-    GRefPtr&lt;GFile&gt; m_destinationFile;
-    GRefPtr&lt;GFile&gt; m_intermediateFile;
-    ResourceResponse m_delayedResponse;
-    RunLoop::Timer&lt;DownloadClient&gt; m_handleResponseLater;
-    bool m_allowOverwrite;
-};
-
-void Download::startNetworkLoad()
-{
-    ASSERT(!m_downloadClient);
-    ASSERT(!m_resourceHandle);
-    m_downloadClient = std::make_unique&lt;DownloadClient&gt;(*this);
-    m_resourceHandle = ResourceHandle::create(0, m_request, m_downloadClient.get(), false, true);
-    didStart();
-}
-
-void Download::startNetworkLoadWithHandle(ResourceHandle* resourceHandle, const ResourceResponse&amp; response)
-{
-    ASSERT(!m_downloadClient);
-    ASSERT(!m_resourceHandle);
-    m_downloadClient = std::make_unique&lt;DownloadClient&gt;(*this);
-    m_resourceHandle = resourceHandle-&gt;releaseForDownload(m_downloadClient.get());
-    didStart();
-    static_cast&lt;DownloadClient*&gt;(m_downloadClient.get())-&gt;handleResponseLater(response);
-}
-
</del><span class="cx"> void Download::resume(const IPC::DataReference&amp;, const String&amp;, const SandboxExtension::Handle&amp;)
</span><span class="cx"> {
</span><span class="cx">     notImplemented();
</span><span class="lines">@@ -233,14 +42,8 @@
</span><span class="cx"> 
</span><span class="cx"> void Download::cancelNetworkLoad()
</span><span class="cx"> {
</span><del>-    if (!m_resourceHandle)
-        return;
-
-    // Cancelling the download will delete it and platformInvalidate() will be called by the destructor.
-    // So, we need to set m_resourceHandle to nullptr before actually cancelling the download to make sure
-    // it won't be cancelled again by platformInvalidate. See https://bugs.webkit.org/show_bug.cgi?id=127650.
-    RefPtr&lt;ResourceHandle&gt; resourceHandle = m_resourceHandle.release();
-    static_cast&lt;DownloadClient*&gt;(m_downloadClient.get())-&gt;cancel(resourceHandle.get());
</del><ins>+    m_download-&gt;cancel();
+    didCancel({ });
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Download::platformInvalidate()
</span><span class="lines">@@ -249,7 +52,6 @@
</span><span class="cx"> 
</span><span class="cx"> void Download::platformDidFinish()
</span><span class="cx"> {
</span><del>-    m_resourceHandle = nullptr;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkDataTaskh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -23,9 +23,11 @@
</span><span class="cx">  * THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><del>-#ifndef NetworkDataTask_h
-#define NetworkDataTask_h
</del><ins>+#pragma once
</ins><span class="cx"> 
</span><ins>+#if USE(NETWORK_SESSION)
+
+#include &quot;DownloadID.h&quot;
</ins><span class="cx"> #include &quot;SandboxExtension.h&quot;
</span><span class="cx"> #include &lt;WebCore/Credential.h&gt;
</span><span class="cx"> #include &lt;WebCore/FrameLoaderTypes.h&gt;
</span><span class="lines">@@ -41,6 +43,13 @@
</span><span class="cx"> OBJC_CLASS NSURLSessionDataTask;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if USE(SOUP)
+#include &lt;WebCore/ProtectionSpace.h&gt;
+#include &lt;WebCore/ResourceResponse.h&gt;
+#include &lt;wtf/RunLoop.h&gt;
+#include &lt;wtf/glib/GRefPtr.h&gt;
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> class AuthenticationChallenge;
</span><span class="cx"> class Credential;
</span><span class="lines">@@ -55,14 +64,8 @@
</span><span class="cx"> class Download;
</span><span class="cx"> class NetworkSession;
</span><span class="cx"> class PendingDownload;
</span><ins>+enum class AuthenticationChallengeDisposition;
</ins><span class="cx"> 
</span><del>-enum class AuthenticationChallengeDisposition {
-    UseCredential,
-    PerformDefaultHandling,
-    Cancel,
-    RejectProtectionSpace
-};
-    
</del><span class="cx"> typedef Function&lt;void(const WebCore::ResourceRequest&amp;)&gt; RedirectCompletionHandler;
</span><span class="cx"> typedef Function&lt;void(AuthenticationChallengeDisposition, const WebCore::Credential&amp;)&gt; ChallengeCompletionHandler;
</span><span class="cx"> typedef Function&lt;void(WebCore::PolicyAction)&gt; ResponseCompletionHandler;
</span><span class="lines">@@ -105,7 +108,8 @@
</span><span class="cx">     typedef uint64_t TaskIdentifier;
</span><span class="cx">     
</span><span class="cx">     ~NetworkDataTask();
</span><del>-    
</del><ins>+
+#if PLATFORM(COCOA)
</ins><span class="cx">     void didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend);
</span><span class="cx">     void didReceiveChallenge(const WebCore::AuthenticationChallenge&amp;, ChallengeCompletionHandler&amp;&amp;);
</span><span class="cx">     void didCompleteWithError(const WebCore::ResourceError&amp;);
</span><span class="lines">@@ -112,12 +116,15 @@
</span><span class="cx">     void didReceiveResponse(WebCore::ResourceResponse&amp;&amp;, ResponseCompletionHandler&amp;&amp;);
</span><span class="cx">     void didReceiveData(Ref&lt;WebCore::SharedBuffer&gt;&amp;&amp;);
</span><span class="cx">     void didBecomeDownload();
</span><del>-    
</del><ins>+
+    void willPerformHTTPRedirection(WebCore::ResourceResponse&amp;&amp;, WebCore::ResourceRequest&amp;&amp;, RedirectCompletionHandler&amp;&amp;);
+    void transferSandboxExtensionToDownload(Download&amp;);
+#endif
</ins><span class="cx">     NetworkDataTaskClient* client() const { return m_client; }
</span><span class="cx">     void clearClient() { m_client = nullptr; }
</span><span class="cx">     
</span><del>-    DownloadID pendingDownloadID() { return m_pendingDownloadID; }
-    PendingDownload* pendingDownload() { return m_pendingDownload; }
</del><ins>+    DownloadID pendingDownloadID() const { return m_pendingDownloadID; }
+    PendingDownload* pendingDownload() const { return m_pendingDownload; }
</ins><span class="cx">     void setPendingDownloadID(DownloadID downloadID)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(!m_pendingDownloadID.downloadID());
</span><span class="lines">@@ -130,13 +137,12 @@
</span><span class="cx">         m_pendingDownload = &amp;pendingDownload;
</span><span class="cx">     }
</span><span class="cx">     void setPendingDownloadLocation(const String&amp; filename, const SandboxExtension::Handle&amp;, bool allowOverwrite);
</span><del>-    const String&amp; pendingDownloadLocation() { return m_pendingDownloadLocation; }
</del><ins>+    const String&amp; pendingDownloadLocation() const { return m_pendingDownloadLocation; }
+    bool isDownload() const { return !!m_pendingDownloadID.downloadID(); }
</ins><span class="cx"> 
</span><span class="cx">     const WebCore::ResourceRequest&amp; firstRequest() const { return m_firstRequest; }
</span><span class="cx">     String suggestedFilename();
</span><span class="cx">     void setSuggestedFilename(const String&amp;);
</span><del>-    void willPerformHTTPRedirection(WebCore::ResourceResponse&amp;&amp;, WebCore::ResourceRequest&amp;&amp;, RedirectCompletionHandler&amp;&amp;);
-    void transferSandboxExtensionToDownload(Download&amp;);
</del><span class="cx">     bool allowsSpecificHTTPSCertificateForHost(const WebCore::AuthenticationChallenge&amp;);
</span><span class="cx">     
</span><span class="cx"> private:
</span><span class="lines">@@ -143,6 +149,61 @@
</span><span class="cx">     NetworkDataTask(NetworkSession&amp;, NetworkDataTaskClient&amp;, const WebCore::ResourceRequest&amp;, WebCore::StoredCredentials, WebCore::ContentSniffingPolicy, bool shouldClearReferrerOnHTTPSToHTTPRedirect);
</span><span class="cx"> 
</span><span class="cx">     bool tryPasswordBasedAuthentication(const WebCore::AuthenticationChallenge&amp;, const ChallengeCompletionHandler&amp;);
</span><ins>+
+#if USE(SOUP)
+    void timeoutFired();
+    void startTimeout();
+    void stopTimeout();
+    void invalidateAndCancel();
+    void createRequest(const WebCore::ResourceRequest&amp;);
+    void clearRequest();
+    static void sendRequestCallback(SoupRequest*, GAsyncResult*, NetworkDataTask*);
+    void didSendRequest(GRefPtr&lt;GInputStream&gt;&amp;&amp;);
+    void didReceiveResponse();
+    static void tlsErrorsChangedCallback(SoupMessage*, GParamSpec*, NetworkDataTask*);
+    void tlsErrorsChanged();
+    void applyAuthenticationToRequest(WebCore::ResourceRequest&amp;);
+    static void authenticateCallback(SoupSession*, SoupMessage*, SoupAuth*, gboolean retrying, NetworkDataTask*);
+    void authenticate(WebCore::AuthenticationChallenge&amp;&amp;);
+    void continueAuthenticate(WebCore::AuthenticationChallenge&amp;&amp;);
+    static void skipInputStreamForRedirectionCallback(GInputStream*, GAsyncResult*, NetworkDataTask*);
+    void skipInputStreamForRedirection();
+    void didFinishSkipInputStreamForRedirection();
+    bool shouldStartHTTPRedirection();
+    void continueHTTPRedirection();
+    static void readCallback(GInputStream*, GAsyncResult*, NetworkDataTask*);
+    void read();
+    void didRead(gssize bytesRead);
+    void didFinishRead();
+    static void requestNextPartCallback(SoupMultipartInputStream*, GAsyncResult*, NetworkDataTask*);
+    void requestNextPart();
+    void didRequestNextPart(GRefPtr&lt;GInputStream&gt;&amp;&amp;);
+    void didFinishRequestNextPart();
+    static void gotHeadersCallback(SoupMessage*, NetworkDataTask*);
+    void didGetHeaders();
+    static void wroteBodyDataCallback(SoupMessage*, SoupBuffer*, NetworkDataTask*);
+    void didWriteBodyData(uint64_t bytesSent);
+    void download();
+    static void writeDownloadCallback(GOutputStream*, GAsyncResult*, NetworkDataTask*);
+    void writeDownload();
+    void didWriteDownload(gsize bytesWritten);
+    void didFailDownload(const WebCore::ResourceError&amp;);
+    void didFinishDownload();
+    void cleanDownloadFiles();
+    void didFail(const WebCore::ResourceError&amp;);
+#if ENABLE(WEB_TIMING)
+    static void networkEventCallback(SoupMessage*, GSocketClientEvent, GIOStream*, NetworkDataTask*);
+    void networkEvent(GSocketClientEvent);
+#if SOUP_CHECK_VERSION(2, 49, 91)
+    static void startingCallback(SoupMessage*, NetworkDataTask*);
+#else
+    static void requestStartedCallback(SoupSession*, SoupMessage*, SoupSocket*, NetworkDataTask*);
+#endif
+    void didStartRequest();
+    static void restartedCallback(SoupMessage*, NetworkDataTask*);
+    void didRestart();
+#endif
+#endif
</ins><span class="cx">     
</span><span class="cx">     enum FailureType {
</span><span class="cx">         NoFailure,
</span><span class="lines">@@ -172,6 +233,30 @@
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx">     RetainPtr&lt;NSURLSessionDataTask&gt; m_task;
</span><span class="cx"> #endif
</span><ins>+#if USE(SOUP)
+    State m_state { State::Suspended };
+    WebCore::ContentSniffingPolicy m_shouldContentSniff;
+    GRefPtr&lt;SoupRequest&gt; m_soupRequest;
+    GRefPtr&lt;SoupMessage&gt; m_soupMessage;
+    GRefPtr&lt;GInputStream&gt; m_inputStream;
+    GRefPtr&lt;SoupMultipartInputStream&gt; m_multipartInputStream;
+    GRefPtr&lt;GCancellable&gt; m_cancellable;
+    GRefPtr&lt;GAsyncResult&gt; m_pendingResult;
+    WebCore::ProtectionSpace m_protectionSpaceForPersistentStorage;
+    WebCore::Credential m_credentialForPersistentStorage;
+    WebCore::ResourceResponse m_response;
+    Vector&lt;char&gt; m_readBuffer;
+    unsigned m_redirectCount { 0 };
+    uint64_t m_bodyDataTotalBytesSent { 0 };
+    GRefPtr&lt;GFile&gt; m_downloadDestinationFile;
+    GRefPtr&lt;GFile&gt; m_downloadIntermediateFile;
+    GRefPtr&lt;GOutputStream&gt; m_downloadOutputStream;
+    bool m_allowOverwriteDownload { false };
+#if ENABLE(WEB_TIMING)
+    double m_startTime { 0 };
+#endif
+    RunLoop::Timer&lt;NetworkDataTask&gt; m_timeoutSource;
+#endif
</ins><span class="cx">     String m_suggestedFilename;
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -181,4 +266,4 @@
</span><span class="cx">     
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#endif
</del><ins>+#endif // USE(NETWORK_SESSION)
</ins></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkLoadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -271,7 +271,7 @@
</span><span class="cx"> void NetworkLoad::didReceiveResponseNetworkSession(ResourceResponse&amp;&amp; response, ResponseCompletionHandler&amp;&amp; completionHandler)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><del>-    if (m_task &amp;&amp; m_task-&gt;pendingDownloadID().downloadID())
</del><ins>+    if (m_task &amp;&amp; m_task-&gt;isDownload())
</ins><span class="cx">         NetworkProcess::singleton().findPendingDownloadLocation(*m_task.get(), WTFMove(completionHandler), response);
</span><span class="cx">     else if (sharedDidReceiveResponse(WTFMove(response)) == NetworkLoadClient::ShouldContinueDidReceiveResponse::Yes)
</span><span class="cx">         completionHandler(PolicyUse);
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkProcesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx"> #include &quot;NetworkProcessPlatformStrategies.h&quot;
</span><span class="cx"> #include &quot;NetworkProcessProxyMessages.h&quot;
</span><span class="cx"> #include &quot;NetworkResourceLoader.h&quot;
</span><ins>+#include &quot;NetworkSession.h&quot;
</ins><span class="cx"> #include &quot;RemoteNetworkingContext.h&quot;
</span><span class="cx"> #include &quot;SessionTracker.h&quot;
</span><span class="cx"> #include &quot;StatisticsData.h&quot;
</span><span class="lines">@@ -100,7 +101,7 @@
</span><span class="cx">     addSupplement&lt;AuthenticationManager&gt;();
</span><span class="cx">     addSupplement&lt;WebCookieManager&gt;();
</span><span class="cx">     addSupplement&lt;CustomProtocolManager&gt;();
</span><del>-#if USE(NETWORK_SESSION)
</del><ins>+#if USE(NETWORK_SESSION) &amp;&amp; PLATFORM(COCOA)
</ins><span class="cx">     NetworkSession::setCustomProtocolManager(supplement&lt;CustomProtocolManager&gt;());
</span><span class="cx"> #endif
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkSessionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkSession.h (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkSession.h        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkSession.h        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -25,6 +25,8 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><ins>+#if USE(NETWORK_SESSION)
+
</ins><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx"> OBJC_CLASS NSURLSession;
</span><span class="cx"> OBJC_CLASS NSOperationQueue;
</span><span class="lines">@@ -35,9 +37,14 @@
</span><span class="cx"> #include &quot;NetworkDataTask.h&quot;
</span><span class="cx"> #include &lt;WebCore/SessionID.h&gt;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><ins>+#include &lt;wtf/HashSet.h&gt;
</ins><span class="cx"> #include &lt;wtf/Ref.h&gt;
</span><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> 
</span><ins>+#if USE(SOUP)
+typedef struct _SoupSession SoupSession;
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> class NetworkStorageSession;
</span><span class="cx"> }
</span><span class="lines">@@ -62,9 +69,13 @@
</span><span class="cx"> 
</span><span class="cx">     WebCore::SessionID sessionID() const { return m_sessionID; }
</span><span class="cx"> 
</span><ins>+#if USE(SOUP)
+    SoupSession* soupSession() const;
+#endif
+
+#if PLATFORM(COCOA)
</ins><span class="cx">     // Must be called before any NetworkSession has been created.
</span><span class="cx">     static void setCustomProtocolManager(CustomProtocolManager*);
</span><del>-#if PLATFORM(COCOA)
</del><span class="cx">     static void setSourceApplicationAuditTokenData(RetainPtr&lt;CFDataRef&gt;&amp;&amp;);
</span><span class="cx">     static void setSourceApplicationBundleIdentifier(const String&amp;);
</span><span class="cx">     static void setSourceApplicationSecondaryIdentifier(const String&amp;);
</span><span class="lines">@@ -74,29 +85,34 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     void clearCredentials();
</span><del>-
</del><ins>+#if PLATFORM(COCOA)
</ins><span class="cx">     NetworkDataTask* dataTaskForIdentifier(NetworkDataTask::TaskIdentifier, WebCore::StoredCredentials);
</span><span class="cx"> 
</span><span class="cx">     void addDownloadID(NetworkDataTask::TaskIdentifier, DownloadID);
</span><span class="cx">     DownloadID downloadID(NetworkDataTask::TaskIdentifier);
</span><span class="cx">     DownloadID takeDownloadID(NetworkDataTask::TaskIdentifier);
</span><del>-    
</del><ins>+#endif
+
</ins><span class="cx"> private:
</span><span class="cx">     NetworkSession(Type, WebCore::SessionID, CustomProtocolManager*);
</span><del>-    WebCore::NetworkStorageSession&amp; networkStorageSession();
</del><ins>+    WebCore::NetworkStorageSession&amp; networkStorageSession() const;
</ins><span class="cx"> 
</span><span class="cx">     WebCore::SessionID m_sessionID;
</span><span class="cx"> 
</span><ins>+#if PLATFORM(COCOA)
</ins><span class="cx">     HashMap&lt;NetworkDataTask::TaskIdentifier, NetworkDataTask*&gt; m_dataTaskMapWithCredentials;
</span><span class="cx">     HashMap&lt;NetworkDataTask::TaskIdentifier, NetworkDataTask*&gt; m_dataTaskMapWithoutCredentials;
</span><span class="cx">     HashMap&lt;NetworkDataTask::TaskIdentifier, DownloadID&gt; m_downloadMap;
</span><span class="cx"> 
</span><del>-#if PLATFORM(COCOA)
</del><span class="cx">     RetainPtr&lt;NSURLSession&gt; m_sessionWithCredentialStorage;
</span><span class="cx">     RetainPtr&lt;WKNetworkSessionDelegate&gt; m_sessionWithCredentialStorageDelegate;
</span><span class="cx">     RetainPtr&lt;NSURLSession&gt; m_sessionWithoutCredentialStorage;
</span><span class="cx">     RetainPtr&lt;WKNetworkSessionDelegate&gt; m_sessionWithoutCredentialStorageDelegate;
</span><ins>+#elif USE(SOUP)
+    HashSet&lt;NetworkDataTask*&gt; m_dataTaskSet;
</ins><span class="cx"> #endif
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit
</span><ins>+
+#endif // USE(NETWORK_SESSION)
</ins></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessPingLoadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/PingLoad.h (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/PingLoad.h        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/NetworkProcess/PingLoad.h        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #ifndef PingLoad_h
</span><span class="cx"> #define PingLoad_h
</span><span class="cx"> 
</span><ins>+#include &quot;AuthenticationManager.h&quot;
</ins><span class="cx"> #include &quot;NetworkDataTask.h&quot;
</span><span class="cx"> #include &quot;SessionTracker.h&quot;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscocoaNetworkDataTaskCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if USE(NETWORK_SESSION)
</span><span class="cx"> 
</span><ins>+#import &quot;AuthenticationManager.h&quot;
</ins><span class="cx"> #import &quot;Download.h&quot;
</span><span class="cx"> #import &quot;DownloadProxyMessages.h&quot;
</span><span class="cx"> #import &quot;Logging.h&quot;
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscocoaNetworkSessionCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if USE(NETWORK_SESSION)
</span><span class="cx"> 
</span><ins>+#import &quot;AuthenticationManager.h&quot;
</ins><span class="cx"> #import &quot;CustomProtocolManager.h&quot;
</span><span class="cx"> #import &quot;DataReference.h&quot;
</span><span class="cx"> #import &quot;Download.h&quot;
</span><span class="lines">@@ -475,7 +476,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-WebCore::NetworkStorageSession&amp; NetworkSession::networkStorageSession()
</del><ins>+WebCore::NetworkStorageSession&amp; NetworkSession::networkStorageSession() const
</ins><span class="cx"> {
</span><span class="cx">     auto* storageSession = WebCore::NetworkStorageSession::storageSession(m_sessionID);
</span><span class="cx">     RELEASE_ASSERT(storageSession);
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesssoupNetworkDataTaskSoupcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/NetworkProcess/soup/NetworkDataTaskSoup.cpp (0 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/soup/NetworkDataTaskSoup.cpp                                (rev 0)
+++ trunk/Source/WebKit2/NetworkProcess/soup/NetworkDataTaskSoup.cpp        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -0,0 +1,1153 @@
</span><ins>+/*
+ * Copyright (C) 2016 Igalia S.L.
+ *
+ * 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;NetworkDataTask.h&quot;
+
+#include &quot;AuthenticationManager.h&quot;
+#include &quot;DataReference.h&quot;
+#include &quot;Download.h&quot;
+#include &quot;DownloadSoupErrors.h&quot;
+#include &quot;NetworkLoad.h&quot;
+#include &quot;NetworkProcess.h&quot;
+#include &quot;NetworkSession.h&quot;
+#include &quot;WebErrors.h&quot;
+#include &lt;WebCore/AuthenticationChallenge.h&gt;
+#include &lt;WebCore/HTTPParsers.h&gt;
+#include &lt;WebCore/NetworkStorageSession.h&gt;
+#include &lt;WebCore/SharedBuffer.h&gt;
+#include &lt;WebCore/SoupNetworkSession.h&gt;
+#include &lt;wtf/MainThread.h&gt;
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static const size_t gDefaultReadBufferSize = 8192;
+
+NetworkDataTask::NetworkDataTask(NetworkSession&amp; session, NetworkDataTaskClient&amp; client, const ResourceRequest&amp; requestWithCredentials, StoredCredentials storedCredentials, ContentSniffingPolicy shouldContentSniff, bool shouldClearReferrerOnHTTPSToHTTPRedirect)
+    : m_failureTimer(*this, &amp;NetworkDataTask::failureTimerFired)
+    , m_session(&amp;session)
+    , m_client(&amp;client)
+    , m_storedCredentials(storedCredentials)
+    , m_lastHTTPMethod(requestWithCredentials.httpMethod())
+    , m_firstRequest(requestWithCredentials)
+    , m_shouldClearReferrerOnHTTPSToHTTPRedirect(shouldClearReferrerOnHTTPSToHTTPRedirect)
+    , m_shouldContentSniff(shouldContentSniff)
+    , m_timeoutSource(RunLoop::main(), this, &amp;NetworkDataTask::timeoutFired)
+{
+    ASSERT(isMainThread());
+
+    m_session-&gt;m_dataTaskSet.add(this);
+
+    if (!requestWithCredentials.url().isValid()) {
+        scheduleFailure(InvalidURLFailure);
+        return;
+    }
+
+    if (!portAllowed(requestWithCredentials.url())) {
+        scheduleFailure(BlockedFailure);
+        return;
+    }
+
+    auto request = requestWithCredentials;
+    if (request.url().protocolIsInHTTPFamily()) {
+#if ENABLE(WEB_TIMING)
+        m_startTime = monotonicallyIncreasingTimeMS();
+#endif
+        auto url = request.url();
+        if (m_storedCredentials == AllowStoredCredentials) {
+            m_user = url.user();
+            m_password = url.pass();
+            request.removeCredentials();
+
+            if (m_user.isEmpty() &amp;&amp; m_password.isEmpty())
+                m_initialCredential = m_session-&gt;networkStorageSession().credentialStorage().get(request.url());
+            else
+                m_session-&gt;networkStorageSession().credentialStorage().set(Credential(m_user, m_password, CredentialPersistenceNone), request.url());
+        }
+        applyAuthenticationToRequest(request);
+    }
+    createRequest(request);
+}
+
+NetworkDataTask::~NetworkDataTask()
+{
+    ASSERT(isMainThread());
+    ASSERT(!m_client);
+    clearRequest();
+    m_session-&gt;m_dataTaskSet.remove(this);
+}
+
+void NetworkDataTask::scheduleFailure(FailureType type)
+{
+    ASSERT(type != NoFailure);
+    m_scheduledFailureType = type;
+    m_failureTimer.startOneShot(0);
+}
+
+void NetworkDataTask::failureTimerFired()
+{
+    RefPtr&lt;NetworkDataTask&gt; protectedThis(this);
+
+    switch (m_scheduledFailureType) {
+    case BlockedFailure:
+        m_scheduledFailureType = NoFailure;
+        if (m_client)
+            m_client-&gt;wasBlocked();
+        return;
+    case InvalidURLFailure:
+        m_scheduledFailureType = NoFailure;
+        if (m_client)
+            m_client-&gt;cannotShowURL();
+        return;
+    case NoFailure:
+        ASSERT_NOT_REACHED();
+        break;
+    }
+    ASSERT_NOT_REACHED();
+}
+
+String NetworkDataTask::suggestedFilename()
+{
+    if (!m_suggestedFilename.isEmpty())
+        return m_suggestedFilename;
+
+    String suggestedFilename = m_response.suggestedFilename();
+    if (!suggestedFilename.isEmpty())
+        return suggestedFilename;
+
+    return decodeURLEscapeSequences(m_response.url().lastPathComponent());
+}
+
+void NetworkDataTask::setSuggestedFilename(const String&amp; suggestedName)
+{
+    m_suggestedFilename = suggestedName;
+}
+
+void NetworkDataTask::setPendingDownloadLocation(const String&amp; filename, const SandboxExtension::Handle&amp;, bool allowOverwrite)
+{
+    m_pendingDownloadLocation = filename;
+    m_allowOverwriteDownload = allowOverwrite;
+}
+
+bool NetworkDataTask::allowsSpecificHTTPSCertificateForHost(const AuthenticationChallenge&amp;)
+{
+    return false;
+}
+
+void NetworkDataTask::createRequest(const ResourceRequest&amp; request)
+{
+    GUniquePtr&lt;SoupURI&gt; soupURI = request.createSoupURI();
+    if (!soupURI) {
+        scheduleFailure(InvalidURLFailure);
+        return;
+    }
+
+    GRefPtr&lt;SoupRequest&gt; soupRequest = adoptGRef(soup_session_request_uri(m_session-&gt;soupSession(), soupURI.get(), nullptr));
+    if (!soupRequest) {
+        scheduleFailure(InvalidURLFailure);
+        return;
+    }
+
+    request.updateSoupRequest(soupRequest.get());
+
+    if (!request.url().protocolIsInHTTPFamily()) {
+        m_soupRequest = WTFMove(soupRequest);
+        return;
+    }
+
+    // HTTP request.
+    GRefPtr&lt;SoupMessage&gt; soupMessage = adoptGRef(soup_request_http_get_message(SOUP_REQUEST_HTTP(soupRequest.get())));
+    if (!soupMessage) {
+        scheduleFailure(InvalidURLFailure);
+        return;
+    }
+
+    request.updateSoupMessage(soupMessage.get());
+    if (m_shouldContentSniff == DoNotSniffContent)
+        soup_message_disable_feature(soupMessage.get(), SOUP_TYPE_CONTENT_SNIFFER);
+    if (m_user.isEmpty() &amp;&amp; m_password.isEmpty() &amp;&amp; m_storedCredentials == DoNotAllowStoredCredentials) {
+        // In case credential is not available and credential storage should not to be used,
+        // disable authentication manager so that credentials stored in libsoup are not used.
+        soup_message_disable_feature(soupMessage.get(), SOUP_TYPE_AUTH_MANAGER);
+    }
+
+    // Make sure we have an Accept header for subresources; some sites want this to serve some of their subresources.
+    if (!soup_message_headers_get_one(soupMessage-&gt;request_headers, &quot;Accept&quot;))
+        soup_message_headers_append(soupMessage-&gt;request_headers, &quot;Accept&quot;, &quot;*/*&quot;);
+
+    // In the case of XHR .send() and .send(&quot;&quot;) explicitly tell libsoup to send a zero content-lenght header
+    // for consistency with other UA implementations like Firefox. It's done in the backend here instead of
+    // in XHR code since in XHR CORS checking prevents us from this kind of late header manipulation.
+    if ((soupMessage-&gt;method == SOUP_METHOD_POST || soupMessage-&gt;method == SOUP_METHOD_PUT) &amp;&amp; !soupMessage-&gt;request_body-&gt;length)
+        soup_message_headers_set_content_length(soupMessage-&gt;request_headers, 0);
+
+    unsigned flags = SOUP_MESSAGE_NO_REDIRECT;
+    soup_message_set_flags(soupMessage.get(), static_cast&lt;SoupMessageFlags&gt;(soup_message_get_flags(soupMessage.get()) | flags));
+
+#if SOUP_CHECK_VERSION(2, 43, 1)
+    soup_message_set_priority(soupMessage.get(), toSoupMessagePriority(request.priority()));
+#endif
+
+    m_soupRequest = WTFMove(soupRequest);
+    m_soupMessage = WTFMove(soupMessage);
+
+    g_signal_connect(m_soupMessage.get(), &quot;notify::tls-errors&quot;, G_CALLBACK(tlsErrorsChangedCallback), this);
+    g_signal_connect(m_soupMessage.get(), &quot;got-headers&quot;, G_CALLBACK(gotHeadersCallback), this);
+    g_signal_connect(m_soupMessage.get(), &quot;wrote-body-data&quot;, G_CALLBACK(wroteBodyDataCallback), this);
+    g_signal_connect(m_session-&gt;soupSession(), &quot;authenticate&quot;,  G_CALLBACK(authenticateCallback), this);
+#if ENABLE(WEB_TIMING)
+    g_signal_connect(m_soupMessage.get(), &quot;network-event&quot;, G_CALLBACK(networkEventCallback), this);
+    g_signal_connect(m_soupMessage.get(), &quot;restarted&quot;, G_CALLBACK(restartedCallback), this);
+#if SOUP_CHECK_VERSION(2, 49, 91)
+    g_signal_connect(m_soupMessage.get(), &quot;starting&quot;, G_CALLBACK(startingCallback), this);
+#else
+    g_signal_connect(m_session-&gt;soupSession(), &quot;request-started&quot;, G_CALLBACK(requestStartedCallback), this);
+#endif
+#endif
+}
+
+void NetworkDataTask::clearRequest()
+{
+    if (m_state == State::Completed)
+        return;
+
+    m_state = State::Completed;
+
+    stopTimeout();
+    m_pendingResult = nullptr;
+    m_soupRequest = nullptr;
+    m_inputStream = nullptr;
+    m_multipartInputStream = nullptr;
+    m_downloadOutputStream = nullptr;
+    g_cancellable_cancel(m_cancellable.get());
+    m_cancellable = nullptr;
+    if (m_soupMessage) {
+        g_signal_handlers_disconnect_matched(m_soupMessage.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
+        soup_session_cancel_message(m_session-&gt;soupSession(), m_soupMessage.get(), SOUP_STATUS_CANCELLED);
+        m_soupMessage = nullptr;
+    }
+    g_signal_handlers_disconnect_matched(m_session-&gt;soupSession(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
+}
+
+void NetworkDataTask::resume()
+{
+    ASSERT(m_state != State::Running);
+    if (m_state == State::Canceling || m_state == State::Completed)
+        return;
+
+    m_state = State::Running;
+
+    if (m_scheduledFailureType != NoFailure) {
+        ASSERT(m_failureTimer.isActive());
+        return;
+    }
+
+    startTimeout();
+
+    RefPtr&lt;NetworkDataTask&gt; protectedThis(this);
+    if (m_soupRequest &amp;&amp; !m_cancellable) {
+        m_cancellable = adoptGRef(g_cancellable_new());
+        soup_request_send_async(m_soupRequest.get(), m_cancellable.get(), reinterpret_cast&lt;GAsyncReadyCallback&gt;(sendRequestCallback), protectedThis.leakRef());
+        return;
+    }
+
+    if (m_pendingResult) {
+        GRefPtr&lt;GAsyncResult&gt; pendingResult = WTFMove(m_pendingResult);
+        if (m_inputStream)
+            readCallback(m_inputStream.get(), pendingResult.get(), protectedThis.leakRef());
+        else if (m_multipartInputStream)
+            requestNextPartCallback(m_multipartInputStream.get(), pendingResult.get(), protectedThis.leakRef());
+        else if (m_soupRequest)
+            sendRequestCallback(m_soupRequest.get(), pendingResult.get(), protectedThis.leakRef());
+        else
+            ASSERT_NOT_REACHED();
+    }
+}
+
+void NetworkDataTask::suspend()
+{
+    ASSERT(m_state != State::Suspended);
+    if (m_state == State::Canceling || m_state == State::Completed)
+        return;
+    m_state = State::Suspended;
+
+    stopTimeout();
+}
+
+void NetworkDataTask::cancel()
+{
+    if (m_state == State::Canceling || m_state == State::Completed)
+        return;
+
+    m_state = State::Canceling;
+
+    if (m_soupMessage)
+        soup_session_cancel_message(m_session-&gt;soupSession(), m_soupMessage.get(), SOUP_STATUS_CANCELLED);
+
+    g_cancellable_cancel(m_cancellable.get());
+
+    if (isDownload())
+        cleanDownloadFiles();
+}
+
+void NetworkDataTask::invalidateAndCancel()
+{
+    cancel();
+    clearRequest();
+}
+
+NetworkDataTask::State NetworkDataTask::state() const
+{
+    return m_state;
+}
+
+void NetworkDataTask::timeoutFired()
+{
+    if (m_state == State::Canceling || m_state == State::Completed || !m_client) {
+        clearRequest();
+        return;
+    }
+
+    RefPtr&lt;NetworkDataTask&gt; protectedThis(this);
+    invalidateAndCancel();
+    m_client-&gt;didCompleteWithError(ResourceError::timeoutError(m_firstRequest.url()));
+}
+
+void NetworkDataTask::startTimeout()
+{
+    if (m_firstRequest.timeoutInterval() &gt; 0)
+        m_timeoutSource.startOneShot(m_firstRequest.timeoutInterval());
+}
+
+void NetworkDataTask::stopTimeout()
+{
+    m_timeoutSource.stop();
+}
+
+void NetworkDataTask::sendRequestCallback(SoupRequest* soupRequest, GAsyncResult* result, NetworkDataTask* task)
+{
+    RefPtr&lt;NetworkDataTask&gt; protectedThis = adoptRef(task);
+    if (task-&gt;state() == State::Canceling || task-&gt;state() == State::Completed || !task-&gt;m_client) {
+        task-&gt;clearRequest();
+        return;
+    }
+    ASSERT(soupRequest == task-&gt;m_soupRequest.get());
+
+    if (task-&gt;state() == State::Suspended) {
+        ASSERT(!task-&gt;m_pendingResult);
+        task-&gt;m_pendingResult = result;
+        return;
+    }
+
+    GUniqueOutPtr&lt;GError&gt; error;
+    GRefPtr&lt;GInputStream&gt; inputStream = adoptGRef(soup_request_send_finish(soupRequest, result, &amp;error.outPtr()));
+    if (error)
+        task-&gt;didFail(ResourceError::httpError(task-&gt;m_soupMessage.get(), error.get(), soupRequest));
+    else
+        task-&gt;didSendRequest(WTFMove(inputStream));
+}
+
+void NetworkDataTask::didSendRequest(GRefPtr&lt;GInputStream&gt;&amp;&amp; inputStream)
+{
+    if (m_soupMessage) {
+        if (m_shouldContentSniff == SniffContent &amp;&amp; m_soupMessage-&gt;status_code != SOUP_STATUS_NOT_MODIFIED)
+            m_response.setSniffedContentType(soup_request_get_content_type(m_soupRequest.get()));
+        m_response.updateFromSoupMessage(m_soupMessage.get());
+
+        if (shouldStartHTTPRedirection()) {
+            m_inputStream = WTFMove(inputStream);
+            skipInputStreamForRedirection();
+            return;
+        }
+
+        if (m_response.isMultipart())
+            m_multipartInputStream = adoptGRef(soup_multipart_input_stream_new(m_soupMessage.get(), inputStream.get()));
+        else
+            m_inputStream = WTFMove(inputStream);
+
+#if ENABLE(WEB_TIMING)
+        m_response.networkLoadTiming().responseStart = monotonicallyIncreasingTimeMS() - m_startTime;
+#endif
+    } else {
+        m_response.setURL(m_firstRequest.url());
+        const gchar* contentType = soup_request_get_content_type(m_soupRequest.get());
+        m_response.setMimeType(extractMIMETypeFromMediaType(contentType));
+        m_response.setTextEncodingName(extractCharsetFromMediaType(contentType));
+        m_response.setExpectedContentLength(soup_request_get_content_length(m_soupRequest.get()));
+
+        m_inputStream = WTFMove(inputStream);
+    }
+
+    didReceiveResponse();
+}
+
+void NetworkDataTask::didReceiveResponse()
+{
+    ASSERT(!m_response.isNull());
+
+    auto response = ResourceResponse(m_response);
+    m_client-&gt;didReceiveResponseNetworkSession(WTFMove(response), [this, protectedThis = makeRef(*this)](PolicyAction policyAction) {
+        if (m_state == State::Canceling || m_state == State::Completed) {
+            clearRequest();
+            return;
+        }
+
+        switch (policyAction) {
+        case PolicyAction::PolicyUse:
+            if (m_inputStream)
+                read();
+            else if (m_multipartInputStream)
+                requestNextPart();
+            else
+                ASSERT_NOT_REACHED();
+
+            break;
+        case PolicyAction::PolicyIgnore:
+            clearRequest();
+            break;
+        case PolicyAction::PolicyDownload:
+            download();
+            break;
+        }
+    });
+}
+
+void NetworkDataTask::tlsErrorsChangedCallback(SoupMessage* soupMessage, GParamSpec*, NetworkDataTask* task)
+{
+    if (task-&gt;state() == State::Canceling || task-&gt;state() == State::Completed || !task-&gt;m_client) {
+        task-&gt;clearRequest();
+        return;
+    }
+
+    ASSERT(soupMessage == task-&gt;m_soupMessage.get());
+    task-&gt;tlsErrorsChanged();
+}
+
+void NetworkDataTask::tlsErrorsChanged()
+{
+    ASSERT(m_soupRequest);
+    SoupNetworkSession::checkTLSErrors(m_soupRequest.get(), m_soupMessage.get(), [this] (const ResourceError&amp; error) {
+        if (error.isNull())
+            return;
+
+        RefPtr&lt;NetworkDataTask&gt; protectedThis(this);
+        invalidateAndCancel();
+        m_client-&gt;didCompleteWithError(error);
+    });
+}
+
+void NetworkDataTask::applyAuthenticationToRequest(ResourceRequest&amp; request)
+{
+    // We always put the credentials into the URL. In the Coca port HTTP family credentials are applied in
+    // the didReceiveChallenge callback, but libsoup requires us to use this method to override
+    // any previously remembered credentials. It has its own per-session credential storage.
+    auto url = request.url();
+    if (!m_initialCredential.isEmpty()) {
+        url.setUser(m_initialCredential.user());
+        url.setPass(m_initialCredential.password());
+    } else {
+        url.setUser(m_user);
+        url.setPass(m_password);
+    }
+
+    m_user = String();
+    m_password = String();
+
+    request.setURL(url);
+}
+
+void NetworkDataTask::authenticateCallback(SoupSession* session, SoupMessage* soupMessage, SoupAuth* soupAuth, gboolean retrying, NetworkDataTask* task)
+{
+    ASSERT(session == task-&gt;m_session-&gt;soupSession());
+    if (soupMessage != task-&gt;m_soupMessage.get())
+        return;
+
+    if (task-&gt;state() == State::Canceling || task-&gt;state() == State::Completed || !task-&gt;m_client) {
+        task-&gt;clearRequest();
+        return;
+    }
+
+    task-&gt;authenticate(AuthenticationChallenge(soupMessage, soupAuth, retrying));
+}
+
+static inline bool isAuthenticationFailureStatusCode(int httpStatusCode)
+{
+    return httpStatusCode == SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED || httpStatusCode == SOUP_STATUS_UNAUTHORIZED;
+}
+
+void NetworkDataTask::authenticate(AuthenticationChallenge&amp;&amp; challenge)
+{
+    ASSERT(m_soupMessage);
+    if (m_storedCredentials == AllowStoredCredentials) {
+        if (!m_initialCredential.isEmpty() || challenge.previousFailureCount()) {
+            // The stored credential wasn't accepted, stop using it. There is a race condition
+            // here, since a different credential might have already been stored by another
+            // NetworkDataTask, but the observable effect should be very minor, if any.
+            m_session-&gt;networkStorageSession().credentialStorage().remove(challenge.protectionSpace());
+        }
+
+        if (!challenge.previousFailureCount()) {
+            auto credential = m_session-&gt;networkStorageSession().credentialStorage().get(challenge.protectionSpace());
+            if (!credential.isEmpty() &amp;&amp; credential != m_initialCredential) {
+                ASSERT(credential.persistence() == CredentialPersistenceNone);
+
+                if (isAuthenticationFailureStatusCode(challenge.failureResponse().httpStatusCode())) {
+                    // Store the credential back, possibly adding it as a default for this directory.
+                    m_session-&gt;networkStorageSession().credentialStorage().set(credential, challenge.protectionSpace(), challenge.failureResponse().url());
+                }
+                soup_auth_authenticate(challenge.soupAuth(), credential.user().utf8().data(), credential.password().utf8().data());
+                return;
+            }
+        }
+    }
+
+    soup_session_pause_message(m_session-&gt;soupSession(), m_soupMessage.get());
+
+    // We could also do this before we even start the request, but that would be at the expense
+    // of all request latency, versus a one-time latency for the small subset of requests that
+    // use HTTP authentication. In the end, this doesn't matter much, because persistent credentials
+    // will become session credentials after the first use.
+    if (m_storedCredentials == AllowStoredCredentials) {
+        auto protectionSpace = challenge.protectionSpace();
+        m_session-&gt;networkStorageSession().getCredentialFromPersistentStorage(protectionSpace,
+            [this, protectedThis = makeRef(*this), authChallenge = WTFMove(challenge)] (Credential&amp;&amp; credential) mutable {
+                if (m_state == State::Canceling || m_state == State::Completed || !m_client) {
+                    clearRequest();
+                    return;
+                }
+
+                authChallenge.setProposedCredential(WTFMove(credential));
+                continueAuthenticate(WTFMove(authChallenge));
+        });
+    } else
+        continueAuthenticate(WTFMove(challenge));
+}
+
+void NetworkDataTask::continueAuthenticate(AuthenticationChallenge&amp;&amp; challenge)
+{
+    m_client-&gt;didReceiveChallenge(challenge, [this, protectedThis = makeRef(*this), challenge](AuthenticationChallengeDisposition disposition, const Credential&amp; credential) {
+        if (m_state == State::Canceling || m_state == State::Completed) {
+            clearRequest();
+            return;
+        }
+
+        if (disposition == AuthenticationChallengeDisposition::Cancel) {
+            cancel();
+            didFail(cancelledError(m_soupRequest.get()));
+            return;
+        }
+
+        if (disposition == AuthenticationChallengeDisposition::UseCredential &amp;&amp; !credential.isEmpty()) {
+            if (m_storedCredentials == AllowStoredCredentials) {
+                // Eventually we will manage per-session credentials only internally or use some newly-exposed API from libsoup,
+                // because once we authenticate via libsoup, there is no way to ignore it for a particular request. Right now,
+                // we place the credentials in the store even though libsoup will never fire the authenticate signal again for
+                // this protection space.
+                if (credential.persistence() == CredentialPersistenceForSession || credential.persistence() == CredentialPersistencePermanent)
+                    m_session-&gt;networkStorageSession().credentialStorage().set(credential, challenge.protectionSpace(), challenge.failureResponse().url());
+
+                if (credential.persistence() == CredentialPersistencePermanent) {
+                    m_protectionSpaceForPersistentStorage = challenge.protectionSpace();
+                    m_credentialForPersistentStorage = credential;
+                }
+            }
+
+            soup_auth_authenticate(challenge.soupAuth(), credential.user().utf8().data(), credential.password().utf8().data());
+        }
+
+        soup_session_unpause_message(m_session-&gt;soupSession(), m_soupMessage.get());
+    });
+}
+
+void NetworkDataTask::skipInputStreamForRedirectionCallback(GInputStream* inputStream, GAsyncResult* result, NetworkDataTask* task)
+{
+    RefPtr&lt;NetworkDataTask&gt; protectedThis = adoptRef(task);
+    if (task-&gt;state() == State::Canceling || task-&gt;state() == State::Completed || !task-&gt;m_client) {
+        task-&gt;clearRequest();
+        return;
+    }
+    ASSERT(inputStream == task-&gt;m_inputStream.get());
+
+    GUniqueOutPtr&lt;GError&gt; error;
+    gssize bytesSkipped = g_input_stream_skip_finish(inputStream, result, &amp;error.outPtr());
+    if (error)
+        task-&gt;didFail(ResourceError::genericGError(error.get(), task-&gt;m_soupRequest.get()));
+    else if (bytesSkipped &gt; 0)
+        task-&gt;skipInputStreamForRedirection();
+    else
+        task-&gt;didFinishSkipInputStreamForRedirection();
+}
+
+void NetworkDataTask::skipInputStreamForRedirection()
+{
+    ASSERT(m_inputStream);
+    RefPtr&lt;NetworkDataTask&gt; protectedThis(this);
+    g_input_stream_skip_async(m_inputStream.get(), gDefaultReadBufferSize, G_PRIORITY_DEFAULT, m_cancellable.get(),
+        reinterpret_cast&lt;GAsyncReadyCallback&gt;(skipInputStreamForRedirectionCallback), protectedThis.leakRef());
+}
+
+void NetworkDataTask::didFinishSkipInputStreamForRedirection()
+{
+    g_input_stream_close(m_inputStream.get(), nullptr, nullptr);
+    continueHTTPRedirection();
+}
+
+static bool shouldRedirectAsGET(SoupMessage* message, bool crossOrigin)
+{
+    if (message-&gt;method == SOUP_METHOD_GET || message-&gt;method == SOUP_METHOD_HEAD)
+        return false;
+
+    switch (message-&gt;status_code) {
+    case SOUP_STATUS_SEE_OTHER:
+        return true;
+    case SOUP_STATUS_FOUND:
+    case SOUP_STATUS_MOVED_PERMANENTLY:
+        if (message-&gt;method == SOUP_METHOD_POST)
+            return true;
+        break;
+    }
+
+    if (crossOrigin &amp;&amp; message-&gt;method == SOUP_METHOD_DELETE)
+        return true;
+
+    return false;
+}
+
+bool NetworkDataTask::shouldStartHTTPRedirection()
+{
+    ASSERT(m_soupMessage);
+    ASSERT(!m_response.isNull());
+
+    auto status = m_response.httpStatusCode();
+    if (!SOUP_STATUS_IS_REDIRECTION(status))
+        return false;
+
+    // Some 3xx status codes aren't actually redirects.
+    if (status == 300 || status == 304 || status == 305 || status == 306)
+        return false;
+
+    if (m_response.httpHeaderField(HTTPHeaderName::Location).isEmpty())
+        return false;
+
+    return true;
+}
+
+void NetworkDataTask::continueHTTPRedirection()
+{
+    ASSERT(m_soupMessage);
+    ASSERT(!m_response.isNull());
+
+    static const unsigned maxRedirects = 20;
+    if (m_redirectCount++ &gt; maxRedirects) {
+        didFail(ResourceError::transportError(m_soupRequest.get(), SOUP_STATUS_TOO_MANY_REDIRECTS, &quot;Too many redirects&quot;));
+        return;
+    }
+
+    ResourceRequest request = m_firstRequest;
+    request.setURL(URL(m_response.url(), m_response.httpHeaderField(HTTPHeaderName::Location)));
+    request.setFirstPartyForCookies(request.url());
+
+    // Should not set Referer after a redirect from a secure resource to non-secure one.
+    if (m_shouldClearReferrerOnHTTPSToHTTPRedirect &amp;&amp; !request.url().protocolIs(&quot;https&quot;) &amp;&amp; protocolIs(request.httpReferrer(), &quot;https&quot;))
+        request.clearHTTPReferrer();
+
+    bool isCrossOrigin = !protocolHostAndPortAreEqual(m_firstRequest.url(), request.url());
+    if (!equalLettersIgnoringASCIICase(request.httpMethod(), &quot;GET&quot;)) {
+        // Change newRequest method to GET if change was made during a previous redirection or if current redirection says so.
+        if (m_soupMessage-&gt;method == SOUP_METHOD_GET || !request.url().protocolIsInHTTPFamily() || shouldRedirectAsGET(m_soupMessage.get(), isCrossOrigin)) {
+            request.setHTTPMethod(&quot;GET&quot;);
+            request.setHTTPBody(nullptr);
+            request.clearHTTPContentType();
+        }
+    }
+
+    const auto&amp; url = request.url();
+    m_user = url.user();
+    m_password = url.pass();
+    m_lastHTTPMethod = request.httpMethod();
+    request.removeCredentials();
+
+    if (isCrossOrigin) {
+        // The network layer might carry over some headers from the original request that
+        // we want to strip here because the redirect is cross-origin.
+        request.clearHTTPAuthorization();
+        request.clearHTTPOrigin();
+    } else if (url.protocolIsInHTTPFamily() &amp;&amp; m_storedCredentials == AllowStoredCredentials) {
+        if (m_user.isEmpty() &amp;&amp; m_password.isEmpty()) {
+            auto credential = m_session-&gt;networkStorageSession().credentialStorage().get(request.url());
+            if (!credential.isEmpty())
+                m_initialCredential = credential;
+        }
+    }
+
+    clearRequest();
+
+    auto response = ResourceResponse(m_response);
+    m_client-&gt;willPerformHTTPRedirection(WTFMove(response), WTFMove(request), [this, protectedThis = makeRef(*this), isCrossOrigin](const ResourceRequest&amp; newRequest) {
+        if (newRequest.isNull() || m_state == State::Canceling)
+            return;
+
+        auto request = newRequest;
+        if (request.url().protocolIsInHTTPFamily()) {
+#if ENABLE(WEB_TIMING)
+            if (isCrossOrigin)
+                m_startTime = monotonicallyIncreasingTimeMS();
+#endif
+            applyAuthenticationToRequest(request);
+        }
+        createRequest(request);
+        if (m_soupRequest &amp;&amp; m_state != State::Suspended) {
+            m_state = State::Suspended;
+            resume();
+        }
+    });
+}
+
+void NetworkDataTask::readCallback(GInputStream* inputStream, GAsyncResult* result, NetworkDataTask* task)
+{
+    RefPtr&lt;NetworkDataTask&gt; protectedThis = adoptRef(task);
+    if (task-&gt;state() == State::Canceling || task-&gt;state() == State::Completed || (!task-&gt;m_client &amp;&amp; !task-&gt;isDownload())) {
+        task-&gt;clearRequest();
+        return;
+    }
+    ASSERT(inputStream == task-&gt;m_inputStream.get());
+
+    if (task-&gt;state() == State::Suspended) {
+        ASSERT(!task-&gt;m_pendingResult);
+        task-&gt;m_pendingResult = result;
+        return;
+    }
+
+    GUniqueOutPtr&lt;GError&gt; error;
+    gssize bytesRead = g_input_stream_read_finish(inputStream, result, &amp;error.outPtr());
+    if (error)
+        task-&gt;didFail(ResourceError::genericGError(error.get(), task-&gt;m_soupRequest.get()));
+    else if (bytesRead &gt; 0)
+        task-&gt;didRead(bytesRead);
+    else
+        task-&gt;didFinishRead();
+}
+
+void NetworkDataTask::read()
+{
+    RefPtr&lt;NetworkDataTask&gt; protectedThis(this);
+    ASSERT(m_inputStream);
+    m_readBuffer.grow(gDefaultReadBufferSize);
+    g_input_stream_read_async(m_inputStream.get(), m_readBuffer.data(), m_readBuffer.size(), G_PRIORITY_DEFAULT, m_cancellable.get(),
+        reinterpret_cast&lt;GAsyncReadyCallback&gt;(readCallback), protectedThis.leakRef());
+}
+
+void NetworkDataTask::didRead(gssize bytesRead)
+{
+    m_readBuffer.shrink(bytesRead);
+    if (m_downloadOutputStream) {
+        ASSERT(isDownload());
+        writeDownload();
+    } else {
+        ASSERT(m_client);
+        m_client-&gt;didReceiveData(SharedBuffer::adoptVector(m_readBuffer));
+        read();
+    }
+}
+
+void NetworkDataTask::didFinishRead()
+{
+    ASSERT(m_inputStream);
+    g_input_stream_close(m_inputStream.get(), nullptr, nullptr);
+    m_inputStream = nullptr;
+    if (m_multipartInputStream) {
+        requestNextPart();
+        return;
+    }
+
+    if (m_downloadOutputStream) {
+        didFinishDownload();
+        return;
+    }
+
+    clearRequest();
+    ASSERT(m_client);
+    m_client-&gt;didCompleteWithError({ });
+}
+
+void NetworkDataTask::requestNextPartCallback(SoupMultipartInputStream* multipartInputStream, GAsyncResult* result, NetworkDataTask* task)
+{
+    RefPtr&lt;NetworkDataTask&gt; protectedThis = adoptRef(task);
+    if (task-&gt;state() == State::Canceling || task-&gt;state() == State::Completed || !task-&gt;m_client) {
+        task-&gt;clearRequest();
+        return;
+    }
+    ASSERT(multipartInputStream == task-&gt;m_multipartInputStream.get());
+
+    if (task-&gt;state() == State::Suspended) {
+        ASSERT(!task-&gt;m_pendingResult);
+        task-&gt;m_pendingResult = result;
+        return;
+    }
+
+    GUniqueOutPtr&lt;GError&gt; error;
+    GRefPtr&lt;GInputStream&gt; inputStream = adoptGRef(soup_multipart_input_stream_next_part_finish(multipartInputStream, result, &amp;error.outPtr()));
+    if (error)
+        task-&gt;didFail(ResourceError::httpError(task-&gt;m_soupMessage.get(), error.get(), task-&gt;m_soupRequest.get()));
+    else if (inputStream)
+        task-&gt;didRequestNextPart(WTFMove(inputStream));
+    else
+        task-&gt;didFinishRequestNextPart();
+}
+
+void NetworkDataTask::requestNextPart()
+{
+    RefPtr&lt;NetworkDataTask&gt; protectedThis(this);
+    ASSERT(m_multipartInputStream);
+    ASSERT(!m_inputStream);
+    soup_multipart_input_stream_next_part_async(m_multipartInputStream.get(), G_PRIORITY_DEFAULT, m_cancellable.get(),
+        reinterpret_cast&lt;GAsyncReadyCallback&gt;(requestNextPartCallback), protectedThis.leakRef());
+}
+
+void NetworkDataTask::didRequestNextPart(GRefPtr&lt;GInputStream&gt;&amp;&amp; inputStream)
+{
+    ASSERT(!m_inputStream);
+    m_inputStream = WTFMove(inputStream);
+    m_response = ResourceResponse();
+    m_response.setURL(m_firstRequest.url());
+    m_response.updateFromSoupMessageHeaders(soup_multipart_input_stream_get_headers(m_multipartInputStream.get()));
+    didReceiveResponse();
+}
+
+void NetworkDataTask::didFinishRequestNextPart()
+{
+    ASSERT(!m_inputStream);
+    ASSERT(m_multipartInputStream);
+    g_input_stream_close(G_INPUT_STREAM(m_multipartInputStream.get()), nullptr, nullptr);
+    clearRequest();
+    m_client-&gt;didCompleteWithError({ });
+}
+
+void NetworkDataTask::gotHeadersCallback(SoupMessage* soupMessage, NetworkDataTask* task)
+{
+    if (task-&gt;state() == State::Canceling || task-&gt;state() == State::Completed || !task-&gt;m_client) {
+        task-&gt;clearRequest();
+        return;
+    }
+    ASSERT(task-&gt;m_soupMessage.get() == soupMessage);
+    task-&gt;didGetHeaders();
+}
+
+void NetworkDataTask::didGetHeaders()
+{
+    // We are a bit more conservative with the persistent credential storage than the session store,
+    // since we are waiting until we know that this authentication succeeded before actually storing.
+    // This is because we want to avoid hitting the disk twice (once to add and once to remove) for
+    // incorrect credentials or polluting the keychain with invalid credentials.
+    if (!isAuthenticationFailureStatusCode(m_soupMessage-&gt;status_code) &amp;&amp; m_soupMessage-&gt;status_code &lt; 500) {
+        m_session-&gt;networkStorageSession().saveCredentialToPersistentStorage(m_protectionSpaceForPersistentStorage, m_credentialForPersistentStorage);
+        m_protectionSpaceForPersistentStorage = ProtectionSpace();
+        m_credentialForPersistentStorage = Credential();
+    }
+}
+
+void NetworkDataTask::wroteBodyDataCallback(SoupMessage* soupMessage, SoupBuffer* buffer, NetworkDataTask* task)
+{
+    if (task-&gt;state() == State::Canceling || task-&gt;state() == State::Completed || !task-&gt;m_client) {
+        task-&gt;clearRequest();
+        return;
+    }
+    ASSERT(task-&gt;m_soupMessage.get() == soupMessage);
+    task-&gt;didWriteBodyData(buffer-&gt;length);
+}
+
+void NetworkDataTask::didWriteBodyData(uint64_t bytesSent)
+{
+    RefPtr&lt;NetworkDataTask&gt; protectedThis(this);
+    m_bodyDataTotalBytesSent += bytesSent;
+    m_client-&gt;didSendData(m_bodyDataTotalBytesSent, m_soupMessage-&gt;request_body-&gt;length);
+}
+
+void NetworkDataTask::download()
+{
+    ASSERT(isDownload());
+    ASSERT(m_pendingDownloadLocation);
+    ASSERT(!m_response.isNull());
+
+    if (m_response.httpStatusCode() &gt;= 400) {
+        didFailDownload(platformDownloadNetworkError(m_response.httpStatusCode(), m_response.url(), m_response.httpStatusText()));
+        return;
+    }
+
+    m_downloadDestinationFile = adoptGRef(g_file_new_for_uri(m_pendingDownloadLocation.utf8().data()));
+    GRefPtr&lt;GFileOutputStream&gt; outputStream;
+    GUniqueOutPtr&lt;GError&gt; error;
+    if (m_allowOverwriteDownload)
+        outputStream = adoptGRef(g_file_replace(m_downloadDestinationFile.get(), nullptr, FALSE, G_FILE_CREATE_NONE, nullptr, &amp;error.outPtr()));
+    else
+        outputStream = adoptGRef(g_file_create(m_downloadDestinationFile.get(), G_FILE_CREATE_NONE, nullptr, &amp;error.outPtr()));
+    if (!outputStream) {
+        didFailDownload(platformDownloadDestinationError(m_response, error-&gt;message));
+        return;
+    }
+
+    String intermediateURI = m_pendingDownloadLocation + &quot;.wkdownload&quot;;
+    m_downloadIntermediateFile = adoptGRef(g_file_new_for_uri(intermediateURI.utf8().data()));
+    outputStream = adoptGRef(g_file_replace(m_downloadIntermediateFile.get(), 0, TRUE, G_FILE_CREATE_NONE, 0, &amp;error.outPtr()));
+    if (!outputStream) {
+        didFailDownload(platformDownloadDestinationError(m_response, error-&gt;message));
+        return;
+    }
+    m_downloadOutputStream = adoptGRef(G_OUTPUT_STREAM(outputStream.leakRef()));
+
+    auto&amp; downloadManager = NetworkProcess::singleton().downloadManager();
+    auto download = std::make_unique&lt;Download&gt;(downloadManager, m_pendingDownloadID, this, m_session-&gt;sessionID(), suggestedFilename());
+    auto* downloadPtr = download.get();
+    downloadManager.dataTaskBecameDownloadTask(m_pendingDownloadID, WTFMove(download));
+    downloadPtr-&gt;didCreateDestination(m_pendingDownloadLocation);
+
+    ASSERT(m_client);
+    m_client-&gt;didBecomeDownload();
+
+    read();
+}
+
+void NetworkDataTask::writeDownloadCallback(GOutputStream* outputStream, GAsyncResult* result, NetworkDataTask* task)
+{
+    RefPtr&lt;NetworkDataTask&gt; protectedThis = adoptRef(task);
+    if (task-&gt;state() == State::Canceling || task-&gt;state() == State::Completed || !task-&gt;isDownload()) {
+        task-&gt;clearRequest();
+        return;
+    }
+    ASSERT(outputStream == task-&gt;m_downloadOutputStream.get());
+
+    GUniqueOutPtr&lt;GError&gt; error;
+    gsize bytesWritten;
+#if GLIB_CHECK_VERSION(2, 44, 0)
+    g_output_stream_write_all_finish(outputStream, result, &amp;bytesWritten, &amp;error.outPtr());
+#else
+    gssize writeTaskResult = g_task_propagate_int(G_TASK(result), &amp;error.outPtr());
+    if (writeTaskResult != -1)
+        bytesWritten = writeTaskResult;
+#endif
+    if (error)
+        task-&gt;didFailDownload(platformDownloadDestinationError(task-&gt;m_response, error-&gt;message));
+    else
+        task-&gt;didWriteDownload(bytesWritten);
+}
+
+void NetworkDataTask::writeDownload()
+{
+    RefPtr&lt;NetworkDataTask&gt; protectedThis(this);
+#if GLIB_CHECK_VERSION(2, 44, 0)
+    g_output_stream_write_all_async(m_downloadOutputStream.get(), m_readBuffer.data(), m_readBuffer.size(), G_PRIORITY_DEFAULT, m_cancellable.get(),
+        reinterpret_cast&lt;GAsyncReadyCallback&gt;(writeDownloadCallback), protectedThis.leakRef());
+#else
+    GRefPtr&lt;GTask&gt; writeTask = adoptGRef(g_task_new(m_downloadOutputStream.get(), m_cancellable.get(),
+        reinterpret_cast&lt;GAsyncReadyCallback&gt;(writeDownloadCallback), protectedThis.leakRef()));
+    g_task_set_task_data(writeTask.get(), this, nullptr);
+    g_task_run_in_thread(writeTask.get(), [](GTask* writeTask, gpointer source, gpointer userData, GCancellable* cancellable) {
+        auto* task = static_cast&lt;NetworkDataTask*&gt;(userData);
+        GOutputStream* outputStream = G_OUTPUT_STREAM(source);
+        RELEASE_ASSERT(task-&gt;m_downloadOutputStream.get() == outputStream);
+        RELEASE_ASSERT(task-&gt;m_cancellable.get() == cancellable);
+        GError* error = nullptr;
+        if (g_cancellable_set_error_if_cancelled(cancellable, &amp;error)) {
+            g_task_return_error(writeTask, error);
+            return;
+        }
+
+        gsize bytesWritten;
+        if (g_output_stream_write_all(outputStream, task-&gt;m_readBuffer.data(), task-&gt;m_readBuffer.size(), &amp;bytesWritten, cancellable, &amp;error))
+            g_task_return_int(writeTask, bytesWritten);
+        else
+            g_task_return_error(writeTask, error);
+    });
+#endif
+}
+
+void NetworkDataTask::didWriteDownload(gsize bytesWritten)
+{
+    ASSERT(bytesWritten == m_readBuffer.size());
+    auto* download = NetworkProcess::singleton().downloadManager().download(m_pendingDownloadID);
+    ASSERT(download);
+    download-&gt;didReceiveData(bytesWritten);
+    read();
+}
+
+void NetworkDataTask::didFinishDownload()
+{
+    ASSERT(!m_response.isNull());
+    ASSERT(m_downloadOutputStream);
+    g_output_stream_close(m_downloadOutputStream.get(), nullptr, nullptr);
+    m_downloadOutputStream = nullptr;
+
+    ASSERT(m_downloadDestinationFile);
+    ASSERT(m_downloadIntermediateFile);
+    GUniqueOutPtr&lt;GError&gt; error;
+    if (!g_file_move(m_downloadIntermediateFile.get(), m_downloadDestinationFile.get(), G_FILE_COPY_OVERWRITE, m_cancellable.get(), nullptr, nullptr, &amp;error.outPtr())) {
+        didFailDownload(platformDownloadDestinationError(m_response, error-&gt;message));
+        return;
+    }
+
+    GRefPtr&lt;GFileInfo&gt; info = adoptGRef(g_file_info_new());
+    CString uri = m_response.url().string().utf8();
+    g_file_info_set_attribute_string(info.get(), &quot;metadata::download-uri&quot;, uri.data());
+    g_file_info_set_attribute_string(info.get(), &quot;xattr::xdg.origin.url&quot;, uri.data());
+    g_file_set_attributes_async(m_downloadDestinationFile.get(), info.get(), G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT, nullptr, nullptr, nullptr);
+
+    clearRequest();
+    auto* download = NetworkProcess::singleton().downloadManager().download(m_pendingDownloadID);
+    ASSERT(download);
+    download-&gt;didFinish();
+}
+
+void NetworkDataTask::didFailDownload(const ResourceError&amp; error)
+{
+    clearRequest();
+    cleanDownloadFiles();
+    if (m_client)
+        m_client-&gt;didCompleteWithError(error);
+    else {
+        auto* download = NetworkProcess::singleton().downloadManager().download(m_pendingDownloadID);
+        ASSERT(download);
+        download-&gt;didFail(error, IPC::DataReference());
+    }
+}
+
+void NetworkDataTask::cleanDownloadFiles()
+{
+    if (m_downloadDestinationFile) {
+        g_file_delete(m_downloadDestinationFile.get(), nullptr, nullptr);
+        m_downloadDestinationFile = nullptr;
+    }
+    if (m_downloadIntermediateFile) {
+        g_file_delete(m_downloadIntermediateFile.get(), nullptr, nullptr);
+        m_downloadIntermediateFile = nullptr;
+    }
+}
+
+void NetworkDataTask::didFail(const ResourceError&amp; error)
+{
+    if (isDownload()) {
+        didFailDownload(platformDownloadNetworkError(error.errorCode(), error.failingURL(), error.localizedDescription()));
+        return;
+    }
+
+    clearRequest();
+    ASSERT(m_client);
+    m_client-&gt;didCompleteWithError(error);
+}
+
+#if ENABLE(WEB_TIMING)
+void NetworkDataTask::networkEventCallback(SoupMessage* soupMessage, GSocketClientEvent event, GIOStream*, NetworkDataTask* task)
+{
+    if (task-&gt;state() == State::Canceling || task-&gt;state() == State::Completed || !task-&gt;m_client)
+        return;
+
+    ASSERT(task-&gt;m_soupMessage.get() == soupMessage);
+    task-&gt;networkEvent(event);
+}
+
+void NetworkDataTask::networkEvent(GSocketClientEvent event)
+{
+    double deltaTime = monotonicallyIncreasingTimeMS() - m_startTime;
+    auto&amp; loadTiming = m_response.networkLoadTiming();
+    switch (event) {
+    case G_SOCKET_CLIENT_RESOLVING:
+        loadTiming.domainLookupStart = deltaTime;
+        break;
+    case G_SOCKET_CLIENT_RESOLVED:
+        loadTiming.domainLookupEnd = deltaTime;
+        break;
+    case G_SOCKET_CLIENT_CONNECTING:
+        loadTiming.connectStart = deltaTime;
+        break;
+    case G_SOCKET_CLIENT_CONNECTED:
+        // Web Timing considers that connection time involves dns, proxy &amp; TLS negotiation...
+        // so we better pick G_SOCKET_CLIENT_COMPLETE for connectEnd
+        break;
+    case G_SOCKET_CLIENT_PROXY_NEGOTIATING:
+        break;
+    case G_SOCKET_CLIENT_PROXY_NEGOTIATED:
+        break;
+    case G_SOCKET_CLIENT_TLS_HANDSHAKING:
+        loadTiming.secureConnectionStart = deltaTime;
+        break;
+    case G_SOCKET_CLIENT_TLS_HANDSHAKED:
+        break;
+    case G_SOCKET_CLIENT_COMPLETE:
+        loadTiming.connectEnd = deltaTime;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        break;
+    }
+}
+
+#if SOUP_CHECK_VERSION(2, 49, 91)
+void NetworkDataTask::startingCallback(SoupMessage* soupMessage, NetworkDataTask* task)
+{
+    if (task-&gt;state() == State::Canceling || task-&gt;state() == State::Completed || !task-&gt;m_client)
+        return;
+
+    ASSERT(task-&gt;m_soupMessage.get() == soupMessage);
+    task-&gt;didStartRequest();
+}
+#else
+void NetworkDataTask::requestStartedCallback(SoupSession* session, SoupMessage* soupMessage, SoupSocket*, NetworkDataTask* task)
+{
+    ASSERT(session == task-&gt;m_session-&gt;soupSession());
+    if (soupMessage != task-&gt;m_soupMessage.get())
+        return;
+
+    if (task-&gt;state() == State::Canceling || task-&gt;state() == State::Completed || !task-&gt;m_client)
+        return;
+
+    task-&gt;didStartRequest();
+}
+#endif
+
+void NetworkDataTask::didStartRequest()
+{
+    m_response.networkLoadTiming().requestStart = monotonicallyIncreasingTimeMS() - m_startTime;
+}
+
+void NetworkDataTask::restartedCallback(SoupMessage* soupMessage, NetworkDataTask* task)
+{
+    // Called each time the message is going to be sent again except the first time.
+    // This happens when libsoup handles HTTP authentication.
+    if (task-&gt;state() == State::Canceling || task-&gt;state() == State::Completed || !task-&gt;m_client)
+        return;
+
+    ASSERT(task-&gt;m_soupMessage.get() == soupMessage);
+    task-&gt;didRestart();
+}
+
+void NetworkDataTask::didRestart()
+{
+    m_startTime = monotonicallyIncreasingTimeMS();
+}
+#endif // ENABLE(WEB_TIMING)
+
+} // namespace WebKit
+
</ins></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesssoupNetworkSessionSoupcppfromrev207585trunkSourceWebKit2NetworkProcesssoupRemoteNetworkingContextSoupcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebKit2/NetworkProcess/soup/NetworkSessionSoup.cpp (from rev 207585, trunk/Source/WebKit2/NetworkProcess/soup/RemoteNetworkingContextSoup.cpp) (0 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/soup/NetworkSessionSoup.cpp                                (rev 0)
+++ trunk/Source/WebKit2/NetworkProcess/soup/NetworkSessionSoup.cpp        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -0,0 +1,80 @@
</span><ins>+/*
+ * Copyright (C) 2016 Igalia S.L.
+ *
+ * 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;NetworkSession.h&quot;
+
+#include &lt;WebCore/NetworkStorageSession.h&gt;
+#include &lt;WebCore/SoupNetworkSession.h&gt;
+#include &lt;wtf/MainThread.h&gt;
+
+using namespace WebCore;
+
+namespace WebKit {
+
+Ref&lt;NetworkSession&gt; NetworkSession::create(Type type, SessionID sessionID, CustomProtocolManager*)
+{
+    return adoptRef(*new NetworkSession(type, sessionID, nullptr));
+}
+
+NetworkSession&amp; NetworkSession::defaultSession()
+{
+    ASSERT(isMainThread());
+    static NetworkSession* session = &amp;NetworkSession::create(NetworkSession::Type::Normal, SessionID::defaultSessionID(), nullptr).leakRef();
+    return *session;
+}
+
+NetworkStorageSession&amp; NetworkSession::networkStorageSession() const
+{
+    auto* storageSession = NetworkStorageSession::storageSession(m_sessionID);
+    RELEASE_ASSERT(storageSession);
+    return *storageSession;
+}
+
+NetworkSession::NetworkSession(Type type, SessionID sessionID, CustomProtocolManager*)
+    : m_sessionID(sessionID)
+{
+}
+
+NetworkSession::~NetworkSession()
+{
+}
+
+SoupSession* NetworkSession::soupSession() const
+{
+    return networkStorageSession().soupNetworkSession().soupSession();
+}
+
+void NetworkSession::invalidateAndCancel()
+{
+    for (auto* task : m_dataTaskSet)
+        task-&gt;invalidateAndCancel();
+}
+
+void NetworkSession::clearCredentials()
+{
+}
+
+} // namespace WebKit
</ins></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesssoupRemoteNetworkingContextSoupcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/soup/RemoteNetworkingContextSoup.cpp (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/soup/RemoteNetworkingContextSoup.cpp        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/NetworkProcess/soup/RemoteNetworkingContextSoup.cpp        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -28,6 +28,8 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;RemoteNetworkingContext.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;NetworkSession.h&quot;
+#include &quot;SessionTracker.h&quot;
</ins><span class="cx"> #include &lt;WebCore/NetworkStorageSession.h&gt;
</span><span class="cx"> #include &lt;WebCore/NotImplemented.h&gt;
</span><span class="cx"> #include &lt;WebCore/ResourceHandle.h&gt;
</span><span class="lines">@@ -45,13 +47,21 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RemoteNetworkingContext::ensurePrivateBrowsingSession(SessionID)
</del><ins>+void RemoteNetworkingContext::ensurePrivateBrowsingSession(SessionID sessionID)
</ins><span class="cx"> {
</span><del>-    notImplemented();
</del><ins>+    ASSERT(sessionID.isEphemeral());
+
+    if (NetworkStorageSession::storageSession(sessionID))
+        return;
+
+    NetworkStorageSession::ensurePrivateBrowsingSession(sessionID, String::number(sessionID.sessionID()));
+    SessionTracker::setSession(sessionID, NetworkSession::create(NetworkSession::Type::Ephemeral, sessionID, nullptr));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> NetworkStorageSession&amp; RemoteNetworkingContext::storageSession() const
</span><span class="cx"> {
</span><ins>+    if (auto session = NetworkStorageSession::storageSession(m_sessionID))
+        return *session;
</ins><span class="cx">     return NetworkStorageSession::defaultStorageSession();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2PlatformEflcmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/PlatformEfl.cmake (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/PlatformEfl.cmake        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/PlatformEfl.cmake        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -14,7 +14,9 @@
</span><span class="cx"> 
</span><span class="cx">     NetworkProcess/efl/NetworkProcessMainEfl.cpp
</span><span class="cx"> 
</span><ins>+    NetworkProcess/soup/NetworkDataTaskSoup.cpp
</ins><span class="cx">     NetworkProcess/soup/NetworkProcessSoup.cpp
</span><ins>+    NetworkProcess/soup/NetworkSessionSoup.cpp
</ins><span class="cx">     NetworkProcess/soup/RemoteNetworkingContextSoup.cpp
</span><span class="cx"> 
</span><span class="cx">     Platform/IPC/unix/AttachmentUnix.cpp
</span></span></pre></div>
<a id="trunkSourceWebKit2PlatformGTKcmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/PlatformGTK.cmake (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/PlatformGTK.cmake        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/PlatformGTK.cmake        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -39,8 +39,10 @@
</span><span class="cx">     NetworkProcess/cache/NetworkCacheDataSoup.cpp
</span><span class="cx">     NetworkProcess/cache/NetworkCacheIOChannelSoup.cpp
</span><span class="cx"> 
</span><ins>+    NetworkProcess/soup/NetworkDataTaskSoup.cpp
</ins><span class="cx">     NetworkProcess/soup/NetworkProcessMainSoup.cpp
</span><span class="cx">     NetworkProcess/soup/NetworkProcessSoup.cpp
</span><ins>+    NetworkProcess/soup/NetworkSessionSoup.cpp
</ins><span class="cx">     NetworkProcess/soup/RemoteNetworkingContextSoup.cpp
</span><span class="cx"> 
</span><span class="cx">     Platform/IPC/glib/GSocketMonitor.cpp
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedAuthenticationAuthenticationManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/Authentication/AuthenticationManager.h (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/Authentication/AuthenticationManager.h        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/Shared/Authentication/AuthenticationManager.h        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -28,10 +28,10 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;MessageReceiver.h&quot;
</span><span class="cx"> #include &quot;NetworkProcessSupplement.h&quot;
</span><del>-#include &quot;NetworkSession.h&quot;
</del><span class="cx"> #include &quot;WebProcessSupplement.h&quot;
</span><span class="cx"> #include &lt;WebCore/AuthenticationChallenge.h&gt;
</span><span class="cx"> #include &lt;wtf/Forward.h&gt;
</span><ins>+#include &lt;wtf/Function.h&gt;
</ins><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -48,6 +48,14 @@
</span><span class="cx"> class PendingDownload;
</span><span class="cx"> class WebFrame;
</span><span class="cx"> 
</span><ins>+enum class AuthenticationChallengeDisposition {
+    UseCredential,
+    PerformDefaultHandling,
+    Cancel,
+    RejectProtectionSpace
+};
+typedef Function&lt;void(AuthenticationChallengeDisposition, const WebCore::Credential&amp;)&gt; ChallengeCompletionHandler;
+
</ins><span class="cx"> class AuthenticationManager : public WebProcessSupplement, public NetworkProcessSupplement, public IPC::MessageReceiver {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(AuthenticationManager);
</span><span class="cx"> public:
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportsoupWebFrameNetworkingContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;WebFrameNetworkingContext.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;NetworkSession.h&quot;
</ins><span class="cx"> #include &quot;SessionTracker.h&quot;
</span><span class="cx"> #include &quot;WebFrame.h&quot;
</span><span class="cx"> #include &quot;WebPage.h&quot;
</span><span class="lines">@@ -43,11 +44,13 @@
</span><span class="cx"> void WebFrameNetworkingContext::ensurePrivateBrowsingSession(SessionID sessionID)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><ins>+    ASSERT(sessionID.isEphemeral());
</ins><span class="cx"> 
</span><span class="cx">     if (NetworkStorageSession::storageSession(sessionID))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     NetworkStorageSession::ensurePrivateBrowsingSession(sessionID, String::number(sessionID.sessionID()));
</span><ins>+    SessionTracker::setSession(sessionID, NetworkSession::create(NetworkSession::Type::Ephemeral, sessionID, nullptr));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebFrameNetworkingContext::setCookieAcceptPolicyForAllContexts(HTTPCookieAcceptPolicy policy)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebProcesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebProcess.cpp (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebProcess.cpp        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.cpp        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> #include &quot;Logging.h&quot;
</span><span class="cx"> #include &quot;NetworkConnectionToWebProcessMessages.h&quot;
</span><span class="cx"> #include &quot;NetworkProcessConnection.h&quot;
</span><ins>+#include &quot;NetworkSession.h&quot;
</ins><span class="cx"> #include &quot;PluginProcessConnectionManager.h&quot;
</span><span class="cx"> #include &quot;SessionTracker.h&quot;
</span><span class="cx"> #include &quot;StatisticsData.h&quot;
</span></span></pre></div>
<a id="trunkSourceWebKit2configh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/config.h (207585 => 207586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/config.h        2016-10-20 06:05:26 UTC (rev 207585)
+++ trunk/Source/WebKit2/config.h        2016-10-20 06:42:24 UTC (rev 207586)
</span><span class="lines">@@ -75,7 +75,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-#if (PLATFORM(MAC) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101200) || (PLATFORM(IOS) &amp;&amp; __IPHONE_OS_VERSION_MIN_REQUIRED &gt;= 100000)
</del><ins>+#if (PLATFORM(MAC) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101200) || (PLATFORM(IOS) &amp;&amp; __IPHONE_OS_VERSION_MIN_REQUIRED &gt;= 100000) || USE(SOUP)
</ins><span class="cx"> #ifndef USE_NETWORK_SESSION
</span><span class="cx"> #define USE_NETWORK_SESSION 1
</span><span class="cx"> #endif
</span></span></pre>
</div>
</div>

</body>
</html>