<!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 <cgarcia@igalia.com>
+
+ [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 <achristensen@webkit.org>
</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 "DownloadManager.h"
</span><span class="cx"> #include "DownloadProxyMessages.h"
</span><span class="cx"> #include "Logging.h"
</span><ins>+#include "NetworkDataTask.h"
</ins><span class="cx"> #include "SandboxExtension.h"
</span><span class="cx"> #include "WebCoreArgumentCoders.h"
</span><span class="cx"> #include <WebCore/NotImplemented.h>
</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) && PLATFORM(COCOA)
-Download::Download(DownloadManager& downloadManager, DownloadID downloadID, NSURLSessionDownloadTask* download, const WebCore::SessionID& sessionID, const String& suggestedName)
</del><ins>+#if USE(NETWORK_SESSION)
+Download::Download(DownloadManager& downloadManager, DownloadID downloadID, PlatformDownloadTaskRef download, const WebCore::SessionID& sessionID, const String& 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 <WebCore/SessionID.h>
</span><span class="cx"> #include <memory>
</span><span class="cx"> #include <wtf/Noncopyable.h>
</span><del>-
-#if PLATFORM(COCOA)
</del><span class="cx"> #include <wtf/RetainPtr.h>
</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 <CFNetwork/CFURLDownloadPriv.h>
</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) && PLATFORM(COCOA)
- Download(DownloadManager&, DownloadID, NSURLSessionDownloadTask*, const WebCore::SessionID& sessionID, const String& suggestedFilename = { });
</del><ins>+#if USE(NETWORK_SESSION)
+ Download(DownloadManager&, DownloadID, PlatformDownloadTaskRef, const WebCore::SessionID& sessionID, const String& suggestedFilename = { });
</ins><span class="cx"> #endif
</span><span class="cx"> Download(DownloadManager&, DownloadID, const WebCore::ResourceRequest&, const String& suggestedFilename = { });
</span><span class="cx">
</span><span class="lines">@@ -130,15 +137,19 @@
</span><span class="cx">
</span><span class="cx"> RefPtr<SandboxExtension> 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<NSURLSessionDownloadTask> m_download;
</span><ins>+#elif USE(SOUP)
+ RefPtr<NetworkDataTask> 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<NSURLDownload> m_nsURLDownload;
</span><span class="cx"> RetainPtr<WKDownloadAsDelegate> 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<CFURLDownloadRef> 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 "Download.h"
</span><span class="cx">
</span><span class="cx"> #include "DataReference.h"
</span><del>-#include "DownloadSoupErrors.h"
</del><ins>+#include "NetworkDataTask.h"
</ins><span class="cx"> #include <WebCore/NotImplemented.h>
</span><del>-#include <WebCore/ResourceHandleInternal.h>
-#include <gio/gio.h>
-#include <wtf/RunLoop.h>
-#include <wtf/glib/GRefPtr.h>
-#include <wtf/glib/GUniquePtr.h>
-#include <wtf/text/CString.h>
</del><span class="cx">
</span><del>-#if PLATFORM(GTK)
-#include <glib/gi18n-lib.h>
-#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& download)
- : m_download(download)
- , m_handleResponseLater(RunLoop::main(), this, &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& error)
- {
- deleteFilesIfNeeded();
- m_download.didFail(error, IPC::DataReference());
- }
-
- void didReceiveResponse(ResourceHandle*, ResourceResponse&& response) override
- {
- m_response = WTFMove(response);
- m_download.didReceiveResponse(m_response);
-
- if (m_response.httpStatusCode() >= 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<char> buffer(g_strdup_printf(_("Cannot determine destination URI for download with suggested filename %s"), suggestedFilename.utf8().data()));
- String errorMessage = String::fromUTF8(buffer.get());
-#else
- String errorMessage = makeString("Cannot determine destination URI for download with suggested filename ", suggestedFilename);
-#endif
- downloadFailed(platformDownloadDestinationError(m_response, errorMessage));
- return;
- }
-
- m_destinationFile = adoptGRef(g_file_new_for_uri(destinationURI.utf8().data()));
- GRefPtr<GFileOutputStream> outputStream;
- GUniqueOutPtr<GError> error;
- if (m_allowOverwrite)
- outputStream = adoptGRef(g_file_replace(m_destinationFile.get(), nullptr, FALSE, G_FILE_CREATE_NONE, nullptr, &error.outPtr()));
- else
- outputStream = adoptGRef(g_file_create(m_destinationFile.get(), G_FILE_CREATE_NONE, nullptr, &error.outPtr()));
- if (!outputStream) {
- m_destinationFile.clear();
- downloadFailed(platformDownloadDestinationError(m_response, error->message));
- return;
- }
-
- String intermediateURI = destinationURI + ".wkdownload";
- 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, &error.outPtr()));
- if (!m_outputStream) {
- downloadFailed(platformDownloadDestinationError(m_response, error->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<GError> error;
- g_output_stream_write_all(G_OUTPUT_STREAM(m_outputStream.get()), data, length, &bytesWritten, 0, &error.outPtr());
- if (error) {
- downloadFailed(platformDownloadDestinationError(m_response, error->message));
- return;
- }
- m_download.didReceiveData(bytesWritten);
- }
-
- void didFinishLoading(ResourceHandle*, double) override
- {
- m_outputStream = nullptr;
-
- ASSERT(m_destinationFile);
- ASSERT(m_intermediateFile);
- GUniqueOutPtr<GError> error;
- if (!g_file_move(m_intermediateFile.get(), m_destinationFile.get(), G_FILE_COPY_OVERWRITE, nullptr, nullptr, nullptr, &error.outPtr())) {
- downloadFailed(platformDownloadDestinationError(m_response, error->message));
- return;
- }
-
- GRefPtr<GFileInfo> info = adoptGRef(g_file_info_new());
- CString uri = m_response.url().string().utf8();
- g_file_info_set_attribute_string(info.get(), "metadata::download-uri", uri.data());
- g_file_info_set_attribute_string(info.get(), "xattr::xdg.origin.url", 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& error) override
- {
- downloadFailed(platformDownloadNetworkError(error.errorCode(), error.failingURL(), error.localizedDescription()));
- }
-
- void cancel(ResourceHandle* handle)
- {
- handle->cancel();
- deleteFilesIfNeeded();
- m_download.didCancel(IPC::DataReference());
- }
-
- void handleResponse()
- {
- didReceiveResponse(nullptr, WTFMove(m_delayedResponse));
- }
-
- void handleResponseLater(const ResourceResponse& 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& m_download;
- GRefPtr<GFileOutputStream> m_outputStream;
- ResourceResponse m_response;
- GRefPtr<GFile> m_destinationFile;
- GRefPtr<GFile> m_intermediateFile;
- ResourceResponse m_delayedResponse;
- RunLoop::Timer<DownloadClient> m_handleResponseLater;
- bool m_allowOverwrite;
-};
-
-void Download::startNetworkLoad()
-{
- ASSERT(!m_downloadClient);
- ASSERT(!m_resourceHandle);
- m_downloadClient = std::make_unique<DownloadClient>(*this);
- m_resourceHandle = ResourceHandle::create(0, m_request, m_downloadClient.get(), false, true);
- didStart();
-}
-
-void Download::startNetworkLoadWithHandle(ResourceHandle* resourceHandle, const ResourceResponse& response)
-{
- ASSERT(!m_downloadClient);
- ASSERT(!m_resourceHandle);
- m_downloadClient = std::make_unique<DownloadClient>(*this);
- m_resourceHandle = resourceHandle->releaseForDownload(m_downloadClient.get());
- didStart();
- static_cast<DownloadClient*>(m_downloadClient.get())->handleResponseLater(response);
-}
-
</del><span class="cx"> void Download::resume(const IPC::DataReference&, const String&, const SandboxExtension::Handle&)
</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<ResourceHandle> resourceHandle = m_resourceHandle.release();
- static_cast<DownloadClient*>(m_downloadClient.get())->cancel(resourceHandle.get());
</del><ins>+ m_download->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 "DownloadID.h"
</ins><span class="cx"> #include "SandboxExtension.h"
</span><span class="cx"> #include <WebCore/Credential.h>
</span><span class="cx"> #include <WebCore/FrameLoaderTypes.h>
</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 <WebCore/ProtectionSpace.h>
+#include <WebCore/ResourceResponse.h>
+#include <wtf/RunLoop.h>
+#include <wtf/glib/GRefPtr.h>
+#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<void(const WebCore::ResourceRequest&)> RedirectCompletionHandler;
</span><span class="cx"> typedef Function<void(AuthenticationChallengeDisposition, const WebCore::Credential&)> ChallengeCompletionHandler;
</span><span class="cx"> typedef Function<void(WebCore::PolicyAction)> 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&, ChallengeCompletionHandler&&);
</span><span class="cx"> void didCompleteWithError(const WebCore::ResourceError&);
</span><span class="lines">@@ -112,12 +116,15 @@
</span><span class="cx"> void didReceiveResponse(WebCore::ResourceResponse&&, ResponseCompletionHandler&&);
</span><span class="cx"> void didReceiveData(Ref<WebCore::SharedBuffer>&&);
</span><span class="cx"> void didBecomeDownload();
</span><del>-
</del><ins>+
+ void willPerformHTTPRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, RedirectCompletionHandler&&);
+ void transferSandboxExtensionToDownload(Download&);
+#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 = &pendingDownload;
</span><span class="cx"> }
</span><span class="cx"> void setPendingDownloadLocation(const String& filename, const SandboxExtension::Handle&, bool allowOverwrite);
</span><del>- const String& pendingDownloadLocation() { return m_pendingDownloadLocation; }
</del><ins>+ const String& pendingDownloadLocation() const { return m_pendingDownloadLocation; }
+ bool isDownload() const { return !!m_pendingDownloadID.downloadID(); }
</ins><span class="cx">
</span><span class="cx"> const WebCore::ResourceRequest& firstRequest() const { return m_firstRequest; }
</span><span class="cx"> String suggestedFilename();
</span><span class="cx"> void setSuggestedFilename(const String&);
</span><del>- void willPerformHTTPRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, RedirectCompletionHandler&&);
- void transferSandboxExtensionToDownload(Download&);
</del><span class="cx"> bool allowsSpecificHTTPSCertificateForHost(const WebCore::AuthenticationChallenge&);
</span><span class="cx">
</span><span class="cx"> private:
</span><span class="lines">@@ -143,6 +149,61 @@
</span><span class="cx"> NetworkDataTask(NetworkSession&, NetworkDataTaskClient&, const WebCore::ResourceRequest&, WebCore::StoredCredentials, WebCore::ContentSniffingPolicy, bool shouldClearReferrerOnHTTPSToHTTPRedirect);
</span><span class="cx">
</span><span class="cx"> bool tryPasswordBasedAuthentication(const WebCore::AuthenticationChallenge&, const ChallengeCompletionHandler&);
</span><ins>+
+#if USE(SOUP)
+ void timeoutFired();
+ void startTimeout();
+ void stopTimeout();
+ void invalidateAndCancel();
+ void createRequest(const WebCore::ResourceRequest&);
+ void clearRequest();
+ static void sendRequestCallback(SoupRequest*, GAsyncResult*, NetworkDataTask*);
+ void didSendRequest(GRefPtr<GInputStream>&&);
+ void didReceiveResponse();
+ static void tlsErrorsChangedCallback(SoupMessage*, GParamSpec*, NetworkDataTask*);
+ void tlsErrorsChanged();
+ void applyAuthenticationToRequest(WebCore::ResourceRequest&);
+ static void authenticateCallback(SoupSession*, SoupMessage*, SoupAuth*, gboolean retrying, NetworkDataTask*);
+ void authenticate(WebCore::AuthenticationChallenge&&);
+ void continueAuthenticate(WebCore::AuthenticationChallenge&&);
+ 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<GInputStream>&&);
+ 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&);
+ void didFinishDownload();
+ void cleanDownloadFiles();
+ void didFail(const WebCore::ResourceError&);
+#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<NSURLSessionDataTask> m_task;
</span><span class="cx"> #endif
</span><ins>+#if USE(SOUP)
+ State m_state { State::Suspended };
+ WebCore::ContentSniffingPolicy m_shouldContentSniff;
+ GRefPtr<SoupRequest> m_soupRequest;
+ GRefPtr<SoupMessage> m_soupMessage;
+ GRefPtr<GInputStream> m_inputStream;
+ GRefPtr<SoupMultipartInputStream> m_multipartInputStream;
+ GRefPtr<GCancellable> m_cancellable;
+ GRefPtr<GAsyncResult> m_pendingResult;
+ WebCore::ProtectionSpace m_protectionSpaceForPersistentStorage;
+ WebCore::Credential m_credentialForPersistentStorage;
+ WebCore::ResourceResponse m_response;
+ Vector<char> m_readBuffer;
+ unsigned m_redirectCount { 0 };
+ uint64_t m_bodyDataTotalBytesSent { 0 };
+ GRefPtr<GFile> m_downloadDestinationFile;
+ GRefPtr<GFile> m_downloadIntermediateFile;
+ GRefPtr<GOutputStream> m_downloadOutputStream;
+ bool m_allowOverwriteDownload { false };
+#if ENABLE(WEB_TIMING)
+ double m_startTime { 0 };
+#endif
+ RunLoop::Timer<NetworkDataTask> 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&& response, ResponseCompletionHandler&& completionHandler)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(isMainThread());
</span><del>- if (m_task && m_task->pendingDownloadID().downloadID())
</del><ins>+ if (m_task && m_task->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 "NetworkProcessPlatformStrategies.h"
</span><span class="cx"> #include "NetworkProcessProxyMessages.h"
</span><span class="cx"> #include "NetworkResourceLoader.h"
</span><ins>+#include "NetworkSession.h"
</ins><span class="cx"> #include "RemoteNetworkingContext.h"
</span><span class="cx"> #include "SessionTracker.h"
</span><span class="cx"> #include "StatisticsData.h"
</span><span class="lines">@@ -100,7 +101,7 @@
</span><span class="cx"> addSupplement<AuthenticationManager>();
</span><span class="cx"> addSupplement<WebCookieManager>();
</span><span class="cx"> addSupplement<CustomProtocolManager>();
</span><del>-#if USE(NETWORK_SESSION)
</del><ins>+#if USE(NETWORK_SESSION) && PLATFORM(COCOA)
</ins><span class="cx"> NetworkSession::setCustomProtocolManager(supplement<CustomProtocolManager>());
</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 "NetworkDataTask.h"
</span><span class="cx"> #include <WebCore/SessionID.h>
</span><span class="cx"> #include <wtf/HashMap.h>
</span><ins>+#include <wtf/HashSet.h>
</ins><span class="cx"> #include <wtf/Ref.h>
</span><span class="cx"> #include <wtf/RefCounted.h>
</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<CFDataRef>&&);
</span><span class="cx"> static void setSourceApplicationBundleIdentifier(const String&);
</span><span class="cx"> static void setSourceApplicationSecondaryIdentifier(const String&);
</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& networkStorageSession();
</del><ins>+ WebCore::NetworkStorageSession& 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<NetworkDataTask::TaskIdentifier, NetworkDataTask*> m_dataTaskMapWithCredentials;
</span><span class="cx"> HashMap<NetworkDataTask::TaskIdentifier, NetworkDataTask*> m_dataTaskMapWithoutCredentials;
</span><span class="cx"> HashMap<NetworkDataTask::TaskIdentifier, DownloadID> m_downloadMap;
</span><span class="cx">
</span><del>-#if PLATFORM(COCOA)
</del><span class="cx"> RetainPtr<NSURLSession> m_sessionWithCredentialStorage;
</span><span class="cx"> RetainPtr<WKNetworkSessionDelegate> m_sessionWithCredentialStorageDelegate;
</span><span class="cx"> RetainPtr<NSURLSession> m_sessionWithoutCredentialStorage;
</span><span class="cx"> RetainPtr<WKNetworkSessionDelegate> m_sessionWithoutCredentialStorageDelegate;
</span><ins>+#elif USE(SOUP)
+ HashSet<NetworkDataTask*> 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 "AuthenticationManager.h"
</ins><span class="cx"> #include "NetworkDataTask.h"
</span><span class="cx"> #include "SessionTracker.h"
</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 "AuthenticationManager.h"
</ins><span class="cx"> #import "Download.h"
</span><span class="cx"> #import "DownloadProxyMessages.h"
</span><span class="cx"> #import "Logging.h"
</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 "AuthenticationManager.h"
</ins><span class="cx"> #import "CustomProtocolManager.h"
</span><span class="cx"> #import "DataReference.h"
</span><span class="cx"> #import "Download.h"
</span><span class="lines">@@ -475,7 +476,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><del>-WebCore::NetworkStorageSession& NetworkSession::networkStorageSession()
</del><ins>+WebCore::NetworkStorageSession& 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 "config.h"
+#include "NetworkDataTask.h"
+
+#include "AuthenticationManager.h"
+#include "DataReference.h"
+#include "Download.h"
+#include "DownloadSoupErrors.h"
+#include "NetworkLoad.h"
+#include "NetworkProcess.h"
+#include "NetworkSession.h"
+#include "WebErrors.h"
+#include <WebCore/AuthenticationChallenge.h>
+#include <WebCore/HTTPParsers.h>
+#include <WebCore/NetworkStorageSession.h>
+#include <WebCore/SharedBuffer.h>
+#include <WebCore/SoupNetworkSession.h>
+#include <wtf/MainThread.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static const size_t gDefaultReadBufferSize = 8192;
+
+NetworkDataTask::NetworkDataTask(NetworkSession& session, NetworkDataTaskClient& client, const ResourceRequest& requestWithCredentials, StoredCredentials storedCredentials, ContentSniffingPolicy shouldContentSniff, bool shouldClearReferrerOnHTTPSToHTTPRedirect)
+ : m_failureTimer(*this, &NetworkDataTask::failureTimerFired)
+ , m_session(&session)
+ , m_client(&client)
+ , m_storedCredentials(storedCredentials)
+ , m_lastHTTPMethod(requestWithCredentials.httpMethod())
+ , m_firstRequest(requestWithCredentials)
+ , m_shouldClearReferrerOnHTTPSToHTTPRedirect(shouldClearReferrerOnHTTPSToHTTPRedirect)
+ , m_shouldContentSniff(shouldContentSniff)
+ , m_timeoutSource(RunLoop::main(), this, &NetworkDataTask::timeoutFired)
+{
+ ASSERT(isMainThread());
+
+ m_session->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() && m_password.isEmpty())
+ m_initialCredential = m_session->networkStorageSession().credentialStorage().get(request.url());
+ else
+ m_session->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->m_dataTaskSet.remove(this);
+}
+
+void NetworkDataTask::scheduleFailure(FailureType type)
+{
+ ASSERT(type != NoFailure);
+ m_scheduledFailureType = type;
+ m_failureTimer.startOneShot(0);
+}
+
+void NetworkDataTask::failureTimerFired()
+{
+ RefPtr<NetworkDataTask> protectedThis(this);
+
+ switch (m_scheduledFailureType) {
+ case BlockedFailure:
+ m_scheduledFailureType = NoFailure;
+ if (m_client)
+ m_client->wasBlocked();
+ return;
+ case InvalidURLFailure:
+ m_scheduledFailureType = NoFailure;
+ if (m_client)
+ m_client->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& suggestedName)
+{
+ m_suggestedFilename = suggestedName;
+}
+
+void NetworkDataTask::setPendingDownloadLocation(const String& filename, const SandboxExtension::Handle&, bool allowOverwrite)
+{
+ m_pendingDownloadLocation = filename;
+ m_allowOverwriteDownload = allowOverwrite;
+}
+
+bool NetworkDataTask::allowsSpecificHTTPSCertificateForHost(const AuthenticationChallenge&)
+{
+ return false;
+}
+
+void NetworkDataTask::createRequest(const ResourceRequest& request)
+{
+ GUniquePtr<SoupURI> soupURI = request.createSoupURI();
+ if (!soupURI) {
+ scheduleFailure(InvalidURLFailure);
+ return;
+ }
+
+ GRefPtr<SoupRequest> soupRequest = adoptGRef(soup_session_request_uri(m_session->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<SoupMessage> 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() && m_password.isEmpty() && 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->request_headers, "Accept"))
+ soup_message_headers_append(soupMessage->request_headers, "Accept", "*/*");
+
+ // In the case of XHR .send() and .send("") 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->method == SOUP_METHOD_POST || soupMessage->method == SOUP_METHOD_PUT) && !soupMessage->request_body->length)
+ soup_message_headers_set_content_length(soupMessage->request_headers, 0);
+
+ unsigned flags = SOUP_MESSAGE_NO_REDIRECT;
+ soup_message_set_flags(soupMessage.get(), static_cast<SoupMessageFlags>(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(), "notify::tls-errors", G_CALLBACK(tlsErrorsChangedCallback), this);
+ g_signal_connect(m_soupMessage.get(), "got-headers", G_CALLBACK(gotHeadersCallback), this);
+ g_signal_connect(m_soupMessage.get(), "wrote-body-data", G_CALLBACK(wroteBodyDataCallback), this);
+ g_signal_connect(m_session->soupSession(), "authenticate", G_CALLBACK(authenticateCallback), this);
+#if ENABLE(WEB_TIMING)
+ g_signal_connect(m_soupMessage.get(), "network-event", G_CALLBACK(networkEventCallback), this);
+ g_signal_connect(m_soupMessage.get(), "restarted", G_CALLBACK(restartedCallback), this);
+#if SOUP_CHECK_VERSION(2, 49, 91)
+ g_signal_connect(m_soupMessage.get(), "starting", G_CALLBACK(startingCallback), this);
+#else
+ g_signal_connect(m_session->soupSession(), "request-started", 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->soupSession(), m_soupMessage.get(), SOUP_STATUS_CANCELLED);
+ m_soupMessage = nullptr;
+ }
+ g_signal_handlers_disconnect_matched(m_session->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<NetworkDataTask> protectedThis(this);
+ if (m_soupRequest && !m_cancellable) {
+ m_cancellable = adoptGRef(g_cancellable_new());
+ soup_request_send_async(m_soupRequest.get(), m_cancellable.get(), reinterpret_cast<GAsyncReadyCallback>(sendRequestCallback), protectedThis.leakRef());
+ return;
+ }
+
+ if (m_pendingResult) {
+ GRefPtr<GAsyncResult> 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->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<NetworkDataTask> protectedThis(this);
+ invalidateAndCancel();
+ m_client->didCompleteWithError(ResourceError::timeoutError(m_firstRequest.url()));
+}
+
+void NetworkDataTask::startTimeout()
+{
+ if (m_firstRequest.timeoutInterval() > 0)
+ m_timeoutSource.startOneShot(m_firstRequest.timeoutInterval());
+}
+
+void NetworkDataTask::stopTimeout()
+{
+ m_timeoutSource.stop();
+}
+
+void NetworkDataTask::sendRequestCallback(SoupRequest* soupRequest, GAsyncResult* result, NetworkDataTask* task)
+{
+ RefPtr<NetworkDataTask> protectedThis = adoptRef(task);
+ if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) {
+ task->clearRequest();
+ return;
+ }
+ ASSERT(soupRequest == task->m_soupRequest.get());
+
+ if (task->state() == State::Suspended) {
+ ASSERT(!task->m_pendingResult);
+ task->m_pendingResult = result;
+ return;
+ }
+
+ GUniqueOutPtr<GError> error;
+ GRefPtr<GInputStream> inputStream = adoptGRef(soup_request_send_finish(soupRequest, result, &error.outPtr()));
+ if (error)
+ task->didFail(ResourceError::httpError(task->m_soupMessage.get(), error.get(), soupRequest));
+ else
+ task->didSendRequest(WTFMove(inputStream));
+}
+
+void NetworkDataTask::didSendRequest(GRefPtr<GInputStream>&& inputStream)
+{
+ if (m_soupMessage) {
+ if (m_shouldContentSniff == SniffContent && m_soupMessage->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->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->state() == State::Canceling || task->state() == State::Completed || !task->m_client) {
+ task->clearRequest();
+ return;
+ }
+
+ ASSERT(soupMessage == task->m_soupMessage.get());
+ task->tlsErrorsChanged();
+}
+
+void NetworkDataTask::tlsErrorsChanged()
+{
+ ASSERT(m_soupRequest);
+ SoupNetworkSession::checkTLSErrors(m_soupRequest.get(), m_soupMessage.get(), [this] (const ResourceError& error) {
+ if (error.isNull())
+ return;
+
+ RefPtr<NetworkDataTask> protectedThis(this);
+ invalidateAndCancel();
+ m_client->didCompleteWithError(error);
+ });
+}
+
+void NetworkDataTask::applyAuthenticationToRequest(ResourceRequest& 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->m_session->soupSession());
+ if (soupMessage != task->m_soupMessage.get())
+ return;
+
+ if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) {
+ task->clearRequest();
+ return;
+ }
+
+ task->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&& 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->networkStorageSession().credentialStorage().remove(challenge.protectionSpace());
+ }
+
+ if (!challenge.previousFailureCount()) {
+ auto credential = m_session->networkStorageSession().credentialStorage().get(challenge.protectionSpace());
+ if (!credential.isEmpty() && 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->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->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->networkStorageSession().getCredentialFromPersistentStorage(protectionSpace,
+ [this, protectedThis = makeRef(*this), authChallenge = WTFMove(challenge)] (Credential&& 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&& challenge)
+{
+ m_client->didReceiveChallenge(challenge, [this, protectedThis = makeRef(*this), challenge](AuthenticationChallengeDisposition disposition, const Credential& 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 && !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->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->soupSession(), m_soupMessage.get());
+ });
+}
+
+void NetworkDataTask::skipInputStreamForRedirectionCallback(GInputStream* inputStream, GAsyncResult* result, NetworkDataTask* task)
+{
+ RefPtr<NetworkDataTask> protectedThis = adoptRef(task);
+ if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) {
+ task->clearRequest();
+ return;
+ }
+ ASSERT(inputStream == task->m_inputStream.get());
+
+ GUniqueOutPtr<GError> error;
+ gssize bytesSkipped = g_input_stream_skip_finish(inputStream, result, &error.outPtr());
+ if (error)
+ task->didFail(ResourceError::genericGError(error.get(), task->m_soupRequest.get()));
+ else if (bytesSkipped > 0)
+ task->skipInputStreamForRedirection();
+ else
+ task->didFinishSkipInputStreamForRedirection();
+}
+
+void NetworkDataTask::skipInputStreamForRedirection()
+{
+ ASSERT(m_inputStream);
+ RefPtr<NetworkDataTask> protectedThis(this);
+ g_input_stream_skip_async(m_inputStream.get(), gDefaultReadBufferSize, G_PRIORITY_DEFAULT, m_cancellable.get(),
+ reinterpret_cast<GAsyncReadyCallback>(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->method == SOUP_METHOD_GET || message->method == SOUP_METHOD_HEAD)
+ return false;
+
+ switch (message->status_code) {
+ case SOUP_STATUS_SEE_OTHER:
+ return true;
+ case SOUP_STATUS_FOUND:
+ case SOUP_STATUS_MOVED_PERMANENTLY:
+ if (message->method == SOUP_METHOD_POST)
+ return true;
+ break;
+ }
+
+ if (crossOrigin && message->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++ > maxRedirects) {
+ didFail(ResourceError::transportError(m_soupRequest.get(), SOUP_STATUS_TOO_MANY_REDIRECTS, "Too many redirects"));
+ 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 && !request.url().protocolIs("https") && protocolIs(request.httpReferrer(), "https"))
+ request.clearHTTPReferrer();
+
+ bool isCrossOrigin = !protocolHostAndPortAreEqual(m_firstRequest.url(), request.url());
+ if (!equalLettersIgnoringASCIICase(request.httpMethod(), "GET")) {
+ // Change newRequest method to GET if change was made during a previous redirection or if current redirection says so.
+ if (m_soupMessage->method == SOUP_METHOD_GET || !request.url().protocolIsInHTTPFamily() || shouldRedirectAsGET(m_soupMessage.get(), isCrossOrigin)) {
+ request.setHTTPMethod("GET");
+ request.setHTTPBody(nullptr);
+ request.clearHTTPContentType();
+ }
+ }
+
+ const auto& 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() && m_storedCredentials == AllowStoredCredentials) {
+ if (m_user.isEmpty() && m_password.isEmpty()) {
+ auto credential = m_session->networkStorageSession().credentialStorage().get(request.url());
+ if (!credential.isEmpty())
+ m_initialCredential = credential;
+ }
+ }
+
+ clearRequest();
+
+ auto response = ResourceResponse(m_response);
+ m_client->willPerformHTTPRedirection(WTFMove(response), WTFMove(request), [this, protectedThis = makeRef(*this), isCrossOrigin](const ResourceRequest& 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 && m_state != State::Suspended) {
+ m_state = State::Suspended;
+ resume();
+ }
+ });
+}
+
+void NetworkDataTask::readCallback(GInputStream* inputStream, GAsyncResult* result, NetworkDataTask* task)
+{
+ RefPtr<NetworkDataTask> protectedThis = adoptRef(task);
+ if (task->state() == State::Canceling || task->state() == State::Completed || (!task->m_client && !task->isDownload())) {
+ task->clearRequest();
+ return;
+ }
+ ASSERT(inputStream == task->m_inputStream.get());
+
+ if (task->state() == State::Suspended) {
+ ASSERT(!task->m_pendingResult);
+ task->m_pendingResult = result;
+ return;
+ }
+
+ GUniqueOutPtr<GError> error;
+ gssize bytesRead = g_input_stream_read_finish(inputStream, result, &error.outPtr());
+ if (error)
+ task->didFail(ResourceError::genericGError(error.get(), task->m_soupRequest.get()));
+ else if (bytesRead > 0)
+ task->didRead(bytesRead);
+ else
+ task->didFinishRead();
+}
+
+void NetworkDataTask::read()
+{
+ RefPtr<NetworkDataTask> 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<GAsyncReadyCallback>(readCallback), protectedThis.leakRef());
+}
+
+void NetworkDataTask::didRead(gssize bytesRead)
+{
+ m_readBuffer.shrink(bytesRead);
+ if (m_downloadOutputStream) {
+ ASSERT(isDownload());
+ writeDownload();
+ } else {
+ ASSERT(m_client);
+ m_client->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->didCompleteWithError({ });
+}
+
+void NetworkDataTask::requestNextPartCallback(SoupMultipartInputStream* multipartInputStream, GAsyncResult* result, NetworkDataTask* task)
+{
+ RefPtr<NetworkDataTask> protectedThis = adoptRef(task);
+ if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) {
+ task->clearRequest();
+ return;
+ }
+ ASSERT(multipartInputStream == task->m_multipartInputStream.get());
+
+ if (task->state() == State::Suspended) {
+ ASSERT(!task->m_pendingResult);
+ task->m_pendingResult = result;
+ return;
+ }
+
+ GUniqueOutPtr<GError> error;
+ GRefPtr<GInputStream> inputStream = adoptGRef(soup_multipart_input_stream_next_part_finish(multipartInputStream, result, &error.outPtr()));
+ if (error)
+ task->didFail(ResourceError::httpError(task->m_soupMessage.get(), error.get(), task->m_soupRequest.get()));
+ else if (inputStream)
+ task->didRequestNextPart(WTFMove(inputStream));
+ else
+ task->didFinishRequestNextPart();
+}
+
+void NetworkDataTask::requestNextPart()
+{
+ RefPtr<NetworkDataTask> 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<GAsyncReadyCallback>(requestNextPartCallback), protectedThis.leakRef());
+}
+
+void NetworkDataTask::didRequestNextPart(GRefPtr<GInputStream>&& 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->didCompleteWithError({ });
+}
+
+void NetworkDataTask::gotHeadersCallback(SoupMessage* soupMessage, NetworkDataTask* task)
+{
+ if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) {
+ task->clearRequest();
+ return;
+ }
+ ASSERT(task->m_soupMessage.get() == soupMessage);
+ task->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->status_code) && m_soupMessage->status_code < 500) {
+ m_session->networkStorageSession().saveCredentialToPersistentStorage(m_protectionSpaceForPersistentStorage, m_credentialForPersistentStorage);
+ m_protectionSpaceForPersistentStorage = ProtectionSpace();
+ m_credentialForPersistentStorage = Credential();
+ }
+}
+
+void NetworkDataTask::wroteBodyDataCallback(SoupMessage* soupMessage, SoupBuffer* buffer, NetworkDataTask* task)
+{
+ if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) {
+ task->clearRequest();
+ return;
+ }
+ ASSERT(task->m_soupMessage.get() == soupMessage);
+ task->didWriteBodyData(buffer->length);
+}
+
+void NetworkDataTask::didWriteBodyData(uint64_t bytesSent)
+{
+ RefPtr<NetworkDataTask> protectedThis(this);
+ m_bodyDataTotalBytesSent += bytesSent;
+ m_client->didSendData(m_bodyDataTotalBytesSent, m_soupMessage->request_body->length);
+}
+
+void NetworkDataTask::download()
+{
+ ASSERT(isDownload());
+ ASSERT(m_pendingDownloadLocation);
+ ASSERT(!m_response.isNull());
+
+ if (m_response.httpStatusCode() >= 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<GFileOutputStream> outputStream;
+ GUniqueOutPtr<GError> error;
+ if (m_allowOverwriteDownload)
+ outputStream = adoptGRef(g_file_replace(m_downloadDestinationFile.get(), nullptr, FALSE, G_FILE_CREATE_NONE, nullptr, &error.outPtr()));
+ else
+ outputStream = adoptGRef(g_file_create(m_downloadDestinationFile.get(), G_FILE_CREATE_NONE, nullptr, &error.outPtr()));
+ if (!outputStream) {
+ didFailDownload(platformDownloadDestinationError(m_response, error->message));
+ return;
+ }
+
+ String intermediateURI = m_pendingDownloadLocation + ".wkdownload";
+ 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, &error.outPtr()));
+ if (!outputStream) {
+ didFailDownload(platformDownloadDestinationError(m_response, error->message));
+ return;
+ }
+ m_downloadOutputStream = adoptGRef(G_OUTPUT_STREAM(outputStream.leakRef()));
+
+ auto& downloadManager = NetworkProcess::singleton().downloadManager();
+ auto download = std::make_unique<Download>(downloadManager, m_pendingDownloadID, this, m_session->sessionID(), suggestedFilename());
+ auto* downloadPtr = download.get();
+ downloadManager.dataTaskBecameDownloadTask(m_pendingDownloadID, WTFMove(download));
+ downloadPtr->didCreateDestination(m_pendingDownloadLocation);
+
+ ASSERT(m_client);
+ m_client->didBecomeDownload();
+
+ read();
+}
+
+void NetworkDataTask::writeDownloadCallback(GOutputStream* outputStream, GAsyncResult* result, NetworkDataTask* task)
+{
+ RefPtr<NetworkDataTask> protectedThis = adoptRef(task);
+ if (task->state() == State::Canceling || task->state() == State::Completed || !task->isDownload()) {
+ task->clearRequest();
+ return;
+ }
+ ASSERT(outputStream == task->m_downloadOutputStream.get());
+
+ GUniqueOutPtr<GError> error;
+ gsize bytesWritten;
+#if GLIB_CHECK_VERSION(2, 44, 0)
+ g_output_stream_write_all_finish(outputStream, result, &bytesWritten, &error.outPtr());
+#else
+ gssize writeTaskResult = g_task_propagate_int(G_TASK(result), &error.outPtr());
+ if (writeTaskResult != -1)
+ bytesWritten = writeTaskResult;
+#endif
+ if (error)
+ task->didFailDownload(platformDownloadDestinationError(task->m_response, error->message));
+ else
+ task->didWriteDownload(bytesWritten);
+}
+
+void NetworkDataTask::writeDownload()
+{
+ RefPtr<NetworkDataTask> 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<GAsyncReadyCallback>(writeDownloadCallback), protectedThis.leakRef());
+#else
+ GRefPtr<GTask> writeTask = adoptGRef(g_task_new(m_downloadOutputStream.get(), m_cancellable.get(),
+ reinterpret_cast<GAsyncReadyCallback>(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<NetworkDataTask*>(userData);
+ GOutputStream* outputStream = G_OUTPUT_STREAM(source);
+ RELEASE_ASSERT(task->m_downloadOutputStream.get() == outputStream);
+ RELEASE_ASSERT(task->m_cancellable.get() == cancellable);
+ GError* error = nullptr;
+ if (g_cancellable_set_error_if_cancelled(cancellable, &error)) {
+ g_task_return_error(writeTask, error);
+ return;
+ }
+
+ gsize bytesWritten;
+ if (g_output_stream_write_all(outputStream, task->m_readBuffer.data(), task->m_readBuffer.size(), &bytesWritten, cancellable, &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->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<GError> error;
+ if (!g_file_move(m_downloadIntermediateFile.get(), m_downloadDestinationFile.get(), G_FILE_COPY_OVERWRITE, m_cancellable.get(), nullptr, nullptr, &error.outPtr())) {
+ didFailDownload(platformDownloadDestinationError(m_response, error->message));
+ return;
+ }
+
+ GRefPtr<GFileInfo> info = adoptGRef(g_file_info_new());
+ CString uri = m_response.url().string().utf8();
+ g_file_info_set_attribute_string(info.get(), "metadata::download-uri", uri.data());
+ g_file_info_set_attribute_string(info.get(), "xattr::xdg.origin.url", 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->didFinish();
+}
+
+void NetworkDataTask::didFailDownload(const ResourceError& error)
+{
+ clearRequest();
+ cleanDownloadFiles();
+ if (m_client)
+ m_client->didCompleteWithError(error);
+ else {
+ auto* download = NetworkProcess::singleton().downloadManager().download(m_pendingDownloadID);
+ ASSERT(download);
+ download->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& error)
+{
+ if (isDownload()) {
+ didFailDownload(platformDownloadNetworkError(error.errorCode(), error.failingURL(), error.localizedDescription()));
+ return;
+ }
+
+ clearRequest();
+ ASSERT(m_client);
+ m_client->didCompleteWithError(error);
+}
+
+#if ENABLE(WEB_TIMING)
+void NetworkDataTask::networkEventCallback(SoupMessage* soupMessage, GSocketClientEvent event, GIOStream*, NetworkDataTask* task)
+{
+ if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client)
+ return;
+
+ ASSERT(task->m_soupMessage.get() == soupMessage);
+ task->networkEvent(event);
+}
+
+void NetworkDataTask::networkEvent(GSocketClientEvent event)
+{
+ double deltaTime = monotonicallyIncreasingTimeMS() - m_startTime;
+ auto& 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 & 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->state() == State::Canceling || task->state() == State::Completed || !task->m_client)
+ return;
+
+ ASSERT(task->m_soupMessage.get() == soupMessage);
+ task->didStartRequest();
+}
+#else
+void NetworkDataTask::requestStartedCallback(SoupSession* session, SoupMessage* soupMessage, SoupSocket*, NetworkDataTask* task)
+{
+ ASSERT(session == task->m_session->soupSession());
+ if (soupMessage != task->m_soupMessage.get())
+ return;
+
+ if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client)
+ return;
+
+ task->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->state() == State::Canceling || task->state() == State::Completed || !task->m_client)
+ return;
+
+ ASSERT(task->m_soupMessage.get() == soupMessage);
+ task->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 "config.h"
+#include "NetworkSession.h"
+
+#include <WebCore/NetworkStorageSession.h>
+#include <WebCore/SoupNetworkSession.h>
+#include <wtf/MainThread.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+Ref<NetworkSession> NetworkSession::create(Type type, SessionID sessionID, CustomProtocolManager*)
+{
+ return adoptRef(*new NetworkSession(type, sessionID, nullptr));
+}
+
+NetworkSession& NetworkSession::defaultSession()
+{
+ ASSERT(isMainThread());
+ static NetworkSession* session = &NetworkSession::create(NetworkSession::Type::Normal, SessionID::defaultSessionID(), nullptr).leakRef();
+ return *session;
+}
+
+NetworkStorageSession& 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->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 "config.h"
</span><span class="cx"> #include "RemoteNetworkingContext.h"
</span><span class="cx">
</span><ins>+#include "NetworkSession.h"
+#include "SessionTracker.h"
</ins><span class="cx"> #include <WebCore/NetworkStorageSession.h>
</span><span class="cx"> #include <WebCore/NotImplemented.h>
</span><span class="cx"> #include <WebCore/ResourceHandle.h>
</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& 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 "MessageReceiver.h"
</span><span class="cx"> #include "NetworkProcessSupplement.h"
</span><del>-#include "NetworkSession.h"
</del><span class="cx"> #include "WebProcessSupplement.h"
</span><span class="cx"> #include <WebCore/AuthenticationChallenge.h>
</span><span class="cx"> #include <wtf/Forward.h>
</span><ins>+#include <wtf/Function.h>
</ins><span class="cx"> #include <wtf/HashMap.h>
</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<void(AuthenticationChallengeDisposition, const WebCore::Credential&)> 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 "config.h"
</span><span class="cx"> #include "WebFrameNetworkingContext.h"
</span><span class="cx">
</span><ins>+#include "NetworkSession.h"
</ins><span class="cx"> #include "SessionTracker.h"
</span><span class="cx"> #include "WebFrame.h"
</span><span class="cx"> #include "WebPage.h"
</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 "Logging.h"
</span><span class="cx"> #include "NetworkConnectionToWebProcessMessages.h"
</span><span class="cx"> #include "NetworkProcessConnection.h"
</span><ins>+#include "NetworkSession.h"
</ins><span class="cx"> #include "PluginProcessConnectionManager.h"
</span><span class="cx"> #include "SessionTracker.h"
</span><span class="cx"> #include "StatisticsData.h"
</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) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000)
</del><ins>+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 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>