Title: [198083] trunk/Source
Revision
198083
Author
[email protected]
Date
2016-03-13 13:12:01 -0700 (Sun, 13 Mar 2016)

Log Message

WebKit can easily crash below NetworkSession::dataTaskForIdentifier() with NSURLSession enabled
<rdar://problem/25129946>
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):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (198082 => 198083)


--- 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)
@@ -1,3 +1,37 @@
+2016-03-12  Sam Weinig  <[email protected]>
+
+        WebKit can easily crash below NetworkSession::dataTaskForIdentifier() with NSURLSession enabled
+        <rdar://problem/25129946>
+        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):
+
 2016-03-13  Jon Lee  <[email protected]>
 
         getUserMedia requests from the main frame should be treated the same as requests from an iframe with the same origin

Modified: trunk/Source/WebCore/platform/network/NetworkStorageSession.h (198082 => 198083)


--- 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)
@@ -27,12 +27,12 @@
 #define NetworkStorageSession_h
 
 #include "CredentialStorage.h"
-
-#include <wtf/RetainPtr.h>
+#include "SessionID.h"
 #include <wtf/text/WTFString.h>
 
 #if PLATFORM(COCOA) || USE(CFNETWORK)
 #include "CFNetworkSPI.h"
+#include <wtf/RetainPtr.h>
 #endif
 
 namespace WebCore {
@@ -45,31 +45,36 @@
     WTF_MAKE_NONCOPYABLE(NetworkStorageSession); WTF_MAKE_FAST_ALLOCATED;
 public:
     WEBCORE_EXPORT static NetworkStorageSession& defaultStorageSession();
-    WEBCORE_EXPORT static std::unique_ptr<NetworkStorageSession> createPrivateBrowsingSession(const String& identifierBase = String());
+    WEBCORE_EXPORT static std::unique_ptr<NetworkStorageSession> createPrivateBrowsingSession(SessionID, const String& identifierBase = String());
 
     WEBCORE_EXPORT static void switchToNewTestingSession();
 
+    SessionID sessionID() const { return m_sessionID; }
     CredentialStorage& credentialStorage() { return m_credentialStorage; }
 
 #if PLATFORM(COCOA) || USE(CFNETWORK)
-    NetworkStorageSession(RetainPtr<CFURLStorageSessionRef>);
+    NetworkStorageSession(SessionID, RetainPtr<CFURLStorageSessionRef>);
+
     // May be null, in which case a Foundation default should be used.
     CFURLStorageSessionRef platformSession() { return m_platformSession.get(); }
     WEBCORE_EXPORT RetainPtr<CFHTTPCookieStorageRef> cookieStorage() const;
 #elif USE(SOUP)
-    NetworkStorageSession(std::unique_ptr<SoupNetworkSession>);
+    NetworkStorageSession(SessionID, std::unique_ptr<SoupNetworkSession>);
     ~NetworkStorageSession();
+
     SoupNetworkSession& soupNetworkSession() const;
     void setSoupNetworkSession(std::unique_ptr<SoupNetworkSession>);
 #else
-    NetworkStorageSession(NetworkingContext*);
+    NetworkStorageSession(SessionID, NetworkingContext*);
     ~NetworkStorageSession();
+
     NetworkingContext* context() const;
 #endif
 
 private:
+    SessionID m_sessionID;
+
 #if PLATFORM(COCOA) || USE(CFNETWORK)
-    NetworkStorageSession();
     RetainPtr<CFURLStorageSessionRef> m_platformSession;
 #elif USE(SOUP)
     std::unique_ptr<SoupNetworkSession> m_session;

Modified: trunk/Source/WebCore/platform/network/NetworkStorageSessionStub.cpp (198082 => 198083)


--- 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)
@@ -30,11 +30,13 @@
 #include "NetworkStorageSession.h"
 
 #include "NetworkingContext.h"
+#include <wtf/NeverDestroyed.h>
 
 namespace WebCore {
 
-NetworkStorageSession::NetworkStorageSession(NetworkingContext* context)
-    : m_context(context)
+NetworkStorageSession::NetworkStorageSession(SessionID sessionID, NetworkingContext* context)
+    : m_sessionID(sessionID)
+    , m_context(context)
 {
 }
 
@@ -47,18 +49,25 @@
     return m_context.get();
 }
 
-std::unique_ptr<NetworkStorageSession> NetworkStorageSession::createPrivateBrowsingSession(const String&)
+std::unique_ptr<NetworkStorageSession> NetworkStorageSession::createPrivateBrowsingSession(SessionID sessionID, const String&)
 {
     ASSERT_NOT_REACHED();
     return nullptr;
 }
 
-NetworkStorageSession& NetworkStorageSession::defaultStorageSession()
+static std::unique_ptr<NetworkStorageSession>& defaultSession()
 {
-    DEPRECATED_DEFINE_STATIC_LOCAL(NetworkStorageSession, session, (0));
+    static NeverDestroyed<std::unique_ptr<NetworkStorageSession>> session;
     return session;
 }
 
