<!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>[198083] trunk/Source</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/198083">198083</a></dd>
<dt>Author</dt> <dd>weinig@apple.com</dd>
<dt>Date</dt> <dd>2016-03-13 13:12:01 -0700 (Sun, 13 Mar 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>WebKit can easily crash below NetworkSession::dataTaskForIdentifier() with NSURLSession enabled
&lt;rdar://problem/25129946&gt;
https://bugs.webkit.org/show_bug.cgi?id=155401

Reviewed by Alex Christensen.

Source/WebCore:

Add a SessionID as a member of NetworkStorageSession. This allows us to avoid having HashMaps
to map between the two types.

* platform/network/NetworkStorageSession.h:
(WebCore::NetworkStorageSession::sessionID):
(WebCore::NetworkStorageSession::credentialStorage):
(WebCore::NetworkStorageSession::platformSession):
* platform/network/NetworkStorageSessionStub.cpp:
(WebCore::NetworkStorageSession::NetworkStorageSession):
(WebCore::NetworkStorageSession::context):
(WebCore::NetworkStorageSession::createPrivateBrowsingSession):
(WebCore::defaultSession):
(WebCore::NetworkStorageSession::defaultStorageSession):
(WebCore::NetworkStorageSession::switchToNewTestingSession):
* platform/network/cf/NetworkStorageSessionCFNet.cpp:
(WebCore::NetworkStorageSession::NetworkStorageSession):
(WebCore::NetworkStorageSession::switchToNewTestingSession):
(WebCore::NetworkStorageSession::defaultStorageSession):
(WebCore::NetworkStorageSession::createPrivateBrowsingSession):
* platform/network/soup/NetworkStorageSessionSoup.cpp:
(WebCore::NetworkStorageSession::NetworkStorageSession):
(WebCore::NetworkStorageSession::defaultStorageSession):
(WebCore::NetworkStorageSession::createPrivateBrowsingSession):
(WebCore::NetworkStorageSession::switchToNewTestingSession):
(WebCore::NetworkStorageSession::soupNetworkSession):

Source/WebKit/mac:

* WebCoreSupport/WebFrameNetworkingContext.mm:
(WebFrameNetworkingContext::ensurePrivateBrowsingSession):
Pass a SessionID to NetworkStorageSession::createPrivateBrowsingSession().

Source/WebKit/win:

* WebCoreSupport/WebFrameNetworkingContext.cpp:
(WebFrameNetworkingContext::ensurePrivateBrowsingSession):
Pass a SessionID to NetworkStorageSession::createPrivateBrowsingSession().

Source/WebKit2:

The issue was that NSURLSessionDataTasks can continue to invoke their NSURLSession's delegate methods
after -[NSURLSession invalidateAndCancel] is called. So, when the NetworkSession was destroyed, and
still had outstanding data tasks, the session delegate would get called, try to use the session, and
crash. To fix this I:
        
- Made NetworkSession RefCounted.
- Gave NetworkSession two delegates, one for each NSURLSession.
- Made each delegate have a strong reference to the NetworkSession that gets cleared out in the
  newly implemented URLSession:didBecomeInvalidWithError: method.
- Changed from simply destroying the NetworkSession in SessionTracker::destroySession(), to derefing
  it and explicitly calling invalidateAndCancel on the two associated NSURLSessions (which in turn 
  eventually cause the URLSession:didBecomeInvalidWithError: to fire).
- To ensure the correct lifetime of the WebCore::NetworkStorageSession, I made it a member of the
  NetworkSession. This also allowed some simplification inside SessionTracker.

* NetworkProcess/NetworkDataTask.h:
(WebKit::NetworkDataTask::setPendingDownload):
(WebKit::NetworkDataTask::pendingDownloadLocation):
* NetworkProcess/NetworkLoad.cpp:
(WebKit::NetworkLoad::NetworkLoad):
* NetworkProcess/NetworkSession.h:
(WebKit::NetworkSession::sessionID):
* NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
(WebKit::NetworkDataTask::NetworkDataTask):
(WebKit::NetworkDataTask::~NetworkDataTask):
(WebKit::NetworkDataTask::willPerformHTTPRedirection):
(WebKit::NetworkDataTask::tryPasswordBasedAuthentication):
* NetworkProcess/cocoa/NetworkSessionCocoa.mm:
(-[WKNetworkSessionDelegate initWithNetworkSession:]):
(-[WKNetworkSessionDelegate URLSession:didBecomeInvalidWithError:]):
(WebKit::NetworkSession::setCustomProtocolManager):
(WebKit::NetworkSession::create):
(WebKit::NetworkSession::defaultSession):
(WebKit::NetworkSession::NetworkSession):
(WebKit::NetworkSession::~NetworkSession):
(WebKit::NetworkSession::invalidateAndCancel):
(WebKit::NetworkSession::networkStorageSession):
(WebKit::NetworkSession::clearCredentials):
* NetworkProcess/mac/RemoteNetworkingContext.mm:
(WebKit::RemoteNetworkingContext::ensurePrivateBrowsingSession):
* Shared/SessionTracker.cpp:
(WebKit::identifierBase):
(WebKit::SessionTracker::getIdentifierBase):
(WebKit::SessionTracker::setIdentifierBase):
(WebKit::staticSessionMap):
(WebKit::SessionTracker::networkSession):
(WebKit::SessionTracker::storageSession):
(WebKit::staticStorageSessionMap):
(WebKit::SessionTracker::sessionID):
(WebKit::SessionTracker::setSession):
(WebKit::SessionTracker::destroySession):
(WebKit::SessionTracker::forEachNetworkStorageSession):
(WebKit::storageSessionToID): Deleted.
(WebKit::SessionTracker::storageSessionMap): Deleted.
* Shared/SessionTracker.h:
* WebProcess/WebCoreSupport/mac/WebFrameNetworkingContext.mm:
(WebKit::WebFrameNetworkingContext::ensurePrivateBrowsingSession):
(WebKit::WebFrameNetworkingContext::setCookieAcceptPolicyForAllContexts):
(WebKit::WebFrameNetworkingContext::localFileContentSniffingEnabled):
(WebKit::WebFrameNetworkingContext::scheduledRunLoopPairs):
* WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp:
(WebKit::WebFrameNetworkingContext::ensurePrivateBrowsingSession):
(WebKit::WebFrameNetworkingContext::setCookieAcceptPolicyForAllContexts):
(WebKit::WebFrameNetworkingContext::WebFrameNetworkingContext):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkNetworkStorageSessionh">trunk/Source/WebCore/platform/network/NetworkStorageSession.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkNetworkStorageSessionStubcpp">trunk/Source/WebCore/platform/network/NetworkStorageSessionStub.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcfNetworkStorageSessionCFNetcpp">trunk/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworksoupNetworkStorageSessionSoupcpp">trunk/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp</a></li>
<li><a href="#trunkSourceWebKitmacChangeLog">trunk/Source/WebKit/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitmacWebCoreSupportWebFrameNetworkingContextmm">trunk/Source/WebKit/mac/WebCoreSupport/WebFrameNetworkingContext.mm</a></li>
<li><a href="#trunkSourceWebKitwinChangeLog">trunk/Source/WebKit/win/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitwinWebCoreSupportWebFrameNetworkingContextcpp">trunk/Source/WebKit/win/WebCoreSupport/WebFrameNetworkingContext.cpp</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</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="#trunkSourceWebKit2NetworkProcessNetworkSessionh">trunk/Source/WebKit2/NetworkProcess/NetworkSession.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="#trunkSourceWebKit2NetworkProcessmacRemoteNetworkingContextmm">trunk/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.mm</a></li>
<li><a href="#trunkSourceWebKit2SharedSessionTrackercpp">trunk/Source/WebKit2/Shared/SessionTracker.cpp</a></li>
<li><a href="#trunkSourceWebKit2SharedSessionTrackerh">trunk/Source/WebKit2/Shared/SessionTracker.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebCoreSupportmacWebFrameNetworkingContextmm">trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebFrameNetworkingContext.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebCoreSupportsoupWebFrameNetworkingContextcpp">trunk/Source/WebKit2/WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebCore/ChangeLog        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -1,3 +1,37 @@
</span><ins>+2016-03-12  Sam Weinig  &lt;sam@webkit.org&gt;
+
+        WebKit can easily crash below NetworkSession::dataTaskForIdentifier() with NSURLSession enabled
+        &lt;rdar://problem/25129946&gt;
+        https://bugs.webkit.org/show_bug.cgi?id=155401
+
+        Reviewed by Alex Christensen.
+
+        Add a SessionID as a member of NetworkStorageSession. This allows us to avoid having HashMaps
+        to map between the two types.
+
+        * platform/network/NetworkStorageSession.h:
+        (WebCore::NetworkStorageSession::sessionID):
+        (WebCore::NetworkStorageSession::credentialStorage):
+        (WebCore::NetworkStorageSession::platformSession):
+        * platform/network/NetworkStorageSessionStub.cpp:
+        (WebCore::NetworkStorageSession::NetworkStorageSession):
+        (WebCore::NetworkStorageSession::context):
+        (WebCore::NetworkStorageSession::createPrivateBrowsingSession):
+        (WebCore::defaultSession):
+        (WebCore::NetworkStorageSession::defaultStorageSession):
+        (WebCore::NetworkStorageSession::switchToNewTestingSession):
+        * platform/network/cf/NetworkStorageSessionCFNet.cpp:
+        (WebCore::NetworkStorageSession::NetworkStorageSession):
+        (WebCore::NetworkStorageSession::switchToNewTestingSession):
+        (WebCore::NetworkStorageSession::defaultStorageSession):
+        (WebCore::NetworkStorageSession::createPrivateBrowsingSession):
+        * platform/network/soup/NetworkStorageSessionSoup.cpp:
+        (WebCore::NetworkStorageSession::NetworkStorageSession):
+        (WebCore::NetworkStorageSession::defaultStorageSession):
+        (WebCore::NetworkStorageSession::createPrivateBrowsingSession):
+        (WebCore::NetworkStorageSession::switchToNewTestingSession):
+        (WebCore::NetworkStorageSession::soupNetworkSession):
+
</ins><span class="cx"> 2016-03-13  Jon Lee  &lt;jonlee@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         getUserMedia requests from the main frame should be treated the same as requests from an iframe with the same origin
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkNetworkStorageSessionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/NetworkStorageSession.h (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/NetworkStorageSession.h        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebCore/platform/network/NetworkStorageSession.h        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -27,12 +27,12 @@
</span><span class="cx"> #define NetworkStorageSession_h
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CredentialStorage.h&quot;
</span><del>-
-#include &lt;wtf/RetainPtr.h&gt;
</del><ins>+#include &quot;SessionID.h&quot;
</ins><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA) || USE(CFNETWORK)
</span><span class="cx"> #include &quot;CFNetworkSPI.h&quot;
</span><ins>+#include &lt;wtf/RetainPtr.h&gt;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -45,31 +45,36 @@
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(NetworkStorageSession); WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><span class="cx">     WEBCORE_EXPORT static NetworkStorageSession&amp; defaultStorageSession();
</span><del>-    WEBCORE_EXPORT static std::unique_ptr&lt;NetworkStorageSession&gt; createPrivateBrowsingSession(const String&amp; identifierBase = String());
</del><ins>+    WEBCORE_EXPORT static std::unique_ptr&lt;NetworkStorageSession&gt; createPrivateBrowsingSession(SessionID, const String&amp; identifierBase = String());
</ins><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT static void switchToNewTestingSession();
</span><span class="cx"> 
</span><ins>+    SessionID sessionID() const { return m_sessionID; }
</ins><span class="cx">     CredentialStorage&amp; credentialStorage() { return m_credentialStorage; }
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA) || USE(CFNETWORK)
</span><del>-    NetworkStorageSession(RetainPtr&lt;CFURLStorageSessionRef&gt;);
</del><ins>+    NetworkStorageSession(SessionID, RetainPtr&lt;CFURLStorageSessionRef&gt;);
+
</ins><span class="cx">     // May be null, in which case a Foundation default should be used.
</span><span class="cx">     CFURLStorageSessionRef platformSession() { return m_platformSession.get(); }
</span><span class="cx">     WEBCORE_EXPORT RetainPtr&lt;CFHTTPCookieStorageRef&gt; cookieStorage() const;
</span><span class="cx"> #elif USE(SOUP)
</span><del>-    NetworkStorageSession(std::unique_ptr&lt;SoupNetworkSession&gt;);
</del><ins>+    NetworkStorageSession(SessionID, std::unique_ptr&lt;SoupNetworkSession&gt;);
</ins><span class="cx">     ~NetworkStorageSession();
</span><ins>+
</ins><span class="cx">     SoupNetworkSession&amp; soupNetworkSession() const;
</span><span class="cx">     void setSoupNetworkSession(std::unique_ptr&lt;SoupNetworkSession&gt;);
</span><span class="cx"> #else
</span><del>-    NetworkStorageSession(NetworkingContext*);
</del><ins>+    NetworkStorageSession(SessionID, NetworkingContext*);
</ins><span class="cx">     ~NetworkStorageSession();
</span><ins>+
</ins><span class="cx">     NetworkingContext* context() const;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    SessionID m_sessionID;
+
</ins><span class="cx"> #if PLATFORM(COCOA) || USE(CFNETWORK)
</span><del>-    NetworkStorageSession();
</del><span class="cx">     RetainPtr&lt;CFURLStorageSessionRef&gt; m_platformSession;
</span><span class="cx"> #elif USE(SOUP)
</span><span class="cx">     std::unique_ptr&lt;SoupNetworkSession&gt; m_session;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkNetworkStorageSessionStubcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/NetworkStorageSessionStub.cpp (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/NetworkStorageSessionStub.cpp        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebCore/platform/network/NetworkStorageSessionStub.cpp        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -30,11 +30,13 @@
</span><span class="cx"> #include &quot;NetworkStorageSession.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;NetworkingContext.h&quot;
</span><ins>+#include &lt;wtf/NeverDestroyed.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-NetworkStorageSession::NetworkStorageSession(NetworkingContext* context)
-    : m_context(context)
</del><ins>+NetworkStorageSession::NetworkStorageSession(SessionID sessionID, NetworkingContext* context)
+    : m_sessionID(sessionID)
+    , m_context(context)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -47,18 +49,25 @@
</span><span class="cx">     return m_context.get();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-std::unique_ptr&lt;NetworkStorageSession&gt; NetworkStorageSession::createPrivateBrowsingSession(const String&amp;)
</del><ins>+std::unique_ptr&lt;NetworkStorageSession&gt; NetworkStorageSession::createPrivateBrowsingSession(SessionID sessionID, const String&amp;)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-NetworkStorageSession&amp; NetworkStorageSession::defaultStorageSession()
</del><ins>+static std::unique_ptr&lt;NetworkStorageSession&gt;&amp; defaultSession()
</ins><span class="cx"> {
</span><del>-    DEPRECATED_DEFINE_STATIC_LOCAL(NetworkStorageSession, session, (0));
</del><ins>+    static NeverDestroyed&lt;std::unique_ptr&lt;NetworkStorageSession&gt;&gt; session;
</ins><span class="cx">     return session;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+NetworkStorageSession&amp; NetworkStorageSession::defaultStorageSession()
+{
+    if (!defaultSession())
+        defaultSession() = std::make_unique&lt;NetworkStorageSession&gt;(SessionID::defaultSessionID(), nullptr);
+    return *defaultSession();
+}
+
</ins><span class="cx"> void NetworkStorageSession::switchToNewTestingSession()
</span><span class="cx"> {
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcfNetworkStorageSessionCFNetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -41,8 +41,9 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-NetworkStorageSession::NetworkStorageSession(RetainPtr&lt;CFURLStorageSessionRef&gt; platformSession)
-    : m_platformSession(platformSession)
</del><ins>+NetworkStorageSession::NetworkStorageSession(SessionID sessionID, RetainPtr&lt;CFURLStorageSessionRef&gt; platformSession)
+    : m_sessionID(sessionID)
+    , m_platformSession(platformSession)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -58,27 +59,27 @@
</span><span class="cx">     // Session name should be short enough for shared memory region name to be under the limit, otehrwise sandbox rules won't work (see &lt;rdar://problem/13642852&gt;).
</span><span class="cx">     String sessionName = String::format(&quot;WebKit Test-%u&quot;, static_cast&lt;uint32_t&gt;(getCurrentProcessID()));
</span><span class="cx"> #if PLATFORM(COCOA)
</span><del>-    defaultNetworkStorageSession() = std::make_unique&lt;NetworkStorageSession&gt;(adoptCF(wkCreatePrivateStorageSession(sessionName.createCFString().get())));
</del><ins>+    defaultNetworkStorageSession() = std::make_unique&lt;NetworkStorageSession&gt;(SessionID::defaultSessionID(), adoptCF(wkCreatePrivateStorageSession(sessionName.createCFString().get())));
</ins><span class="cx"> #else
</span><del>-    defaultNetworkStorageSession() = std::make_unique&lt;NetworkStorageSession&gt;(adoptCF(wkCreatePrivateStorageSession(sessionName.createCFString().get(), defaultNetworkStorageSession()-&gt;platformSession())));
</del><ins>+    defaultNetworkStorageSession() = std::make_unique&lt;NetworkStorageSession&gt;(SessionID::defaultSessionID(), adoptCF(wkCreatePrivateStorageSession(sessionName.createCFString().get(), defaultNetworkStorageSession()-&gt;platformSession())));
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> NetworkStorageSession&amp; NetworkStorageSession::defaultStorageSession()
</span><span class="cx"> {
</span><span class="cx">     if (!defaultNetworkStorageSession())
</span><del>-        defaultNetworkStorageSession() = std::make_unique&lt;NetworkStorageSession&gt;(nullptr);
</del><ins>+        defaultNetworkStorageSession() = std::make_unique&lt;NetworkStorageSession&gt;(SessionID::defaultSessionID(), nullptr);
</ins><span class="cx">     return *defaultNetworkStorageSession();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-std::unique_ptr&lt;NetworkStorageSession&gt; NetworkStorageSession::createPrivateBrowsingSession(const String&amp; identifierBase)
</del><ins>+std::unique_ptr&lt;NetworkStorageSession&gt; NetworkStorageSession::createPrivateBrowsingSession(SessionID sessionID, const String&amp; identifierBase)
</ins><span class="cx"> {
</span><span class="cx">     RetainPtr&lt;CFStringRef&gt; cfIdentifier = String(identifierBase + &quot;.PrivateBrowsing&quot;).createCFString();
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><del>-    auto session = std::make_unique&lt;NetworkStorageSession&gt;(adoptCF(wkCreatePrivateStorageSession(cfIdentifier.get())));
</del><ins>+    auto session = std::make_unique&lt;NetworkStorageSession&gt;(sessionID, adoptCF(wkCreatePrivateStorageSession(cfIdentifier.get())));
</ins><span class="cx"> #else
</span><del>-    auto session = std::make_unique&lt;NetworkStorageSession&gt;(adoptCF(wkCreatePrivateStorageSession(cfIdentifier.get(), defaultNetworkStorageSession()-&gt;platformSession())));
</del><ins>+    auto session = std::make_unique&lt;NetworkStorageSession&gt;(sessionID, adoptCF(wkCreatePrivateStorageSession(cfIdentifier.get(), defaultNetworkStorageSession()-&gt;platformSession())));
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     return session;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworksoupNetworkStorageSessionSoupcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -36,8 +36,9 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-NetworkStorageSession::NetworkStorageSession(std::unique_ptr&lt;SoupNetworkSession&gt; session)
-    : m_session(WTFMove(session))
</del><ins>+NetworkStorageSession::NetworkStorageSession(SessionID sessionID, std::unique_ptr&lt;SoupNetworkSession&gt; session)
+    : m_sessionID(sessionID)
+    , m_session(WTFMove(session))
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -55,19 +56,19 @@
</span><span class="cx"> NetworkStorageSession&amp; NetworkStorageSession::defaultStorageSession()
</span><span class="cx"> {
</span><span class="cx">     if (!defaultSession())
</span><del>-        defaultSession() = std::make_unique&lt;NetworkStorageSession&gt;(nullptr);
</del><ins>+        defaultSession() = std::make_unique&lt;NetworkStorageSession&gt;(SessionID::defaultSessionID(), nullptr);
</ins><span class="cx">     return *defaultSession();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-std::unique_ptr&lt;NetworkStorageSession&gt; NetworkStorageSession::createPrivateBrowsingSession(const String&amp;)
</del><ins>+std::unique_ptr&lt;NetworkStorageSession&gt; NetworkStorageSession::createPrivateBrowsingSession(SessionID sessionID, const String&amp;)
</ins><span class="cx"> {
</span><del>-    auto session = std::make_unique&lt;NetworkStorageSession&gt;(SoupNetworkSession::createPrivateBrowsingSession());
</del><ins>+    auto session = std::make_unique&lt;NetworkStorageSession&gt;(sessionID, SoupNetworkSession::createPrivateBrowsingSession());
</ins><span class="cx">     return session;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void NetworkStorageSession::switchToNewTestingSession()
</span><span class="cx"> {
</span><del>-    defaultSession() = std::make_unique&lt;NetworkStorageSession&gt;(SoupNetworkSession::createTestingSession());
</del><ins>+    defaultSession() = std::make_unique&lt;NetworkStorageSession&gt;(SessionID::defaultSessionID(), SoupNetworkSession::createTestingSession());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> SoupNetworkSession&amp; NetworkStorageSession::soupNetworkSession() const
</span></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebKit/mac/ChangeLog        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2016-03-12  Sam Weinig  &lt;sam@webkit.org&gt;
+
+        WebKit can easily crash below NetworkSession::dataTaskForIdentifier() with NSURLSession enabled
+        &lt;rdar://problem/25129946&gt;
+        https://bugs.webkit.org/show_bug.cgi?id=155401
+
+        Reviewed by Alex Christensen.
+
+        * WebCoreSupport/WebFrameNetworkingContext.mm:
+        (WebFrameNetworkingContext::ensurePrivateBrowsingSession):
+        Pass a SessionID to NetworkStorageSession::createPrivateBrowsingSession().
+
</ins><span class="cx"> 2016-03-12  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Delete dead SVG Font code
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebFrameNetworkingContextmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebFrameNetworkingContext.mm (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebFrameNetworkingContext.mm        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebFrameNetworkingContext.mm        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #import &lt;WebCore/NetworkStorageSession.h&gt;
</span><span class="cx"> #import &lt;WebCore/Page.h&gt;
</span><span class="cx"> #import &lt;WebCore/ResourceError.h&gt;
</span><ins>+#import &lt;WebCore/SessionID.h&gt;
</ins><span class="cx"> #import &lt;WebCore/Settings.h&gt;
</span><span class="cx"> #import &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -56,7 +57,7 @@
</span><span class="cx">     if (privateSession())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    privateSession() = NetworkStorageSession::createPrivateBrowsingSession([[NSBundle mainBundle] bundleIdentifier]);
</del><ins>+    privateSession() = NetworkStorageSession::createPrivateBrowsingSession(SessionID::legacyPrivateSessionID(), [[NSBundle mainBundle] bundleIdentifier]);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebFrameNetworkingContext::destroyPrivateBrowsingSession()
</span></span></pre></div>
<a id="trunkSourceWebKitwinChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/ChangeLog (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/ChangeLog        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebKit/win/ChangeLog        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2016-03-12  Sam Weinig  &lt;sam@webkit.org&gt;
+
+        WebKit can easily crash below NetworkSession::dataTaskForIdentifier() with NSURLSession enabled
+        &lt;rdar://problem/25129946&gt;
+        https://bugs.webkit.org/show_bug.cgi?id=155401
+
+        Reviewed by Alex Christensen.
+
+        * WebCoreSupport/WebFrameNetworkingContext.cpp:
+        (WebFrameNetworkingContext::ensurePrivateBrowsingSession):
+        Pass a SessionID to NetworkStorageSession::createPrivateBrowsingSession().
+
</ins><span class="cx"> 2016-03-10  Jer Noble  &lt;jer.noble@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed build fix after r197953; correct the settings added in r197953.
</span></span></pre></div>
<a id="trunkSourceWebKitwinWebCoreSupportWebFrameNetworkingContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/WebCoreSupport/WebFrameNetworkingContext.cpp (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/WebCoreSupport/WebFrameNetworkingContext.cpp        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebKit/win/WebCoreSupport/WebFrameNetworkingContext.cpp        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -87,7 +87,7 @@
</span><span class="cx">     } else
</span><span class="cx">         base = identifierBase();
</span><span class="cx"> 
</span><del>-    privateSession() = NetworkStorageSession::createPrivateBrowsingSession(base);
</del><ins>+    privateSession() = NetworkStorageSession::createPrivateBrowsingSession(SessionID::legacyPrivateSessionID(), base);
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebKit2/ChangeLog        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -1,3 +1,76 @@
</span><ins>+2016-03-12  Sam Weinig  &lt;sam@webkit.org&gt;
+
+        WebKit can easily crash below NetworkSession::dataTaskForIdentifier() with NSURLSession enabled
+        &lt;rdar://problem/25129946&gt;
+        https://bugs.webkit.org/show_bug.cgi?id=155401
+
+        Reviewed by Alex Christensen.
+
+        The issue was that NSURLSessionDataTasks can continue to invoke their NSURLSession's delegate methods
+        after -[NSURLSession invalidateAndCancel] is called. So, when the NetworkSession was destroyed, and
+        still had outstanding data tasks, the session delegate would get called, try to use the session, and
+        crash. To fix this I:
+        
+        - Made NetworkSession RefCounted.
+        - Gave NetworkSession two delegates, one for each NSURLSession.
+        - Made each delegate have a strong reference to the NetworkSession that gets cleared out in the
+          newly implemented URLSession:didBecomeInvalidWithError: method.
+        - Changed from simply destroying the NetworkSession in SessionTracker::destroySession(), to derefing
+          it and explicitly calling invalidateAndCancel on the two associated NSURLSessions (which in turn 
+          eventually cause the URLSession:didBecomeInvalidWithError: to fire).
+        - To ensure the correct lifetime of the WebCore::NetworkStorageSession, I made it a member of the
+          NetworkSession. This also allowed some simplification inside SessionTracker.
+
+        * NetworkProcess/NetworkDataTask.h:
+        (WebKit::NetworkDataTask::setPendingDownload):
+        (WebKit::NetworkDataTask::pendingDownloadLocation):
+        * NetworkProcess/NetworkLoad.cpp:
+        (WebKit::NetworkLoad::NetworkLoad):
+        * NetworkProcess/NetworkSession.h:
+        (WebKit::NetworkSession::sessionID):
+        * NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
+        (WebKit::NetworkDataTask::NetworkDataTask):
+        (WebKit::NetworkDataTask::~NetworkDataTask):
+        (WebKit::NetworkDataTask::willPerformHTTPRedirection):
+        (WebKit::NetworkDataTask::tryPasswordBasedAuthentication):
+        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+        (-[WKNetworkSessionDelegate initWithNetworkSession:]):
+        (-[WKNetworkSessionDelegate URLSession:didBecomeInvalidWithError:]):
+        (WebKit::NetworkSession::setCustomProtocolManager):
+        (WebKit::NetworkSession::create):
+        (WebKit::NetworkSession::defaultSession):
+        (WebKit::NetworkSession::NetworkSession):
+        (WebKit::NetworkSession::~NetworkSession):
+        (WebKit::NetworkSession::invalidateAndCancel):
+        (WebKit::NetworkSession::networkStorageSession):
+        (WebKit::NetworkSession::clearCredentials):
+        * NetworkProcess/mac/RemoteNetworkingContext.mm:
+        (WebKit::RemoteNetworkingContext::ensurePrivateBrowsingSession):
+        * Shared/SessionTracker.cpp:
+        (WebKit::identifierBase):
+        (WebKit::SessionTracker::getIdentifierBase):
+        (WebKit::SessionTracker::setIdentifierBase):
+        (WebKit::staticSessionMap):
+        (WebKit::SessionTracker::networkSession):
+        (WebKit::SessionTracker::storageSession):
+        (WebKit::staticStorageSessionMap):
+        (WebKit::SessionTracker::sessionID):
+        (WebKit::SessionTracker::setSession):
+        (WebKit::SessionTracker::destroySession):
+        (WebKit::SessionTracker::forEachNetworkStorageSession):
+        (WebKit::storageSessionToID): Deleted.
+        (WebKit::SessionTracker::storageSessionMap): Deleted.
+        * Shared/SessionTracker.h:
+        * WebProcess/WebCoreSupport/mac/WebFrameNetworkingContext.mm:
+        (WebKit::WebFrameNetworkingContext::ensurePrivateBrowsingSession):
+        (WebKit::WebFrameNetworkingContext::setCookieAcceptPolicyForAllContexts):
+        (WebKit::WebFrameNetworkingContext::localFileContentSniffingEnabled):
+        (WebKit::WebFrameNetworkingContext::scheduledRunLoopPairs):
+        * WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp:
+        (WebKit::WebFrameNetworkingContext::ensurePrivateBrowsingSession):
+        (WebKit::WebFrameNetworkingContext::setCookieAcceptPolicyForAllContexts):
+        (WebKit::WebFrameNetworkingContext::WebFrameNetworkingContext):
+
</ins><span class="cx"> 2016-03-12  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Delete dead SVG Font code
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkDataTaskh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -121,6 +121,7 @@
</span><span class="cx">     }
</span><span class="cx">     void setPendingDownloadLocation(const String&amp; filename, const SandboxExtension::Handle&amp;);
</span><span class="cx">     const String&amp; pendingDownloadLocation() { return m_pendingDownloadLocation; }
</span><ins>+
</ins><span class="cx">     WebCore::ResourceRequest currentRequest();
</span><span class="cx">     String suggestedFilename();
</span><span class="cx">     void willPerformHTTPRedirection(const WebCore::ResourceResponse&amp;, WebCore::ResourceRequest&amp;&amp;, RedirectCompletionHandler);
</span><span class="lines">@@ -141,7 +142,7 @@
</span><span class="cx">     void failureTimerFired();
</span><span class="cx">     void scheduleFailure(FailureType);
</span><span class="cx">     
</span><del>-    NetworkSession&amp; m_session;
</del><ins>+    RefPtr&lt;NetworkSession&gt; m_session;
</ins><span class="cx">     NetworkDataTaskClient* m_client;
</span><span class="cx">     PendingDownload* m_pendingDownload { nullptr };
</span><span class="cx">     DownloadID m_pendingDownloadID;
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkLoadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -58,7 +58,7 @@
</span><span class="cx">         if (!parameters.defersLoading)
</span><span class="cx">             m_task-&gt;resume();
</span><span class="cx">     } else
</span><del>-        ASSERT_NOT_REACHED();
</del><ins>+        WTFLogAlways(&quot;Attempted to create a NetworkLoad with a session (id=%&quot; PRIu64 &quot;) that does not exist.&quot;, parameters.sessionID.sessionID());
</ins><span class="cx"> #else
</span><span class="cx">     m_handle = ResourceHandle::create(m_networkingContext.get(), parameters.request, this, parameters.defersLoading, parameters.contentSniffingPolicy == SniffContent);
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkSessionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkSession.h (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkSession.h        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkSession.h        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -47,19 +47,25 @@
</span><span class="cx"> 
</span><span class="cx"> class CustomProtocolManager;
</span><span class="cx"> 
</span><del>-class NetworkSession {
</del><ins>+class NetworkSession : public RefCounted&lt;NetworkSession&gt; {
</ins><span class="cx">     friend class NetworkDataTask;
</span><span class="cx"> public:
</span><span class="cx">     enum class Type {
</span><span class="cx">         Normal,
</span><span class="cx">         Ephemeral
</span><span class="cx">     };
</span><del>-    NetworkSession(Type, WebCore::SessionID, CustomProtocolManager*, WebCore::NetworkStorageSession*);
</del><ins>+
+    static Ref&lt;NetworkSession&gt; create(Type, WebCore::SessionID, CustomProtocolManager*, std::unique_ptr&lt;WebCore::NetworkStorageSession&gt;);
+    static NetworkSession&amp; defaultSession();
</ins><span class="cx">     ~NetworkSession();
</span><span class="cx"> 
</span><del>-    WebCore::SessionID sessionID() { return m_sessionID; }
</del><ins>+    void invalidateAndCancel();
+
+    WebCore::SessionID sessionID() const { return m_sessionID; }
+    WebCore::NetworkStorageSession&amp; networkStorageSession();
+
</ins><span class="cx">     static void setCustomProtocolManager(CustomProtocolManager*);
</span><del>-    static NetworkSession&amp; defaultSession();
</del><ins>+
</ins><span class="cx"> #if !USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
</span><span class="cx">     void clearCredentials();
</span><span class="cx"> #endif
</span><span class="lines">@@ -71,14 +77,20 @@
</span><span class="cx">     DownloadID takeDownloadID(NetworkDataTask::TaskIdentifier);
</span><span class="cx">     
</span><span class="cx"> private:
</span><ins>+    NetworkSession(Type, WebCore::SessionID, CustomProtocolManager*, std::unique_ptr&lt;WebCore::NetworkStorageSession&gt;);
+
</ins><span class="cx">     WebCore::SessionID m_sessionID;
</span><ins>+    std::unique_ptr&lt;WebCore::NetworkStorageSession&gt; m_networkStorageSession;
+
</ins><span class="cx">     HashMap&lt;NetworkDataTask::TaskIdentifier, NetworkDataTask*&gt; m_dataTaskMapWithCredentials;
</span><span class="cx">     HashMap&lt;NetworkDataTask::TaskIdentifier, NetworkDataTask*&gt; m_dataTaskMapWithoutCredentials;
</span><span class="cx">     HashMap&lt;NetworkDataTask::TaskIdentifier, DownloadID&gt; m_downloadMap;
</span><ins>+
</ins><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx">     RetainPtr&lt;NSURLSession&gt; m_sessionWithCredentialStorage;
</span><ins>+    RetainPtr&lt;WKNetworkSessionDelegate&gt; m_sessionWithCredentialStorageDelegate;
</ins><span class="cx">     RetainPtr&lt;NSURLSession&gt; m_sessionWithoutCredentialStorage;
</span><del>-    RetainPtr&lt;WKNetworkSessionDelegate&gt; m_sessionDelegate;
</del><ins>+    RetainPtr&lt;WKNetworkSessionDelegate&gt; m_sessionWithoutCredentialStorageDelegate;
</ins><span class="cx"> #endif
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscocoaNetworkDataTaskCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -51,7 +51,7 @@
</span><span class="cx"> 
</span><span class="cx"> NetworkDataTask::NetworkDataTask(NetworkSession&amp; session, NetworkDataTaskClient&amp; client, const WebCore::ResourceRequest&amp; requestWithCredentials, WebCore::StoredCredentials storedCredentials, WebCore::ContentSniffingPolicy shouldContentSniff, bool shouldClearReferrerOnHTTPSToHTTPRedirect)
</span><span class="cx">     : m_failureTimer(*this, &amp;NetworkDataTask::failureTimerFired)
</span><del>-    , m_session(session)
</del><ins>+    , m_session(&amp;session)
</ins><span class="cx">     , m_client(&amp;client)
</span><span class="cx">     , m_storedCredentials(storedCredentials)
</span><span class="cx">     , m_lastHTTPMethod(requestWithCredentials.httpMethod())
</span><span class="lines">@@ -79,13 +79,10 @@
</span><span class="cx">         url = request.url();
</span><span class="cx">     
</span><span class="cx"> #if USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
</span><del>-        if (auto storageSession = SessionTracker::storageSession(m_session.sessionID())) {
-            if (m_user.isEmpty() &amp;&amp; m_password.isEmpty())
-                m_initialCredential = storageSession-&gt;credentialStorage().get(url);
-            else
-                storageSession-&gt;credentialStorage().set(WebCore::Credential(m_user, m_password, WebCore::CredentialPersistenceNone), url);
-        } else
-            ASSERT_NOT_REACHED();
</del><ins>+        if (m_user.isEmpty() &amp;&amp; m_password.isEmpty())
+            m_initialCredential = m_session-&gt;networkStorageSession().credentialStorage().get(url);
+        else
+            m_session-&gt;networkStorageSession().credentialStorage().set(WebCore::Credential(m_user, m_password, WebCore::CredentialPersistenceNone), url);
</ins><span class="cx"> #endif
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -104,13 +101,13 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (storedCredentials == WebCore::AllowStoredCredentials) {
</span><del>-        m_task = [m_session.m_sessionWithCredentialStorage dataTaskWithRequest:nsRequest];
-        ASSERT(!m_session.m_dataTaskMapWithCredentials.contains([m_task taskIdentifier]));
-        m_session.m_dataTaskMapWithCredentials.add([m_task taskIdentifier], this);
</del><ins>+        m_task = [m_session-&gt;m_sessionWithCredentialStorage dataTaskWithRequest:nsRequest];
+        ASSERT(!m_session-&gt;m_dataTaskMapWithCredentials.contains([m_task taskIdentifier]));
+        m_session-&gt;m_dataTaskMapWithCredentials.add([m_task taskIdentifier], this);
</ins><span class="cx">     } else {
</span><del>-        m_task = [m_session.m_sessionWithoutCredentialStorage dataTaskWithRequest:nsRequest];
-        ASSERT(!m_session.m_dataTaskMapWithoutCredentials.contains([m_task taskIdentifier]));
-        m_session.m_dataTaskMapWithoutCredentials.add([m_task taskIdentifier], this);
</del><ins>+        m_task = [m_session-&gt;m_sessionWithoutCredentialStorage dataTaskWithRequest:nsRequest];
+        ASSERT(!m_session-&gt;m_dataTaskMapWithoutCredentials.contains([m_task taskIdentifier]));
+        m_session-&gt;m_dataTaskMapWithoutCredentials.add([m_task taskIdentifier], this);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
</span><span class="lines">@@ -125,11 +122,11 @@
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx">     if (m_task) {
</span><span class="cx">         if (m_storedCredentials == WebCore::StoredCredentials::AllowStoredCredentials) {
</span><del>-            ASSERT(m_session.m_dataTaskMapWithCredentials.get([m_task taskIdentifier]) == this);
-            m_session.m_dataTaskMapWithCredentials.remove([m_task taskIdentifier]);
</del><ins>+            ASSERT(m_session-&gt;m_dataTaskMapWithCredentials.get([m_task taskIdentifier]) == this);
+            m_session-&gt;m_dataTaskMapWithCredentials.remove([m_task taskIdentifier]);
</ins><span class="cx">         } else {
</span><del>-            ASSERT(m_session.m_dataTaskMapWithoutCredentials.get([m_task taskIdentifier]) == this);
-            m_session.m_dataTaskMapWithoutCredentials.remove([m_task taskIdentifier]);
</del><ins>+            ASSERT(m_session-&gt;m_dataTaskMapWithoutCredentials.get([m_task taskIdentifier]) == this);
+            m_session-&gt;m_dataTaskMapWithoutCredentials.remove([m_task taskIdentifier]);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -221,16 +218,13 @@
</span><span class="cx">         // Only consider applying authentication credentials if this is actually a redirect and the redirect
</span><span class="cx">         // URL didn't include credentials of its own.
</span><span class="cx">         if (m_user.isEmpty() &amp;&amp; m_password.isEmpty() &amp;&amp; !redirectResponse.isNull()) {
</span><del>-            if (auto storageSession = SessionTracker::storageSession(m_session.sessionID())) {
-                auto credential = storageSession-&gt;credentialStorage().get(request.url());
-                if (!credential.isEmpty()) {
-                    m_initialCredential = credential;
</del><ins>+            auto credential = m_session-&gt;networkStorageSession().credentialStorage().get(request.url());
+            if (!credential.isEmpty()) {
+                m_initialCredential = credential;
</ins><span class="cx"> 
</span><del>-                    // FIXME: Support Digest authentication, and Proxy-Authorization.
-                    applyBasicAuthorizationHeader(request, m_initialCredential);
-                }
-            } else
-                ASSERT_NOT_REACHED();
</del><ins>+                // FIXME: Support Digest authentication, and Proxy-Authorization.
+                applyBasicAuthorizationHeader(request, m_initialCredential);
+            }
</ins><span class="cx">         }
</span><span class="cx"> #endif
</span><span class="cx">     }
</span><span class="lines">@@ -298,28 +292,25 @@
</span><span class="cx"> 
</span><span class="cx"> #if USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
</span><span class="cx">     if (m_storedCredentials == WebCore::AllowStoredCredentials) {
</span><del>-        if (auto storageSession = SessionTracker::storageSession(m_session.sessionID())) {
-            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 ResourceHandle,
-                // but the observable effect should be very minor, if any.
-                storageSession-&gt;credentialStorage().remove(challenge.protectionSpace());
-            }
</del><ins>+        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 ResourceHandle,
+            // but the observable effect should be very minor, if any.
+            m_session-&gt;networkStorageSession().credentialStorage().remove(challenge.protectionSpace());
+        }
</ins><span class="cx"> 
</span><del>-            if (!challenge.previousFailureCount()) {
-                auto credential = storageSession-&gt;credentialStorage().get(challenge.protectionSpace());
-                if (!credential.isEmpty() &amp;&amp; credential != m_initialCredential) {
-                    ASSERT(credential.persistence() == WebCore::CredentialPersistenceNone);
-                    if (challenge.failureResponse().httpStatusCode() == 401) {
-                        // Store the credential back, possibly adding it as a default for this directory.
-                        storageSession-&gt;credentialStorage().set(credential, challenge.protectionSpace(), challenge.failureResponse().url());
-                    }
-                    completionHandler(AuthenticationChallengeDisposition::UseCredential, credential);
-                    return true;
</del><ins>+        if (!challenge.previousFailureCount()) {
+            auto credential = m_session-&gt;networkStorageSession().credentialStorage().get(challenge.protectionSpace());
+            if (!credential.isEmpty() &amp;&amp; credential != m_initialCredential) {
+                ASSERT(credential.persistence() == WebCore::CredentialPersistenceNone);
+                if (challenge.failureResponse().httpStatusCode() == 401) {
+                    // Store the credential back, possibly adding it as a default for this directory.
+                    m_session-&gt;networkStorageSession().credentialStorage().set(credential, challenge.protectionSpace(), challenge.failureResponse().url());
</ins><span class="cx">                 }
</span><ins>+                completionHandler(AuthenticationChallengeDisposition::UseCredential, credential);
+                return true;
</ins><span class="cx">             }
</span><del>-        } else
-            ASSERT_NOT_REACHED();
</del><ins>+        }
</ins><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscocoaNetworkSessionCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -77,7 +77,8 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> @interface WKNetworkSessionDelegate : NSObject &lt;NSURLSessionDataDelegate&gt; {
</span><del>-    WebKit::NetworkSession* _session;
</del><ins>+    RefPtr&lt;WebKit::NetworkSession&gt; _session;
+    bool _sessionDestroyed;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (id)initWithNetworkSession:(WebKit::NetworkSession&amp;)session;
</span><span class="lines">@@ -97,6 +98,11 @@
</span><span class="cx">     return self;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable NSError *)error
+{
+    _session = nullptr;
+}
+
</ins><span class="cx"> - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
</span><span class="cx"> {
</span><span class="cx">     auto storedCredentials = session.configuration.URLCredentialStorage ? WebCore::StoredCredentials::AllowStoredCredentials : WebCore::StoredCredentials::DoNotAllowStoredCredentials;
</span><span class="lines">@@ -265,17 +271,23 @@
</span><span class="cx">     globalCustomProtocolManager() = customProtocolManager;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Ref&lt;NetworkSession&gt; NetworkSession::create(Type type, WebCore::SessionID sessionID, CustomProtocolManager* customProtocolManager, std::unique_ptr&lt;WebCore::NetworkStorageSession&gt; networkStorageSession)
+{
+    return adoptRef(*new NetworkSession(type, sessionID, customProtocolManager, WTFMove(networkStorageSession)));
+}
+
</ins><span class="cx"> NetworkSession&amp; NetworkSession::defaultSession()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><del>-    static NeverDestroyed&lt;NetworkSession&gt; session(NetworkSession::Type::Normal, WebCore::SessionID::defaultSessionID(), globalCustomProtocolManager().get(), &amp;WebCore::NetworkStorageSession::defaultStorageSession());
-    return session;
</del><ins>+    static NetworkSession* session = &amp;NetworkSession::create(NetworkSession::Type::Normal, WebCore::SessionID::defaultSessionID(), globalCustomProtocolManager().get(), nullptr).leakRef();
+    return *session;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-NetworkSession::NetworkSession(Type type, WebCore::SessionID sessionID, CustomProtocolManager* customProtocolManager, WebCore::NetworkStorageSession* networkStorageSession)
</del><ins>+NetworkSession::NetworkSession(Type type, WebCore::SessionID sessionID, CustomProtocolManager* customProtocolManager, std::unique_ptr&lt;WebCore::NetworkStorageSession&gt; networkStorageSession)
</ins><span class="cx">     : m_sessionID(sessionID)
</span><ins>+    , m_networkStorageSession(WTFMove(networkStorageSession))
</ins><span class="cx"> {
</span><del>-    m_sessionDelegate = adoptNS([[WKNetworkSessionDelegate alloc] initWithNetworkSession:*this]);
</del><ins>+    relaxAdoptionRequirement();
</ins><span class="cx"> 
</span><span class="cx">     NSURLSessionConfiguration *configuration = configurationForType(type);
</span><span class="cx"> 
</span><span class="lines">@@ -288,21 +300,42 @@
</span><span class="cx">     setCollectsTimingData();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    if (networkStorageSession) {
-        if (CFHTTPCookieStorageRef storage = networkStorageSession-&gt;cookieStorage().get())
</del><ins>+    if (m_networkStorageSession) {
+        ASSERT(type == Type::Ephemeral);
+        if (CFHTTPCookieStorageRef storage = m_networkStorageSession-&gt;cookieStorage().get())
</ins><span class="cx">             configuration.HTTPCookieStorage = [[[NSHTTPCookieStorage alloc] _initWithCFHTTPCookieStorage:storage] autorelease];
</span><ins>+    } else {
+        ASSERT(type == Type::Normal);
+        if (CFHTTPCookieStorageRef storage = WebCore::NetworkStorageSession::defaultStorageSession().cookieStorage().get())
+            configuration.HTTPCookieStorage = [[[NSHTTPCookieStorage alloc] _initWithCFHTTPCookieStorage:storage] autorelease];
</ins><span class="cx">     }
</span><del>-    m_sessionWithCredentialStorage = [NSURLSession sessionWithConfiguration:configuration delegate:static_cast&lt;id&gt;(m_sessionDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
</del><ins>+
+    m_sessionWithCredentialStorageDelegate = adoptNS([[WKNetworkSessionDelegate alloc] initWithNetworkSession:*this]);
+    m_sessionWithCredentialStorage = [NSURLSession sessionWithConfiguration:configuration delegate:static_cast&lt;id&gt;(m_sessionWithCredentialStorageDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
+
</ins><span class="cx">     configuration.URLCredentialStorage = nil;
</span><del>-    m_sessionWithoutCredentialStorage = [NSURLSession sessionWithConfiguration:configuration delegate:static_cast&lt;id&gt;(m_sessionDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
</del><ins>+    m_sessionWithoutCredentialStorageDelegate = adoptNS([[WKNetworkSessionDelegate alloc] initWithNetworkSession:*this]);
+    m_sessionWithoutCredentialStorage = [NSURLSession sessionWithConfiguration:configuration delegate:static_cast&lt;id&gt;(m_sessionWithoutCredentialStorageDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> NetworkSession::~NetworkSession()
</span><span class="cx"> {
</span><ins>+}
+
+void NetworkSession::invalidateAndCancel()
+{
</ins><span class="cx">     [m_sessionWithCredentialStorage invalidateAndCancel];
</span><span class="cx">     [m_sessionWithoutCredentialStorage invalidateAndCancel];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+
+WebCore::NetworkStorageSession&amp; NetworkSession::networkStorageSession()
+{
+    if (!m_networkStorageSession)
+        return WebCore::NetworkStorageSession::defaultStorageSession();
+    return *m_networkStorageSession;
+}
+
</ins><span class="cx"> #if !USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
</span><span class="cx"> void NetworkSession::clearCredentials()
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessmacRemoteNetworkingContextmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.mm (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.mm        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.mm        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -100,15 +100,14 @@
</span><span class="cx">     else
</span><span class="cx">         base = SessionTracker::getIdentifierBase();
</span><span class="cx"> 
</span><del>-    auto networkStorageSession = NetworkStorageSession::createPrivateBrowsingSession(base + '.' + String::number(sessionID.sessionID()));
</del><ins>+    auto networkStorageSession = NetworkStorageSession::createPrivateBrowsingSession(sessionID, base + '.' + String::number(sessionID.sessionID()));
+
</ins><span class="cx"> #if USE(NETWORK_SESSION)
</span><del>-    auto networkSession = std::make_unique&lt;NetworkSession&gt;(NetworkSession::Type::Ephemeral, sessionID, NetworkProcess::singleton().supplement&lt;CustomProtocolManager&gt;(), networkStorageSession.get());
</del><ins>+    auto networkSession = NetworkSession::create(NetworkSession::Type::Ephemeral, sessionID, NetworkProcess::singleton().supplement&lt;CustomProtocolManager&gt;(), WTFMove(networkStorageSession));
+    SessionTracker::setSession(sessionID, WTFMove(networkSession));
+#else
+    SessionTracker::setSession(sessionID, WTFMove(networkStorageSession));
</ins><span class="cx"> #endif
</span><del>-    SessionTracker::setSession(sessionID, WTFMove(networkStorageSession)
-#if USE(NETWORK_SESSION)
-        , WTFMove(networkSession)
-#endif
-    );
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedSessionTrackercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/SessionTracker.cpp (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/SessionTracker.cpp        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebKit2/Shared/SessionTracker.cpp        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -35,105 +35,108 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><del>-static HashMap&lt;SessionID, std::unique_ptr&lt;NetworkStorageSession&gt;&gt;&amp; staticStorageSessionMap()
</del><ins>+static String&amp; identifierBase()
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(RunLoop::isMain());
</span><span class="cx"> 
</span><del>-    static NeverDestroyed&lt;HashMap&lt;SessionID, std::unique_ptr&lt;NetworkStorageSession&gt;&gt;&gt; map;
-    return map;
</del><ins>+    static NeverDestroyed&lt;String&gt; base;
+    return base;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static HashMap&lt;const NetworkStorageSession*, SessionID&gt;&amp; storageSessionToID()
</del><ins>+const String&amp; SessionTracker::getIdentifierBase()
</ins><span class="cx"> {
</span><del>-    ASSERT(RunLoop::isMain());
-
-    static NeverDestroyed&lt;HashMap&lt;const NetworkStorageSession*, SessionID&gt;&gt; map;
-    return map;
</del><ins>+    return identifierBase();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static String&amp; identifierBase()
</del><ins>+void SessionTracker::setIdentifierBase(const String&amp; identifier)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(RunLoop::isMain());
</span><span class="cx"> 
</span><del>-    static NeverDestroyed&lt;String&gt; base;
-    return base;
</del><ins>+    identifierBase() = identifier;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-const HashMap&lt;SessionID, std::unique_ptr&lt;NetworkStorageSession&gt;&gt;&amp; SessionTracker::storageSessionMap()
</del><ins>+#if USE(NETWORK_SESSION)
+static HashMap&lt;SessionID, RefPtr&lt;NetworkSession&gt;&gt;&amp; staticSessionMap()
</ins><span class="cx"> {
</span><del>-    return staticStorageSessionMap();
</del><ins>+    ASSERT(RunLoop::isMain());
+
+    static NeverDestroyed&lt;HashMap&lt;SessionID, RefPtr&lt;NetworkSession&gt;&gt;&gt; map;
+    return map;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-const String&amp; SessionTracker::getIdentifierBase()
</del><ins>+NetworkSession* SessionTracker::networkSession(SessionID sessionID)
</ins><span class="cx"> {
</span><del>-    return identifierBase();
</del><ins>+    if (sessionID == SessionID::defaultSessionID())
+        return &amp;NetworkSession::defaultSession();
+    return staticSessionMap().get(sessionID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> NetworkStorageSession* SessionTracker::storageSession(SessionID sessionID)
</span><del>-{
-    if (sessionID == SessionID::defaultSessionID())
-        return &amp;NetworkStorageSession::defaultStorageSession();
-    return staticStorageSessionMap().get(sessionID);
</del><ins>+{    
+    auto session = SessionTracker::networkSession(sessionID);
+    if (!session)
+        return nullptr;
+    return &amp;session-&gt;networkStorageSession();
</ins><span class="cx"> }
</span><del>-
-#if USE(NETWORK_SESSION)
-static HashMap&lt;SessionID, std::unique_ptr&lt;NetworkSession&gt;&gt;&amp; staticSessionMap()
</del><ins>+#else
+static HashMap&lt;SessionID, std::unique_ptr&lt;NetworkStorageSession&gt;&gt;&amp; staticStorageSessionMap()
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(RunLoop::isMain());
</span><del>-    
-    static NeverDestroyed&lt;HashMap&lt;SessionID, std::unique_ptr&lt;NetworkSession&gt;&gt;&gt; map;
</del><ins>+
+    static NeverDestroyed&lt;HashMap&lt;SessionID, std::unique_ptr&lt;NetworkStorageSession&gt;&gt;&gt; map;
</ins><span class="cx">     return map;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-NetworkSession* SessionTracker::networkSession(SessionID sessionID)
</del><ins>+NetworkStorageSession* SessionTracker::storageSession(SessionID sessionID)
</ins><span class="cx"> {
</span><span class="cx">     if (sessionID == SessionID::defaultSessionID())
</span><del>-        return &amp;NetworkSession::defaultSession();
-    return staticSessionMap().get(sessionID);
</del><ins>+        return &amp;NetworkStorageSession::defaultStorageSession();
+    return staticStorageSessionMap().get(sessionID);
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> SessionID SessionTracker::sessionID(const NetworkStorageSession&amp; session)
</span><span class="cx"> {
</span><del>-    if (&amp;session == &amp;NetworkStorageSession::defaultStorageSession())
-        return SessionID::defaultSessionID();
-    return storageSessionToID().get(&amp;session);
</del><ins>+    return session.sessionID();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SessionTracker::setSession(SessionID sessionID, std::unique_ptr&lt;NetworkStorageSession&gt; storageSession
</del><span class="cx"> #if USE(NETWORK_SESSION)
</span><del>-    , std::unique_ptr&lt;NetworkSession&gt; session
-#endif
-)
</del><ins>+void SessionTracker::setSession(SessionID sessionID, Ref&lt;NetworkSession&gt;&amp;&amp; session)
</ins><span class="cx"> {
</span><ins>+    ASSERT(sessionID != SessionID::defaultSessionID());
+    staticSessionMap().set(sessionID, WTFMove(session));
+}
+#else
+void SessionTracker::setSession(SessionID sessionID, std::unique_ptr&lt;NetworkStorageSession&gt; storageSession)
+{
</ins><span class="cx">     ASSERT(storageSession);
</span><span class="cx">     ASSERT(sessionID != SessionID::defaultSessionID());
</span><del>-    storageSessionToID().set(storageSession.get(), sessionID);
</del><span class="cx">     staticStorageSessionMap().set(sessionID, WTFMove(storageSession));
</span><del>-#if USE(NETWORK_SESSION)
-    ASSERT(session);
-    staticSessionMap().set(sessionID, WTFMove(session));
</del><ins>+}
</ins><span class="cx"> #endif
</span><del>-}
</del><span class="cx"> 
</span><span class="cx"> void SessionTracker::destroySession(SessionID sessionID)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(RunLoop::isMain());
</span><del>-    if (staticStorageSessionMap().contains(sessionID)) {
</del><span class="cx"> #if USE(NETWORK_SESSION)
</span><del>-        ASSERT_WITH_MESSAGE(staticSessionMap().contains(sessionID), &quot;NetworkSessions and NetworkStorageSessions should always be created, deleted, and managed as pairs&quot;);
-        staticSessionMap().remove(sessionID);
</del><ins>+    auto session = staticSessionMap().take(sessionID);
+    if (session)
+        session-&gt;invalidateAndCancel();
+#else
+    staticStorageSessionMap().remove(sessionID);
</ins><span class="cx"> #endif
</span><del>-        storageSessionToID().remove(storageSession(sessionID));
-        staticStorageSessionMap().remove(sessionID);
-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SessionTracker::setIdentifierBase(const String&amp; identifier)
</del><ins>+void SessionTracker::forEachNetworkStorageSession(std::function&lt;void(const WebCore::NetworkStorageSession&amp;)&gt; functor)
</ins><span class="cx"> {
</span><del>-    ASSERT(RunLoop::isMain());
-
-    identifierBase() = identifier;
</del><ins>+#if USE(NETWORK_SESSION)
+    for (auto&amp; session : staticSessionMap().values())
+        functor(session-&gt;networkStorageSession());
+#else
+    for (auto&amp; networkStorageSession : staticStorageSessionMap().values())
+        functor(*networkStorageSession);
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedSessionTrackerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/SessionTracker.h (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/SessionTracker.h        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebKit2/Shared/SessionTracker.h        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -42,24 +42,28 @@
</span><span class="cx"> class SessionTracker {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(SessionTracker);
</span><span class="cx"> public:
</span><del>-    // FIXME: storageSessionMap()'s returned map does not include default session.
-    static const HashMap&lt;WebCore::SessionID, std::unique_ptr&lt;WebCore::NetworkStorageSession&gt;&gt;&amp; storageSessionMap();
</del><ins>+    static const String&amp; getIdentifierBase();
+    static void setIdentifierBase(const String&amp;);
</ins><span class="cx"> 
</span><del>-    static const String&amp; getIdentifierBase();
</del><span class="cx">     static WebCore::NetworkStorageSession* storageSession(WebCore::SessionID);
</span><ins>+    
+    // FIXME: Remove uses of this as it is just a member access into NetworkStorageSession.
</ins><span class="cx">     static WebCore::SessionID sessionID(const WebCore::NetworkStorageSession&amp;);
</span><del>-    static void setSession(WebCore::SessionID, std::unique_ptr&lt;WebCore::NetworkStorageSession&gt;
</del><ins>+
</ins><span class="cx"> #if USE(NETWORK_SESSION)
</span><del>-        , std::unique_ptr&lt;NetworkSession&gt;
</del><ins>+    static void setSession(WebCore::SessionID, Ref&lt;NetworkSession&gt;&amp;&amp;);
+#else
+    static void setSession(WebCore::SessionID, std::unique_ptr&lt;WebCore::NetworkStorageSession&gt;);
</ins><span class="cx"> #endif
</span><del>-    );
</del><span class="cx">     static void destroySession(WebCore::SessionID);
</span><del>-    static void setIdentifierBase(const String&amp;);
</del><span class="cx">     
</span><span class="cx"> #if USE(NETWORK_SESSION)
</span><span class="cx">     // FIXME: A NetworkSession and a NetworkStorageSession should be the same object once NETWORK_SESSION is used by default.
</span><span class="cx">     static NetworkSession* networkSession(WebCore::SessionID);
</span><span class="cx"> #endif
</span><ins>+
+    // FIXME: This does not include the default network storage sesion in it's iteration.
+    static void forEachNetworkStorageSession(std::function&lt;void(const WebCore::NetworkStorageSession&amp;)&gt;);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportmacWebFrameNetworkingContextmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebFrameNetworkingContext.mm (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebFrameNetworkingContext.mm        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebFrameNetworkingContext.mm        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -58,15 +58,13 @@
</span><span class="cx">     else
</span><span class="cx">         base = SessionTracker::getIdentifierBase();
</span><span class="cx"> 
</span><del>-    auto networkStorageSession = NetworkStorageSession::createPrivateBrowsingSession(base + '.' + String::number(sessionID.sessionID()));
</del><ins>+    auto networkStorageSession = NetworkStorageSession::createPrivateBrowsingSession(sessionID, base + '.' + String::number(sessionID.sessionID()));
</ins><span class="cx"> #if USE(NETWORK_SESSION)
</span><del>-    auto networkSession = std::make_unique&lt;NetworkSession&gt;(NetworkSession::Type::Ephemeral, sessionID, nullptr, networkStorageSession.get());
</del><ins>+    auto networkSession = NetworkSession::create(NetworkSession::Type::Ephemeral, sessionID, nullptr, WTFMove(networkStorageSession));
+    SessionTracker::setSession(sessionID, WTFMove(networkSession));
+#else
+    SessionTracker::setSession(sessionID, WTFMove(networkStorageSession));
</ins><span class="cx"> #endif
</span><del>-    SessionTracker::setSession(sessionID, WTFMove(networkStorageSession)
-#if USE(NETWORK_SESSION)
-        , WTFMove(networkSession)
-#endif
-    );
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebFrameNetworkingContext::setCookieAcceptPolicyForAllContexts(HTTPCookieAcceptPolicy policy)
</span><span class="lines">@@ -76,10 +74,9 @@
</span><span class="cx">     if (RetainPtr&lt;CFHTTPCookieStorageRef&gt; cookieStorage = NetworkStorageSession::defaultStorageSession().cookieStorage())
</span><span class="cx">         CFHTTPCookieStorageSetCookieAcceptPolicy(cookieStorage.get(), policy);
</span><span class="cx"> 
</span><del>-    for (const auto&amp; session : SessionTracker::storageSessionMap().values()) {
-        if (session)
-            CFHTTPCookieStorageSetCookieAcceptPolicy(session-&gt;cookieStorage().get(), policy);
-    }
</del><ins>+    SessionTracker::forEachNetworkStorageSession([&amp;] (const NetworkStorageSession&amp; networkStorageSession) {
+        CFHTTPCookieStorageSetCookieAcceptPolicy(networkStorageSession.cookieStorage().get(), policy);
+    });
</ins><span class="cx"> }
</span><span class="cx">     
</span><span class="cx"> bool WebFrameNetworkingContext::localFileContentSniffingEnabled() const
</span><span class="lines">@@ -90,7 +87,7 @@
</span><span class="cx"> SchedulePairHashSet* WebFrameNetworkingContext::scheduledRunLoopPairs() const
</span><span class="cx"> {
</span><span class="cx">     if (!frame() || !frame()-&gt;page())
</span><del>-        return 0;
</del><ins>+        return nullptr;
</ins><span class="cx">     return frame()-&gt;page()-&gt;scheduledRunLoopPairs();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportsoupWebFrameNetworkingContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp (198082 => 198083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp        2016-03-13 19:51:39 UTC (rev 198082)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp        2016-03-13 20:12:01 UTC (rev 198083)
</span><span class="lines">@@ -48,7 +48,7 @@
</span><span class="cx">     if (SessionTracker::storageSession(sessionID))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    SessionTracker::setSession(sessionID, NetworkStorageSession::createPrivateBrowsingSession(String::number(sessionID.sessionID())));
</del><ins>+    SessionTracker::setSession(sessionID, NetworkStorageSession::createPrivateBrowsingSession(sessionID, String::number(sessionID.sessionID())));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebFrameNetworkingContext::setCookieAcceptPolicyForAllContexts(HTTPCookieAcceptPolicy policy)
</span><span class="lines">@@ -72,10 +72,9 @@
</span><span class="cx">     SoupNetworkSession&amp; soupSession = NetworkStorageSession::defaultStorageSession().soupNetworkSession();
</span><span class="cx">     soup_cookie_jar_set_accept_policy(soupSession.cookieJar(), soupPolicy);
</span><span class="cx"> 
</span><del>-    for (const auto&amp; session : SessionTracker::storageSessionMap().values()) {
-        if (session)
-            soup_cookie_jar_set_accept_policy(session-&gt;soupNetworkSession().cookieJar(), soupPolicy);
-    }
</del><ins>+    SessionTracker::forEachNetworkStorageSession([&amp;] (const NetworkStorageSession&amp; session) {
+        soup_cookie_jar_set_accept_policy(session.soupNetworkSession().cookieJar(), soupPolicy);
+    });
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> WebFrameNetworkingContext::WebFrameNetworkingContext(WebFrame* frame)
</span></span></pre>
</div>
</div>

</body>
</html>