+NetworkStorageSession& NetworkStorageSession::defaultStorageSession()
+{
+    if (!defaultSession())
+        defaultSession() = std::make_unique<NetworkStorageSession>(SessionID::defaultSessionID(), nullptr);
+    return *defaultSession();
+}
+
 void NetworkStorageSession::switchToNewTestingSession()
 {
 }

Modified: trunk/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp (198082 => 198083)


--- 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)
@@ -41,8 +41,9 @@
 
 namespace WebCore {
 
-NetworkStorageSession::NetworkStorageSession(RetainPtr<CFURLStorageSessionRef> platformSession)
-    : m_platformSession(platformSession)
+NetworkStorageSession::NetworkStorageSession(SessionID sessionID, RetainPtr<CFURLStorageSessionRef> platformSession)
+    : m_sessionID(sessionID)
+    , m_platformSession(platformSession)
 {
 }
 
@@ -58,27 +59,27 @@
     // Session name should be short enough for shared memory region name to be under the limit, otehrwise sandbox rules won't work (see <rdar://problem/13642852>).
     String sessionName = String::format("WebKit Test-%u", static_cast<uint32_t>(getCurrentProcessID()));
 #if PLATFORM(COCOA)
-    defaultNetworkStorageSession() = std::make_unique<NetworkStorageSession>(adoptCF(wkCreatePrivateStorageSession(sessionName.createCFString().get())));
+    defaultNetworkStorageSession() = std::make_unique<NetworkStorageSession>(SessionID::defaultSessionID(), adoptCF(wkCreatePrivateStorageSession(sessionName.createCFString().get())));
 #else
-    defaultNetworkStorageSession() = std::make_unique<NetworkStorageSession>(adoptCF(wkCreatePrivateStorageSession(sessionName.createCFString().get(), defaultNetworkStorageSession()->platformSession())));
+    defaultNetworkStorageSession() = std::make_unique<NetworkStorageSession>(SessionID::defaultSessionID(), adoptCF(wkCreatePrivateStorageSession(sessionName.createCFString().get(), defaultNetworkStorageSession()->platformSession())));
 #endif
 }
 
 NetworkStorageSession& NetworkStorageSession::defaultStorageSession()
 {
     if (!defaultNetworkStorageSession())
-        defaultNetworkStorageSession() = std::make_unique<NetworkStorageSession>(nullptr);
+        defaultNetworkStorageSession() = std::make_unique<NetworkStorageSession>(SessionID::defaultSessionID(), nullptr);
     return *defaultNetworkStorageSession();
 }
 
-std::unique_ptr<NetworkStorageSession> NetworkStorageSession::createPrivateBrowsingSession(const String& identifierBase)
+std::unique_ptr<NetworkStorageSession> NetworkStorageSession::createPrivateBrowsingSession(SessionID sessionID, const String& identifierBase)
 {
     RetainPtr<CFStringRef> cfIdentifier = String(identifierBase + ".PrivateBrowsing").createCFString();
 
 #if PLATFORM(COCOA)
-    auto session = std::make_unique<NetworkStorageSession>(adoptCF(wkCreatePrivateStorageSession(cfIdentifier.get())));
+    auto session = std::make_unique<NetworkStorageSession>(sessionID, adoptCF(wkCreatePrivateStorageSession(cfIdentifier.get())));
 #else
-    auto session = std::make_unique<NetworkStorageSession>(adoptCF(wkCreatePrivateStorageSession(cfIdentifier.get(), defaultNetworkStorageSession()->platformSession())));
+    auto session = std::make_unique<NetworkStorageSession>(sessionID, adoptCF(wkCreatePrivateStorageSession(cfIdentifier.get(), defaultNetworkStorageSession()->platformSession())));
 #endif
 
     return session;

Modified: trunk/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp (198082 => 198083)


--- 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)
@@ -36,8 +36,9 @@
 
 namespace WebCore {
 
-NetworkStorageSession::NetworkStorageSession(std::unique_ptr<SoupNetworkSession> session)
-    : m_session(WTFMove(session))
+NetworkStorageSession::NetworkStorageSession(SessionID sessionID, std::unique_ptr<SoupNetworkSession> session)
+    : m_sessionID(sessionID)
+    , m_session(WTFMove(session))
 {
 }
 
@@ -55,19 +56,19 @@
 NetworkStorageSession& NetworkStorageSession::defaultStorageSession()
 {
     if (!defaultSession())
-        defaultSession() = std::make_unique<NetworkStorageSession>(nullptr);
+        defaultSession() = std::make_unique<NetworkStorageSession>(SessionID::defaultSessionID(), nullptr);
     return *defaultSession();
 }
 
-std::unique_ptr<NetworkStorageSession> NetworkStorageSession::createPrivateBrowsingSession(const String&)
+std::unique_ptr<NetworkStorageSession> NetworkStorageSession::createPrivateBrowsingSession(SessionID sessionID, const String&)
 {
-    auto session = std::make_unique<NetworkStorageSession>(SoupNetworkSession::createPrivateBrowsingSession());
+    auto session = std::make_unique<NetworkStorageSession>(sessionID, SoupNetworkSession::createPrivateBrowsingSession());
     return session;
 }
 
 void NetworkStorageSession::switchToNewTestingSession()
 {
-    defaultSession() = std::make_unique<NetworkStorageSession>(SoupNetworkSession::createTestingSession());
+    defaultSession() = std::make_unique<NetworkStorageSession>(SessionID::defaultSessionID(), SoupNetworkSession::createTestingSession());
 }
 
 SoupNetworkSession& NetworkStorageSession::soupNetworkSession() const

Modified: trunk/Source/WebKit/mac/ChangeLog (198082 => 198083)


--- 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)
@@ -1,3 +1,15 @@
+2016-03-12  Sam Weinig  <[email protected]>
+
+        WebKit can easily crash below NetworkSession::dataTaskForIdentifier() with NSURLSession enabled
+        <rdar://problem/25129946>
+        https://bugs.webkit.org/show_bug.cgi?id=155401
+
+        Reviewed by Alex Christensen.
+
+        * WebCoreSupport/WebFrameNetworkingContext.mm:
+        (WebFrameNetworkingContext::ensurePrivateBrowsingSession):
+        Pass a SessionID to NetworkStorageSession::createPrivateBrowsingSession().
+
 2016-03-12  Myles C. Maxfield  <[email protected]>
 
         Delete dead SVG Font code

Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebFrameNetworkingContext.mm (198082 => 198083)


--- 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)
@@ -33,6 +33,7 @@
 #import <WebCore/NetworkStorageSession.h>
 #import <WebCore/Page.h>
 #import <WebCore/ResourceError.h>
+#import <WebCore/SessionID.h>
 #import <WebCore/Settings.h>
 #import <wtf/NeverDestroyed.h>
 
@@ -56,7 +57,7 @@
     if (privateSession())
         return;
 
-    privateSession() = NetworkStorageSession::createPrivateBrowsingSession([[NSBundle mainBundle] bundleIdentifier]);
+    privateSession() = NetworkStorageSession::createPrivateBrowsingSession(SessionID::legacyPrivateSessionID(), [[NSBundle mainBundle] bundleIdentifier]);
 }
 
 void WebFrameNetworkingContext::destroyPrivateBrowsingSession()

Modified: trunk/Source/WebKit/win/ChangeLog (198082 => 198083)


--- 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)
@@ -1,3 +1,15 @@
+2016-03-12  Sam Weinig  <[email protected]>
+
+        WebKit can easily crash below NetworkSession::dataTaskForIdentifier() with NSURLSession enabled
+        <rdar://problem/25129946>
+        https://bugs.webkit.org/show_bug.cgi?id=155401
+
+        Reviewed by Alex Christensen.
+
+        * WebCoreSupport/WebFrameNetworkingContext.cpp:
+        (WebFrameNetworkingContext::ensurePrivateBrowsingSession):
+        Pass a SessionID to NetworkStorageSession::createPrivateBrowsingSession().
+
 2016-03-10  Jer Noble  <[email protected]>
 
         Unreviewed build fix after r197953; correct the settings added in r197953.

Modified: trunk/Source/WebKit/win/WebCoreSupport/WebFrameNetworkingContext.cpp (198082 => 198083)


--- 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)
@@ -87,7 +87,7 @@
     } else
         base = identifierBase();
 
-    privateSession() = NetworkStorageSession::createPrivateBrowsingSession(base);
+    privateSession() = NetworkStorageSession::createPrivateBrowsingSession(SessionID::legacyPrivateSessionID(), base);
 #endif
 }
 

Modified: trunk/Source/WebKit2/ChangeLog (198082 => 198083)


--- 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)
@@ -1,3 +1,76 @@
+2016-03-12  Sam Weinig  <[email protected]>
+
+        WebKit can easily crash below NetworkSession::dataTaskForIdentifier() with NSURLSession enabled
+        <rdar://problem/25129946>
+        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):
+
 2016-03-12  Myles C. Maxfield  <[email protected]>
 
         Delete dead SVG Font code

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h (198082 => 198083)


--- 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)
@@ -121,6 +121,7 @@
     }
     void setPendingDownloadLocation(const String& filename, const SandboxExtension::Handle&);
     const String& pendingDownloadLocation() { return m_pendingDownloadLocation; }
+
     WebCore::ResourceRequest currentRequest();
     String suggestedFilename();
     void willPerformHTTPRedirection(const WebCore::ResourceResponse&, WebCore::ResourceRequest&&, RedirectCompletionHandler);
@@ -141,7 +142,7 @@
     void failureTimerFired();
     void scheduleFailure(FailureType);
     
-    NetworkSession& m_session;
+    RefPtr<NetworkSession> m_session;
     NetworkDataTaskClient* m_client;
     PendingDownload* m_pendingDownload { nullptr };
     DownloadID m_pendingDownloadID;

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp (198082 => 198083)


--- 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)
@@ -58,7 +58,7 @@
         if (!parameters.defersLoading)
             m_task->resume();
     } else
-        ASSERT_NOT_REACHED();
+        WTFLogAlways("Attempted to create a NetworkLoad with a session (id=%" PRIu64 ") that does not exist.", parameters.sessionID.sessionID());
 #else
     m_handle = ResourceHandle::create(m_networkingContext.get(), parameters.request, this, parameters.defersLoading, parameters.contentSniffingPolicy == SniffContent);
 #endif

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkSession.h (198082 => 198083)


--- 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)
@@ -47,19 +47,25 @@
 
 class CustomProtocolManager;
 
-class NetworkSession {
+class NetworkSession : public RefCounted<NetworkSession> {
     friend class NetworkDataTask;
 public:
     enum class Type {
         Normal,
         Ephemeral
     };
-    NetworkSession(Type, WebCore::SessionID, CustomProtocolManager*, WebCore::NetworkStorageSession*);
+
+    static Ref<NetworkSession> create(Type, WebCore::SessionID, CustomProtocolManager*, std::unique_ptr<WebCore::NetworkStorageSession>);
+    static NetworkSession& defaultSession();
     ~NetworkSession();
 
-    WebCore::SessionID sessionID() { return m_sessionID; }
+    void invalidateAndCancel();
+
+    WebCore::SessionID sessionID() const { return m_sessionID; }
+    WebCore::NetworkStorageSession& networkStorageSession();
+
     static void setCustomProtocolManager(CustomProtocolManager*);
-    static NetworkSession& defaultSession();
+
 #if !USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
     void clearCredentials();
 #endif
@@ -71,14 +77,20 @@
     DownloadID takeDownloadID(NetworkDataTask::TaskIdentifier);
     
 private:
+    NetworkSession(Type, WebCore::SessionID, CustomProtocolManager*, std::unique_ptr<WebCore::NetworkStorageSession>);
+
     WebCore::SessionID m_sessionID;
+    std::unique_ptr<WebCore::NetworkStorageSession> m_networkStorageSession;
+
     HashMap<NetworkDataTask::TaskIdentifier, NetworkDataTask*> m_dataTaskMapWithCredentials;
     HashMap<NetworkDataTask::TaskIdentifier, NetworkDataTask*> m_dataTaskMapWithoutCredentials;
     HashMap<NetworkDataTask::TaskIdentifier, DownloadID> m_downloadMap;
+
 #if PLATFORM(COCOA)
     RetainPtr<NSURLSession> m_sessionWithCredentialStorage;
+    RetainPtr<WKNetworkSessionDelegate> m_sessionWithCredentialStorageDelegate;
     RetainPtr<NSURLSession> m_sessionWithoutCredentialStorage;
-    RetainPtr<WKNetworkSessionDelegate> m_sessionDelegate;
+    RetainPtr<WKNetworkSessionDelegate> m_sessionWithoutCredentialStorageDelegate;
 #endif
 };
 

Modified: trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm (198082 => 198083)


--- 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)
@@ -51,7 +51,7 @@
 
 NetworkDataTask::NetworkDataTask(NetworkSession& session, NetworkDataTaskClient& client, const WebCore::ResourceRequest& requestWithCredentials, WebCore::StoredCredentials storedCredentials, WebCore::ContentSniffingPolicy shouldContentSniff, bool shouldClearReferrerOnHTTPSToHTTPRedirect)
     : m_failureTimer(*this, &NetworkDataTask::failureTimerFired)
-    , m_session(session)
+    , m_session(&session)
     , m_client(&client)
     , m_storedCredentials(storedCredentials)
     , m_lastHTTPMethod(requestWithCredentials.httpMethod())
@@ -79,13 +79,10 @@
         url = ""
     
 #if USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
-        if (auto storageSession = SessionTracker::storageSession(m_session.sessionID())) {
-            if (m_user.isEmpty() && m_password.isEmpty())
-                m_initialCredential = storageSession->credentialStorage().get(url);
-            else
-                storageSession->credentialStorage().set(WebCore::Credential(m_user, m_password, WebCore::CredentialPersistenceNone), url);
-        } else
-            ASSERT_NOT_REACHED();
+        if (m_user.isEmpty() && m_password.isEmpty())
+            m_initialCredential = m_session->networkStorageSession().credentialStorage().get(url);
+        else
+            m_session->networkStorageSession().credentialStorage().set(WebCore::Credential(m_user, m_password, WebCore::CredentialPersistenceNone), url);
 #endif
     }
 
@@ -104,13 +101,13 @@
     }
 
     if (storedCredentials == WebCore::AllowStoredCredentials) {
-        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);
+        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);
     } else {
-        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);
+        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);
     }
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
@@ -125,11 +122,11 @@
     ASSERT(isMainThread());
     if (m_task) {
         if (m_storedCredentials == WebCore::StoredCredentials::AllowStoredCredentials) {
-            ASSERT(m_session.m_dataTaskMapWithCredentials.get([m_task taskIdentifier]) == this);
-            m_session.m_dataTaskMapWithCredentials.remove([m_task taskIdentifier]);
+            ASSERT(m_session->m_dataTaskMapWithCredentials.get([m_task taskIdentifier]) == this);
+            m_session->m_dataTaskMapWithCredentials.remove([m_task taskIdentifier]);
         } else {
-            ASSERT(m_session.m_dataTaskMapWithoutCredentials.get([m_task taskIdentifier]) == this);
-            m_session.m_dataTaskMapWithoutCredentials.remove([m_task taskIdentifier]);
+            ASSERT(m_session->m_dataTaskMapWithoutCredentials.get([m_task taskIdentifier]) == this);
+            m_session->m_dataTaskMapWithoutCredentials.remove([m_task taskIdentifier]);
         }
     }
 }
@@ -221,16 +218,13 @@
         // Only consider applying authentication credentials if this is actually a redirect and the redirect
         // URL didn't include credentials of its own.
         if (m_user.isEmpty() && m_password.isEmpty() && !redirectResponse.isNull()) {
-            if (auto storageSession = SessionTracker::storageSession(m_session.sessionID())) {
-                auto credential = storageSession->credentialStorage().get(request.url());
-                if (!credential.isEmpty()) {
-                    m_initialCredential = credential;
+            auto credential = m_session->networkStorageSession().credentialStorage().get(request.url());
+            if (!credential.isEmpty()) {
+                m_initialCredential = credential;
 
-                    // FIXME: Support Digest authentication, and Proxy-Authorization.
-                    applyBasicAuthorizationHeader(request, m_initialCredential);
-                }
-            } else
-                ASSERT_NOT_REACHED();
+                // FIXME: Support Digest authentication, and Proxy-Authorization.
+                applyBasicAuthorizationHeader(request, m_initialCredential);
+            }
         }
 #endif
     }
@@ -298,28 +292,25 @@
 
 #if USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
     if (m_storedCredentials == WebCore::AllowStoredCredentials) {
-        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->credentialStorage().remove(challenge.protectionSpace());
-            }
+        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->networkStorageSession().credentialStorage().remove(challenge.protectionSpace());
+        }
 
-            if (!challenge.previousFailureCount()) {
-                auto credential = storageSession->credentialStorage().get(challenge.protectionSpace());
-                if (!credential.isEmpty() && 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->credentialStorage().set(credential, challenge.protectionSpace(), challenge.failureResponse().url());
-                    }
-                    completionHandler(AuthenticationChallengeDisposition::UseCredential, credential);
-                    return true;
+        if (!challenge.previousFailureCount()) {
+            auto credential = m_session->networkStorageSession().credentialStorage().get(challenge.protectionSpace());
+            if (!credential.isEmpty() && 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->networkStorageSession().credentialStorage().set(credential, challenge.protectionSpace(), challenge.failureResponse().url());
                 }
+                completionHandler(AuthenticationChallengeDisposition::UseCredential, credential);
+                return true;
             }
-        } else
-            ASSERT_NOT_REACHED();
+        }
     }
 #endif
 

Modified: trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm (198082 => 198083)


--- 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)
@@ -77,7 +77,8 @@
 }
 
 @interface WKNetworkSessionDelegate : NSObject <NSURLSessionDataDelegate> {
-    WebKit::NetworkSession* _session;
+    RefPtr<WebKit::NetworkSession> _session;
+    bool _sessionDestroyed;
 }
 
 - (id)initWithNetworkSession:(WebKit::NetworkSession&)session;
@@ -97,6 +98,11 @@
     return self;
 }
 
+- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable NSError *)error
+{
+    _session = nullptr;
+}
+
 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
 {
     auto storedCredentials = session.configuration.URLCredentialStorage ? WebCore::StoredCredentials::AllowStoredCredentials : WebCore::StoredCredentials::DoNotAllowStoredCredentials;
@@ -265,17 +271,23 @@
     globalCustomProtocolManager() = customProtocolManager;
 }
 
+Ref<NetworkSession> NetworkSession::create(Type type, WebCore::SessionID sessionID, CustomProtocolManager* customProtocolManager, std::unique_ptr<WebCore::NetworkStorageSession> networkStorageSession)
+{
+    return adoptRef(*new NetworkSession(type, sessionID, customProtocolManager, WTFMove(networkStorageSession)));
+}
+
 NetworkSession& NetworkSession::defaultSession()
 {
     ASSERT(isMainThread());
-    static NeverDestroyed<NetworkSession> session(NetworkSession::Type::Normal, WebCore::SessionID::defaultSessionID(), globalCustomProtocolManager().get(), &WebCore::NetworkStorageSession::defaultStorageSession());
-    return session;
+    static NetworkSession* session = &NetworkSession::create(NetworkSession::Type::Normal, WebCore::SessionID::defaultSessionID(), globalCustomProtocolManager().get(), nullptr).leakRef();
+    return *session;
 }
 
-NetworkSession::NetworkSession(Type type, WebCore::SessionID sessionID, CustomProtocolManager* customProtocolManager, WebCore::NetworkStorageSession* networkStorageSession)
+NetworkSession::NetworkSession(Type type, WebCore::SessionID sessionID, CustomProtocolManager* customProtocolManager, std::unique_ptr<WebCore::NetworkStorageSession> networkStorageSession)
     : m_sessionID(sessionID)
+    , m_networkStorageSession(WTFMove(networkStorageSession))
 {
-    m_sessionDelegate = adoptNS([[WKNetworkSessionDelegate alloc] initWithNetworkSession:*this]);
+    relaxAdoptionRequirement();
 
     NSURLSessionConfiguration *configuration = configurationForType(type);
 
@@ -288,21 +300,42 @@
     setCollectsTimingData();
 #endif
 
-    if (networkStorageSession) {
-        if (CFHTTPCookieStorageRef storage = networkStorageSession->cookieStorage().get())
+    if (m_networkStorageSession) {
+        ASSERT(type == Type::Ephemeral);
+        if (CFHTTPCookieStorageRef storage = m_networkStorageSession->cookieStorage().get())
             configuration.HTTPCookieStorage = [[[NSHTTPCookieStorage alloc] _initWithCFHTTPCookieStorage:storage] autorelease];
+    } else {
+        ASSERT(type == Type::Normal);
+        if (CFHTTPCookieStorageRef storage = WebCore::NetworkStorageSession::defaultStorageSession().cookieStorage().get())
+            configuration.HTTPCookieStorage = [[[NSHTTPCookieStorage alloc] _initWithCFHTTPCookieStorage:storage] autorelease];
     }
-    m_sessionWithCredentialStorage = [NSURLSession sessionWithConfiguration:configuration delegate:static_cast<id>(m_sessionDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
+
+    m_sessionWithCredentialStorageDelegate = adoptNS([[WKNetworkSessionDelegate alloc] initWithNetworkSession:*this]);
+    m_sessionWithCredentialStorage = [NSURLSession sessionWithConfiguration:configuration delegate:static_cast<id>(m_sessionWithCredentialStorageDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
+
     configuration.URLCredentialStorage = nil;
-    m_sessionWithoutCredentialStorage = [NSURLSession sessionWithConfiguration:configuration delegate:static_cast<id>(m_sessionDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
+    m_sessionWithoutCredentialStorageDelegate = adoptNS([[WKNetworkSessionDelegate alloc] initWithNetworkSession:*this]);
+    m_sessionWithoutCredentialStorage = [NSURLSession sessionWithConfiguration:configuration delegate:static_cast<id>(m_sessionWithoutCredentialStorageDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
 }
 
 NetworkSession::~NetworkSession()
 {
+}
+
+void NetworkSession::invalidateAndCancel()
+{
     [m_sessionWithCredentialStorage invalidateAndCancel];
     [m_sessionWithoutCredentialStorage invalidateAndCancel];
 }
 
+
+WebCore::NetworkStorageSession& NetworkSession::networkStorageSession()
+{
+    if (!m_networkStorageSession)
+        return WebCore::NetworkStorageSession::defaultStorageSession();
+    return *m_networkStorageSession;
+}
+
 #if !USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
 void NetworkSession::clearCredentials()
 {

Modified: trunk/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.mm (198082 => 198083)


--- 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)
@@ -100,15 +100,14 @@
     else
         base = SessionTracker::getIdentifierBase();
 
-    auto networkStorageSession = NetworkStorageSession::createPrivateBrowsingSession(base + '.' + String::number(sessionID.sessionID()));
+    auto networkStorageSession = NetworkStorageSession::createPrivateBrowsingSession(sessionID, base + '.' + String::number(sessionID.sessionID()));
+
 #if USE(NETWORK_SESSION)
-    auto networkSession = std::make_unique<NetworkSession>(NetworkSession::Type::Ephemeral, sessionID, NetworkProcess::singleton().supplement<CustomProtocolManager>(), networkStorageSession.get());
+    auto networkSession = NetworkSession::create(NetworkSession::Type::Ephemeral, sessionID, NetworkProcess::singleton().supplement<CustomProtocolManager>(), WTFMove(networkStorageSession));
+    SessionTracker::setSession(sessionID, WTFMove(networkSession));
+#else
+    SessionTracker::setSession(sessionID, WTFMove(networkStorageSession));
 #endif
-    SessionTracker::setSession(sessionID, WTFMove(networkStorageSession)
-#if USE(NETWORK_SESSION)
-        , WTFMove(networkSession)
-#endif
-    );
 }
 
 }

Modified: trunk/Source/WebKit2/Shared/SessionTracker.cpp (198082 => 198083)


--- 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)
@@ -35,105 +35,108 @@
 
 namespace WebKit {
 
-static HashMap<SessionID, std::unique_ptr<NetworkStorageSession>>& staticStorageSessionMap()
+static String& identifierBase()
 {
     ASSERT(RunLoop::isMain());
 
-    static NeverDestroyed<HashMap<SessionID, std::unique_ptr<NetworkStorageSession>>> map;
-    return map;
+    static NeverDestroyed<String> base;
+    return base;
 }
 
-static HashMap<const NetworkStorageSession*, SessionID>& storageSessionToID()
+const String& SessionTracker::getIdentifierBase()
 {
-    ASSERT(RunLoop::isMain());
-
-    static NeverDestroyed<HashMap<const NetworkStorageSession*, SessionID>> map;
-    return map;
+    return identifierBase();
 }
 
-static String& identifierBase()
+void SessionTracker::setIdentifierBase(const String& identifier)
 {
     ASSERT(RunLoop::isMain());
 
-    static NeverDestroyed<String> base;
-    return base;
+    identifierBase() = identifier;
 }
 
-const HashMap<SessionID, std::unique_ptr<NetworkStorageSession>>& SessionTracker::storageSessionMap()
+#if USE(NETWORK_SESSION)
+static HashMap<SessionID, RefPtr<NetworkSession>>& staticSessionMap()
 {
-    return staticStorageSessionMap();
+    ASSERT(RunLoop::isMain());
+
+    static NeverDestroyed<HashMap<SessionID, RefPtr<NetworkSession>>> map;
+    return map;
 }
 
-const String& SessionTracker::getIdentifierBase()
+NetworkSession* SessionTracker::networkSession(SessionID sessionID)
 {
-    return identifierBase();
+    if (sessionID == SessionID::defaultSessionID())
+        return &NetworkSession::defaultSession();
+    return staticSessionMap().get(sessionID);
 }
 
 NetworkStorageSession* SessionTracker::storageSession(SessionID sessionID)
-{
-    if (sessionID == SessionID::defaultSessionID())
-        return &NetworkStorageSession::defaultStorageSession();
-    return staticStorageSessionMap().get(sessionID);
+{    
+    auto session = SessionTracker::networkSession(sessionID);
+    if (!session)
+        return nullptr;
+    return &session->networkStorageSession();
 }
-
-#if USE(NETWORK_SESSION)
-static HashMap<SessionID, std::unique_ptr<NetworkSession>>& staticSessionMap()
+#else
+static HashMap<SessionID, std::unique_ptr<NetworkStorageSession>>& staticStorageSessionMap()
 {
     ASSERT(RunLoop::isMain());
-    
-    static NeverDestroyed<HashMap<SessionID, std::unique_ptr<NetworkSession>>> map;
+
+    static NeverDestroyed<HashMap<SessionID, std::unique_ptr<NetworkStorageSession>>> map;
     return map;
 }
 
-NetworkSession* SessionTracker::networkSession(SessionID sessionID)
+NetworkStorageSession* SessionTracker::storageSession(SessionID sessionID)
 {
     if (sessionID == SessionID::defaultSessionID())
-        return &NetworkSession::defaultSession();
-    return staticSessionMap().get(sessionID);
+        return &NetworkStorageSession::defaultStorageSession();
+    return staticStorageSessionMap().get(sessionID);
 }
 #endif
 
 SessionID SessionTracker::sessionID(const NetworkStorageSession& session)
 {
-    if (&session == &NetworkStorageSession::defaultStorageSession())
-        return SessionID::defaultSessionID();
-    return storageSessionToID().get(&session);
+    return session.sessionID();
 }
 
-void SessionTracker::setSession(SessionID sessionID, std::unique_ptr<NetworkStorageSession> storageSession
 #if USE(NETWORK_SESSION)
-    , std::unique_ptr<NetworkSession> session
-#endif
-)
+void SessionTracker::setSession(SessionID sessionID, Ref<NetworkSession>&& session)
 {
+    ASSERT(sessionID != SessionID::defaultSessionID());
+    staticSessionMap().set(sessionID, WTFMove(session));
+}
+#else
+void SessionTracker::setSession(SessionID sessionID, std::unique_ptr<NetworkStorageSession> storageSession)
+{
     ASSERT(storageSession);
     ASSERT(sessionID != SessionID::defaultSessionID());
-    storageSessionToID().set(storageSession.get(), sessionID);
     staticStorageSessionMap().set(sessionID, WTFMove(storageSession));
-#if USE(NETWORK_SESSION)
-    ASSERT(session);
-    staticSessionMap().set(sessionID, WTFMove(session));
+}
 #endif
-}
 
 void SessionTracker::destroySession(SessionID sessionID)
 {
     ASSERT(RunLoop::isMain());
-    if (staticStorageSessionMap().contains(sessionID)) {
 #if USE(NETWORK_SESSION)
-        ASSERT_WITH_MESSAGE(staticSessionMap().contains(sessionID), "NetworkSessions and NetworkStorageSessions should always be created, deleted, and managed as pairs");
-        staticSessionMap().remove(sessionID);
+    auto session = staticSessionMap().take(sessionID);
+    if (session)
+        session->invalidateAndCancel();
+#else
+    staticStorageSessionMap().remove(sessionID);
 #endif
-        storageSessionToID().remove(storageSession(sessionID));
-        staticStorageSessionMap().remove(sessionID);
-    }
 }
 
-void SessionTracker::setIdentifierBase(const String& identifier)
+void SessionTracker::forEachNetworkStorageSession(std::function<void(const WebCore::NetworkStorageSession&)> functor)
 {
-    ASSERT(RunLoop::isMain());
-
-    identifierBase() = identifier;
+#if USE(NETWORK_SESSION)
+    for (auto& session : staticSessionMap().values())
+        functor(session->networkStorageSession());
+#else
+    for (auto& networkStorageSession : staticStorageSessionMap().values())
+        functor(*networkStorageSession);
+#endif
 }
 
+
 } // namespace WebKit

Modified: trunk/Source/WebKit2/Shared/SessionTracker.h (198082 => 198083)


--- 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)
@@ -42,24 +42,28 @@
 class SessionTracker {
     WTF_MAKE_NONCOPYABLE(SessionTracker);
 public:
-    // FIXME: storageSessionMap()'s returned map does not include default session.
-    static const HashMap<WebCore::SessionID, std::unique_ptr<WebCore::NetworkStorageSession>>& storageSessionMap();
+    static const String& getIdentifierBase();
+    static void setIdentifierBase(const String&);
 
-    static const String& getIdentifierBase();
     static WebCore::NetworkStorageSession* storageSession(WebCore::SessionID);
+    
+    // FIXME: Remove uses of this as it is just a member access into NetworkStorageSession.
     static WebCore::SessionID sessionID(const WebCore::NetworkStorageSession&);
-    static void setSession(WebCore::SessionID, std::unique_ptr<WebCore::NetworkStorageSession>
+
 #if USE(NETWORK_SESSION)
-        , std::unique_ptr<NetworkSession>
+    static void setSession(WebCore::SessionID, Ref<NetworkSession>&&);
+#else
+    static void setSession(WebCore::SessionID, std::unique_ptr<WebCore::NetworkStorageSession>);
 #endif
-    );
     static void destroySession(WebCore::SessionID);
-    static void setIdentifierBase(const String&);
     
 #if USE(NETWORK_SESSION)
     // FIXME: A NetworkSession and a NetworkStorageSession should be the same object once NETWORK_SESSION is used by default.
     static NetworkSession* networkSession(WebCore::SessionID);
 #endif
+
+    // FIXME: This does not include the default network storage sesion in it's iteration.
+    static void forEachNetworkStorageSession(std::function<void(const WebCore::NetworkStorageSession&)>);
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebFrameNetworkingContext.mm (198082 => 198083)


--- 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)
@@ -58,15 +58,13 @@
     else
         base = SessionTracker::getIdentifierBase();
 
-    auto networkStorageSession = NetworkStorageSession::createPrivateBrowsingSession(base + '.' + String::number(sessionID.sessionID()));
+    auto networkStorageSession = NetworkStorageSession::createPrivateBrowsingSession(sessionID, base + '.' + String::number(sessionID.sessionID()));
 #if USE(NETWORK_SESSION)
-    auto networkSession = std::make_unique<NetworkSession>(NetworkSession::Type::Ephemeral, sessionID, nullptr, networkStorageSession.get());
+    auto networkSession = NetworkSession::create(NetworkSession::Type::Ephemeral, sessionID, nullptr, WTFMove(networkStorageSession));
+    SessionTracker::setSession(sessionID, WTFMove(networkSession));
+#else
+    SessionTracker::setSession(sessionID, WTFMove(networkStorageSession));
 #endif
-    SessionTracker::setSession(sessionID, WTFMove(networkStorageSession)
-#if USE(NETWORK_SESSION)
-        , WTFMove(networkSession)
-#endif
-    );
 }
 
 void WebFrameNetworkingContext::setCookieAcceptPolicyForAllContexts(HTTPCookieAcceptPolicy policy)
@@ -76,10 +74,9 @@
     if (RetainPtr<CFHTTPCookieStorageRef> cookieStorage = NetworkStorageSession::defaultStorageSession().cookieStorage())
         CFHTTPCookieStorageSetCookieAcceptPolicy(cookieStorage.get(), policy);
 
-    for (const auto& session : SessionTracker::storageSessionMap().values()) {
-        if (session)
-            CFHTTPCookieStorageSetCookieAcceptPolicy(session->cookieStorage().get(), policy);
-    }
+    SessionTracker::forEachNetworkStorageSession([&] (const NetworkStorageSession& networkStorageSession) {
+        CFHTTPCookieStorageSetCookieAcceptPolicy(networkStorageSession.cookieStorage().get(), policy);
+    });
 }
     
 bool WebFrameNetworkingContext::localFileContentSniffingEnabled() const
@@ -90,7 +87,7 @@
 SchedulePairHashSet* WebFrameNetworkingContext::scheduledRunLoopPairs() const
 {
     if (!frame() || !frame()->page())
-        return 0;
+        return nullptr;
     return frame()->page()->scheduledRunLoopPairs();
 }
 

Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp (198082 => 198083)


--- 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)
@@ -48,7 +48,7 @@
     if (SessionTracker::storageSession(sessionID))
         return;
 
-    SessionTracker::setSession(sessionID, NetworkStorageSession::createPrivateBrowsingSession(String::number(sessionID.sessionID())));
+    SessionTracker::setSession(sessionID, NetworkStorageSession::createPrivateBrowsingSession(sessionID, String::number(sessionID.sessionID())));
 }
 
 void WebFrameNetworkingContext::setCookieAcceptPolicyForAllContexts(HTTPCookieAcceptPolicy policy)
@@ -72,10 +72,9 @@
     SoupNetworkSession& soupSession = NetworkStorageSession::defaultStorageSession().soupNetworkSession();
     soup_cookie_jar_set_accept_policy(soupSession.cookieJar(), soupPolicy);
 
-    for (const auto& session : SessionTracker::storageSessionMap().values()) {
-        if (session)
-            soup_cookie_jar_set_accept_policy(session->soupNetworkSession().cookieJar(), soupPolicy);
-    }
+    SessionTracker::forEachNetworkStorageSession([&] (const NetworkStorageSession& session) {
+        soup_cookie_jar_set_accept_policy(session.soupNetworkSession().cookieJar(), soupPolicy);
+    });
 }
 
 WebFrameNetworkingContext::WebFrameNetworkingContext(WebFrame* frame)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to