Title: [196984] trunk/Source/WebKit2
Revision
196984
Author
[email protected]
Date
2016-02-23 11:13:18 -0800 (Tue, 23 Feb 2016)

Log Message

Implement downloads with NetworkSession
https://bugs.webkit.org/show_bug.cgi?id=154473

Reviewed by Brady Eidson.

* NetworkProcess/Downloads/Download.cpp:
(WebKit::Download::~Download):
(WebKit::Download::didStart):
(WebKit::Download::shouldDecodeSourceDataOfMIMEType):
(WebKit::Download::decideDestinationWithSuggestedFilename):
(WebKit::Download::didCreateDestination):
* NetworkProcess/Downloads/Download.h:
(WebKit::Download::downloadID):
(WebKit::Download::setSandboxExtension):
* NetworkProcess/Downloads/DownloadManager.cpp:
(WebKit::DownloadManager::startDownload):
(WebKit::DownloadManager::dataTaskBecameDownloadTask):
(WebKit::DownloadManager::continueCanAuthenticateAgainstProtectionSpace):
(WebKit::DownloadManager::continueWillSendRequest):
(WebKit::DownloadManager::willDecidePendingDownloadDestination):
(WebKit::DownloadManager::continueDecidePendingDownloadDestination):
(WebKit::DownloadManager::convertHandleToDownload):
* NetworkProcess/Downloads/DownloadManager.h:
* NetworkProcess/NetworkDataTask.h:
(WebKit::NetworkDataTask::clearClient):

NetworkDataTasks can now outlive their client, so we need to make client a pointer
with the ability to be nulled from the client's destructor.

(WebKit::NetworkDataTask::pendingDownloadID):
(WebKit::NetworkDataTask::pendingDownload):
(WebKit::NetworkDataTask::setPendingDownload):
(WebKit::NetworkDataTask::pendingDownloadLocation):
(WebKit::NetworkDataTask::client): Deleted.
* NetworkProcess/NetworkLoad.cpp:
(WebKit::NetworkLoad::~NetworkLoad):
(WebKit::NetworkLoad::convertTaskToDownload):
(WebKit::NetworkLoad::setPendingDownloadID):
(WebKit::NetworkLoad::didReceiveResponseNetworkSession):

Don't call the didReceiveResponse completion handler immediately when we know we are
going to turn the load into a download.  Instead, save the completion handler until
after we have determined the download destination and set it in the NetworkDataTask.

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::continueWillSendRequest):
(WebKit::NetworkProcess::findPendingDownloadLocation):
(WebKit::NetworkProcess::continueDecidePendingDownloadDestination):
(WebKit::NetworkProcess::setCacheModel):
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkProcess.messages.in:
* NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
(WebKit::NetworkDataTask::NetworkDataTask):
(WebKit::NetworkDataTask::~NetworkDataTask):
(WebKit::NetworkDataTask::didSendData):
(WebKit::NetworkDataTask::didReceiveChallenge):
(WebKit::NetworkDataTask::didCompleteWithError):
(WebKit::NetworkDataTask::didReceiveResponse):
(WebKit::NetworkDataTask::didReceiveData):
(WebKit::NetworkDataTask::didBecomeDownload):
(WebKit::NetworkDataTask::willPerformHTTPRedirection):
(WebKit::NetworkDataTask::scheduleFailure):
(WebKit::NetworkDataTask::failureTimerFired):
(WebKit::NetworkDataTask::findPendingDownloadLocation):
(WebKit::NetworkDataTask::setPendingDownloadLocation):
(WebKit::NetworkDataTask::tryPasswordBasedAuthentication):
(WebKit::NetworkDataTask::transferSandboxExtensionToDownload):
(WebKit::NetworkDataTask::currentRequest):
(WebKit::NetworkDataTask::cancel):
* NetworkProcess/cocoa/NetworkSessionCocoa.mm:
(-[WKNetworkSessionDelegate URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:]):
(-[WKNetworkSessionDelegate URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:]):
(-[WKNetworkSessionDelegate URLSession:task:didReceiveChallenge:completionHandler:]):
(-[WKNetworkSessionDelegate URLSession:task:didCompleteWithError:]):
        
This delegate callback is used for downloads, too.

(-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]):
(-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveData:]):
(-[WKNetworkSessionDelegate URLSession:downloadTask:didFinishDownloadingToURL:]):
(-[WKNetworkSessionDelegate URLSession:dataTask:didBecomeDownloadTask:]):
        
Call didCreateDestination now, which is after the file has been opened on the disk.
A DownloadProxy::DidStart message is now sent from NetworkProcess::findPendingDownloadLocation before
we ask the UIProcess where the download should end up on disk.
Null check the NetworkDataTask's client before using it because it is now a pointer that could be null. 
        
* UIProcess/Downloads/DownloadProxy.cpp:
(WebKit::DownloadProxy::shouldDecodeSourceDataOfMIMEType):
(WebKit::DownloadProxy::decideDestinationWithSuggestedFilenameAsync):
(WebKit::DownloadProxy::decideDestinationWithSuggestedFilename):
(WebKit::DownloadProxy::didCreateDestination):
* UIProcess/Downloads/DownloadProxy.h:
* UIProcess/Downloads/DownloadProxy.messages.in:

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (196983 => 196984)


--- trunk/Source/WebKit2/ChangeLog	2016-02-23 18:17:17 UTC (rev 196983)
+++ trunk/Source/WebKit2/ChangeLog	2016-02-23 19:13:18 UTC (rev 196984)
@@ -1,3 +1,100 @@
+2016-02-23  Alex Christensen  <[email protected]>
+
+        Implement downloads with NetworkSession
+        https://bugs.webkit.org/show_bug.cgi?id=154473
+
+        Reviewed by Brady Eidson.
+
+        * NetworkProcess/Downloads/Download.cpp:
+        (WebKit::Download::~Download):
+        (WebKit::Download::didStart):
+        (WebKit::Download::shouldDecodeSourceDataOfMIMEType):
+        (WebKit::Download::decideDestinationWithSuggestedFilename):
+        (WebKit::Download::didCreateDestination):
+        * NetworkProcess/Downloads/Download.h:
+        (WebKit::Download::downloadID):
+        (WebKit::Download::setSandboxExtension):
+        * NetworkProcess/Downloads/DownloadManager.cpp:
+        (WebKit::DownloadManager::startDownload):
+        (WebKit::DownloadManager::dataTaskBecameDownloadTask):
+        (WebKit::DownloadManager::continueCanAuthenticateAgainstProtectionSpace):
+        (WebKit::DownloadManager::continueWillSendRequest):
+        (WebKit::DownloadManager::willDecidePendingDownloadDestination):
+        (WebKit::DownloadManager::continueDecidePendingDownloadDestination):
+        (WebKit::DownloadManager::convertHandleToDownload):
+        * NetworkProcess/Downloads/DownloadManager.h:
+        * NetworkProcess/NetworkDataTask.h:
+        (WebKit::NetworkDataTask::clearClient):
+
+        NetworkDataTasks can now outlive their client, so we need to make client a pointer
+        with the ability to be nulled from the client's destructor.
+
+        (WebKit::NetworkDataTask::pendingDownloadID):
+        (WebKit::NetworkDataTask::pendingDownload):
+        (WebKit::NetworkDataTask::setPendingDownload):
+        (WebKit::NetworkDataTask::pendingDownloadLocation):
+        (WebKit::NetworkDataTask::client): Deleted.
+        * NetworkProcess/NetworkLoad.cpp:
+        (WebKit::NetworkLoad::~NetworkLoad):
+        (WebKit::NetworkLoad::convertTaskToDownload):
+        (WebKit::NetworkLoad::setPendingDownloadID):
+        (WebKit::NetworkLoad::didReceiveResponseNetworkSession):
+
+        Don't call the didReceiveResponse completion handler immediately when we know we are
+        going to turn the load into a download.  Instead, save the completion handler until
+        after we have determined the download destination and set it in the NetworkDataTask.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::continueWillSendRequest):
+        (WebKit::NetworkProcess::findPendingDownloadLocation):
+        (WebKit::NetworkProcess::continueDecidePendingDownloadDestination):
+        (WebKit::NetworkProcess::setCacheModel):
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/NetworkProcess.messages.in:
+        * NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
+        (WebKit::NetworkDataTask::NetworkDataTask):
+        (WebKit::NetworkDataTask::~NetworkDataTask):
+        (WebKit::NetworkDataTask::didSendData):
+        (WebKit::NetworkDataTask::didReceiveChallenge):
+        (WebKit::NetworkDataTask::didCompleteWithError):
+        (WebKit::NetworkDataTask::didReceiveResponse):
+        (WebKit::NetworkDataTask::didReceiveData):
+        (WebKit::NetworkDataTask::didBecomeDownload):
+        (WebKit::NetworkDataTask::willPerformHTTPRedirection):
+        (WebKit::NetworkDataTask::scheduleFailure):
+        (WebKit::NetworkDataTask::failureTimerFired):
+        (WebKit::NetworkDataTask::findPendingDownloadLocation):
+        (WebKit::NetworkDataTask::setPendingDownloadLocation):
+        (WebKit::NetworkDataTask::tryPasswordBasedAuthentication):
+        (WebKit::NetworkDataTask::transferSandboxExtensionToDownload):
+        (WebKit::NetworkDataTask::currentRequest):
+        (WebKit::NetworkDataTask::cancel):
+        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+        (-[WKNetworkSessionDelegate URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:]):
+        (-[WKNetworkSessionDelegate URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:]):
+        (-[WKNetworkSessionDelegate URLSession:task:didReceiveChallenge:completionHandler:]):
+        (-[WKNetworkSessionDelegate URLSession:task:didCompleteWithError:]):
+        
+        This delegate callback is used for downloads, too.
+
+        (-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]):
+        (-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveData:]):
+        (-[WKNetworkSessionDelegate URLSession:downloadTask:didFinishDownloadingToURL:]):
+        (-[WKNetworkSessionDelegate URLSession:dataTask:didBecomeDownloadTask:]):
+        
+        Call didCreateDestination now, which is after the file has been opened on the disk.
+        A DownloadProxy::DidStart message is now sent from NetworkProcess::findPendingDownloadLocation before
+        we ask the UIProcess where the download should end up on disk.
+        Null check the NetworkDataTask's client before using it because it is now a pointer that could be null. 
+        
+        * UIProcess/Downloads/DownloadProxy.cpp:
+        (WebKit::DownloadProxy::shouldDecodeSourceDataOfMIMEType):
+        (WebKit::DownloadProxy::decideDestinationWithSuggestedFilenameAsync):
+        (WebKit::DownloadProxy::decideDestinationWithSuggestedFilename):
+        (WebKit::DownloadProxy::didCreateDestination):
+        * UIProcess/Downloads/DownloadProxy.h:
+        * UIProcess/Downloads/DownloadProxy.messages.in:
+
 2016-02-23  Brian Burg  <[email protected]>
 
         Connect WebAutomationSession to its backend dispatcher as if it were an agent and add stub implementations

Modified: trunk/Source/WebKit2/NetworkProcess/Downloads/Download.cpp (196983 => 196984)


--- trunk/Source/WebKit2/NetworkProcess/Downloads/Download.cpp	2016-02-23 18:17:17 UTC (rev 196983)
+++ trunk/Source/WebKit2/NetworkProcess/Downloads/Download.cpp	2016-02-23 19:13:18 UTC (rev 196984)
@@ -66,12 +66,7 @@
     m_downloadManager.didDestroyDownload();
 }
 
-#if USE(NETWORK_SESSION)
-void Download::didStart(const ResourceRequest& request)
-{
-    send(Messages::DownloadProxy::DidStart(request));
-}
-#else
+#if !USE(NETWORK_SESSION)
 void Download::didStart()
 {
     send(Messages::DownloadProxy::DidStart(m_request));
@@ -104,6 +99,7 @@
     return result;
 }
 
+#if !USE(NETWORK_SESSION)
 String Download::decideDestinationWithSuggestedFilename(const String& filename, bool& allowOverwrite)
 {
     String destination;
@@ -117,6 +113,7 @@
 
     return destination;
 }
+#endif
 
 void Download::didCreateDestination(const String& path)
 {

Modified: trunk/Source/WebKit2/NetworkProcess/Downloads/Download.h (196983 => 196984)


--- trunk/Source/WebKit2/NetworkProcess/Downloads/Download.h	2016-02-23 18:17:17 UTC (rev 196983)
+++ trunk/Source/WebKit2/NetworkProcess/Downloads/Download.h	2016-02-23 19:13:18 UTC (rev 196984)
@@ -82,9 +82,7 @@
 #endif
     ~Download();
 
-#if USE(NETWORK_SESSION) && PLATFORM(COCOA)
-    void dataTaskDidBecomeDownloadTask(const NetworkSession&, RetainPtr<NSURLSessionDownloadTask>&&);
-#else
+#if !USE(NETWORK_SESSION)
     void start();
     void startWithHandle(WebCore::ResourceHandle*, const WebCore::ResourceResponse&);
 #endif
@@ -94,7 +92,7 @@
     DownloadID downloadID() const { return m_downloadID; }
 
 #if USE(NETWORK_SESSION)
-    void didStart(const WebCore::ResourceRequest&);
+    void setSandboxExtension(RefPtr<SandboxExtension>&& sandboxExtension) { m_sandboxExtension = WTFMove(sandboxExtension); }
 #else
     void didStart();
     void didReceiveAuthenticationChallenge(const WebCore::AuthenticationChallenge&);
@@ -102,7 +100,9 @@
     void didReceiveResponse(const WebCore::ResourceResponse&);
     void didReceiveData(uint64_t length);
     bool shouldDecodeSourceDataOfMIMEType(const String& mimeType);
+#if !USE(NETWORK_SESSION)
     String decideDestinationWithSuggestedFilename(const String& filename, bool& allowOverwrite);
+#endif
     void didCreateDestination(const String& path);
     void didFinish();
     void platformDidFinish();

Modified: trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.cpp (196983 => 196984)


--- trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.cpp	2016-02-23 18:17:17 UTC (rev 196983)
+++ trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.cpp	2016-02-23 19:13:18 UTC (rev 196984)
@@ -65,13 +65,18 @@
 }
 
 #if USE(NETWORK_SESSION)
-std::unique_ptr<PendingDownload> DownloadManager::dataTaskBecameDownloadTask(DownloadID downloadID, std::unique_ptr<Download>&& download)
+std::pair<RefPtr<NetworkDataTask>, std::unique_ptr<PendingDownload>> DownloadManager::dataTaskBecameDownloadTask(DownloadID downloadID, std::unique_ptr<Download>&& download)
 {
     // This is needed for downloads started with startDownload, otherwise it will return nullptr.
     auto pendingDownload = m_pendingDownloads.take(downloadID);
 
+    // This is needed for downloads started with convertTaskToDownload, otherwise it will return nullptr.
+    auto downloadAfterLocationDecided = m_downloadsAfterDestinationDecided.take(downloadID);
+    
+    ASSERT(!!pendingDownload != !!downloadAfterLocationDecided);
+    
     m_downloads.add(downloadID, WTFMove(download));
-    return pendingDownload;
+    return std::make_pair(WTFMove(downloadAfterLocationDecided), WTFMove(pendingDownload));
 }
     
 void DownloadManager::continueCanAuthenticateAgainstProtectionSpace(DownloadID downloadID, bool canAuthenticate)
@@ -89,6 +94,28 @@
     if (pendingDownload)
         pendingDownload->continueWillSendRequest(request);
 }
+
+void DownloadManager::willDecidePendingDownloadDestination(NetworkDataTask& networkDataTask, ResponseCompletionHandler completionHandler)
+{
+    auto addResult = m_downloadsWaitingForDestination.set(networkDataTask.pendingDownloadID(), std::make_pair<RefPtr<NetworkDataTask>, ResponseCompletionHandler>(&networkDataTask, WTFMove(completionHandler)));
+    ASSERT_UNUSED(addResult, addResult.isNewEntry);
+}
+
+void DownloadManager::continueDecidePendingDownloadDestination(DownloadID downloadID, String destination, const SandboxExtension::Handle& sandboxExtensionHandle)
+{
+    auto pair = m_downloadsWaitingForDestination.take(downloadID);
+    auto networkDataTask = pair.first;
+    auto completionHandler = pair.second;
+    if (!networkDataTask || !completionHandler) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    networkDataTask->setPendingDownloadLocation(destination, sandboxExtensionHandle);
+    completionHandler(PolicyDownload);
+    
+    ASSERT(!m_downloadsAfterDestinationDecided.contains(downloadID));
+    m_downloadsAfterDestinationDecided.set(downloadID, networkDataTask);
+}
 #else
 void DownloadManager::convertHandleToDownload(DownloadID downloadID, ResourceHandle* handle, const ResourceRequest& request, const ResourceResponse& response)
 {

Modified: trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.h (196983 => 196984)


--- trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.h	2016-02-23 18:17:17 UTC (rev 196983)
+++ trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.h	2016-02-23 19:13:18 UTC (rev 196984)
@@ -27,6 +27,7 @@
 #define DownloadManager_h
 
 #include "DownloadID.h"
+#include "NetworkDataTask.h"
 #include "PendingDownload.h"
 #include "SandboxExtension.h"
 #include <WebCore/NotImplemented.h>
@@ -72,9 +73,11 @@
 
     void startDownload(WebCore::SessionID, DownloadID, const WebCore::ResourceRequest&);
 #if USE(NETWORK_SESSION)
-    std::unique_ptr<PendingDownload> dataTaskBecameDownloadTask(DownloadID, std::unique_ptr<Download>&&);
+    std::pair<RefPtr<NetworkDataTask>, std::unique_ptr<PendingDownload>> dataTaskBecameDownloadTask(DownloadID, std::unique_ptr<Download>&&);
     void continueCanAuthenticateAgainstProtectionSpace(DownloadID, bool canAuthenticate);
     void continueWillSendRequest(DownloadID, const WebCore::ResourceRequest&);
+    void willDecidePendingDownloadDestination(NetworkDataTask&, ResponseCompletionHandler);
+    void continueDecidePendingDownloadDestination(DownloadID, String destination, const SandboxExtension::Handle&);
 #else
     void convertHandleToDownload(DownloadID, WebCore::ResourceHandle*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
 #endif
@@ -99,6 +102,8 @@
     Client& m_client;
 #if USE(NETWORK_SESSION)
     HashMap<DownloadID, std::unique_ptr<PendingDownload>> m_pendingDownloads;
+    HashMap<DownloadID, std::pair<RefPtr<NetworkDataTask>, ResponseCompletionHandler>> m_downloadsWaitingForDestination;
+    HashMap<DownloadID, RefPtr<NetworkDataTask>> m_downloadsAfterDestinationDecided;
 #endif
     HashMap<DownloadID, std::unique_ptr<Download>> m_downloads;
 };

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h (196983 => 196984)


--- trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h	2016-02-23 18:17:17 UTC (rev 196983)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h	2016-02-23 19:13:18 UTC (rev 196984)
@@ -26,6 +26,7 @@
 #ifndef NetworkDataTask_h
 #define NetworkDataTask_h
 
+#include "SandboxExtension.h"
 #include <WebCore/FrameLoaderTypes.h>
 #include <WebCore/ResourceHandleTypes.h>
 #include <WebCore/ResourceLoaderOptions.h>
@@ -49,6 +50,7 @@
 
 namespace WebKit {
 
+class Download;
 class NetworkSession;
 class PendingDownload;
 
@@ -95,8 +97,15 @@
     
     ~NetworkDataTask();
     
-    NetworkDataTaskClient& client() { return m_client; }
+    void didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend);
+    void didReceiveChallenge(const WebCore::AuthenticationChallenge&, ChallengeCompletionHandler);
+    void didCompleteWithError(const WebCore::ResourceError&);
+    void didReceiveResponse(const WebCore::ResourceResponse&, ResponseCompletionHandler);
+    void didReceiveData(RefPtr<WebCore::SharedBuffer>&&);
+    void didBecomeDownload();
     
+    void clearClient() { m_client = nullptr; }
+    
     DownloadID pendingDownloadID() { return m_pendingDownloadID; }
     PendingDownload* pendingDownload() { return m_pendingDownload; }
     void setPendingDownloadID(DownloadID downloadID)
@@ -110,8 +119,13 @@
         ASSERT(!m_pendingDownload);
         m_pendingDownload = &pendingDownload;
     }
+    void findPendingDownloadLocation(ResponseCompletionHandler);
+    void setPendingDownloadLocation(const String& filename, const SandboxExtension::Handle&);
+    const String& pendingDownloadLocation() { return m_pendingDownloadLocation; }
+    WebCore::ResourceRequest currentRequest();
     bool tryPasswordBasedAuthentication(const WebCore::AuthenticationChallenge&, ChallengeCompletionHandler);
     void willPerformHTTPRedirection(const WebCore::ResourceResponse&, WebCore::ResourceRequest&&, RedirectCompletionHandler);
+    void transferSandboxExtensionToDownload(Download&);
     
 private:
     NetworkDataTask(NetworkSession&, NetworkDataTaskClient&, const WebCore::ResourceRequest&, WebCore::StoredCredentials, WebCore::ContentSniffingPolicy, bool shouldClearReferrerOnHTTPSToHTTPRedirect);
@@ -127,14 +141,16 @@
     void scheduleFailure(FailureType);
     
     NetworkSession& m_session;
-    NetworkDataTaskClient& m_client;
+    NetworkDataTaskClient* m_client;
     PendingDownload* m_pendingDownload { nullptr };
     DownloadID m_pendingDownloadID;
     String m_user;
     String m_password;
     String m_lastHTTPMethod;
+    String m_pendingDownloadLocation;
     WebCore::ResourceRequest m_firstRequest;
     bool m_shouldClearReferrerOnHTTPSToHTTPRedirect;
+    RefPtr<SandboxExtension> m_sandboxExtension;
 #if PLATFORM(COCOA)
     RetainPtr<NSURLSessionDataTask> m_task;
 #endif

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp (196983 => 196984)


--- trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp	2016-02-23 18:17:17 UTC (rev 196983)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp	2016-02-23 19:13:18 UTC (rev 196984)
@@ -71,6 +71,8 @@
 #if USE(NETWORK_SESSION)
     if (m_responseCompletionHandler)
         m_responseCompletionHandler(PolicyIgnore);
+    if (m_task)
+        m_task->clearClient();
 #endif
     if (m_handle)
         m_handle->clearClient();
@@ -163,13 +165,14 @@
 
 void NetworkLoad::convertTaskToDownload(DownloadID downloadID)
 {
+    if (!m_task)
+        return;
+
     m_task->setPendingDownloadID(downloadID);
     
     ASSERT(m_responseCompletionHandler);
-    if (m_responseCompletionHandler) {
-        m_responseCompletionHandler(PolicyDownload);
-        m_responseCompletionHandler = nullptr;
-    }
+    if (m_responseCompletionHandler)
+        m_task->findPendingDownloadLocation(WTFMove(m_responseCompletionHandler));
 }
 
 void NetworkLoad::setPendingDownloadID(DownloadID downloadID)
@@ -218,7 +221,7 @@
 {
     ASSERT(isMainThread());
     if (m_task && m_task->pendingDownloadID().downloadID())
-        completionHandler(PolicyDownload);
+        m_task->findPendingDownloadLocation(completionHandler);
     else if (sharedDidReceiveResponse(response) == NetworkLoadClient::ShouldContinueDidReceiveResponse::Yes)
         completionHandler(PolicyUse);
     else

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp (196983 => 196984)


--- trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp	2016-02-23 18:17:17 UTC (rev 196983)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp	2016-02-23 19:13:18 UTC (rev 196984)
@@ -31,6 +31,7 @@
 #include "AuthenticationManager.h"
 #include "ChildProcessMessages.h"
 #include "CustomProtocolManager.h"
+#include "DownloadProxyMessages.h"
 #include "Logging.h"
 #include "NetworkConnectionToWebProcess.h"
 #include "NetworkProcessCreationParameters.h"
@@ -41,6 +42,7 @@
 #include "SessionTracker.h"
 #include "StatisticsData.h"
 #include "WebCookieManager.h"
+#include "WebCoreArgumentCoders.h"
 #include "WebProcessPoolMessages.h"
 #include "WebsiteData.h"
 #include <WebCore/DNS.h>
@@ -468,6 +470,20 @@
 {
     downloadManager().continueWillSendRequest(downloadID, request);
 }
+
+void NetworkProcess::findPendingDownloadLocation(NetworkDataTask& networkDataTask, String suggestedFilename, ResponseCompletionHandler completionHandler)
+{
+    uint64_t destinationID = networkDataTask.pendingDownloadID().downloadID();
+    downloadProxyConnection()->send(Messages::DownloadProxy::DidStart(networkDataTask.currentRequest()), destinationID);
+    
+    downloadManager().willDecidePendingDownloadDestination(networkDataTask, completionHandler);
+    downloadProxyConnection()->send(Messages::DownloadProxy::DecideDestinationWithSuggestedFilenameAsync(networkDataTask.pendingDownloadID(), suggestedFilename), destinationID);
+}
+    
+void NetworkProcess::continueDecidePendingDownloadDestination(DownloadID downloadID, String destination, const SandboxExtension::Handle& sandboxExtensionHandle)
+{
+    downloadManager().continueDecidePendingDownloadDestination(downloadID, destination, sandboxExtensionHandle);
+}
 #endif
 
 void NetworkProcess::setCacheModel(uint32_t cm)

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkProcess.h (196983 => 196984)


--- trunk/Source/WebKit2/NetworkProcess/NetworkProcess.h	2016-02-23 18:17:17 UTC (rev 196983)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkProcess.h	2016-02-23 19:13:18 UTC (rev 196984)
@@ -42,6 +42,7 @@
 #endif
 
 namespace WebCore {
+class DownloadID;
 class CertificateInfo;
 class NetworkStorageSession;
 class SecurityOrigin;
@@ -99,6 +100,10 @@
     void clearHSTSCache(WebCore::NetworkStorageSession&, std::chrono::system_clock::time_point modifiedSince);
 #endif
 
+#if USE(NETWORK_SESSION)
+    void findPendingDownloadLocation(NetworkDataTask&, String suggestedFilename, ResponseCompletionHandler);
+#endif
+    
     void prefetchDNS(const String&);
 
 private:
@@ -157,6 +162,7 @@
 #if USE(NETWORK_SESSION)
     void continueCanAuthenticateAgainstProtectionSpace(DownloadID, bool canAuthenticate);
     void continueWillSendRequest(DownloadID, const WebCore::ResourceRequest&);
+    void continueDecidePendingDownloadDestination(DownloadID, String destination, const SandboxExtension::Handle& sandboxExtensionHandle);
 #endif
     void setCacheModel(uint32_t);
     void allowSpecificHTTPSCertificateForHost(const WebCore::CertificateInfo&, const String& host);

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in (196983 => 196984)


--- trunk/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in	2016-02-23 18:17:17 UTC (rev 196983)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in	2016-02-23 19:13:18 UTC (rev 196984)
@@ -47,6 +47,7 @@
 #if USE(NETWORK_SESSION)
     ContinueCanAuthenticateAgainstProtectionSpace(WebKit::DownloadID downloadID, bool canAuthenticate)
     ContinueWillSendRequest(WebKit::DownloadID downloadID, WebCore::ResourceRequest request)
+    ContinueDecidePendingDownloadDestination(WebKit::DownloadID downloadID, String destination, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
 #endif
 
     SetProcessSuppressionEnabled(bool flag)

Modified: trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm (196983 => 196984)


--- trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm	2016-02-23 18:17:17 UTC (rev 196983)
+++ trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm	2016-02-23 19:13:18 UTC (rev 196984)
@@ -28,17 +28,25 @@
 
 #if USE(NETWORK_SESSION)
 
+#import "Download.h"
+#import "DownloadProxyMessages.h"
+#import "NetworkProcess.h"
+#import "WebCoreArgumentCoders.h"
 #import <WebCore/AuthenticationChallenge.h>
 #import <WebCore/CFNetworkSPI.h>
 #import <WebCore/ResourceRequest.h>
 #import <wtf/MainThread.h>
 
+@interface NSURLSessionTask ()
+@property (readwrite, copy) NSString *_pathToDownloadTaskFile;
+@end
+
 namespace WebKit {
 
 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_client(client)
+    , m_client(&client)
     , m_lastHTTPMethod(requestWithCredentials.httpMethod())
     , m_firstRequest(requestWithCredentials)
     , m_shouldClearReferrerOnHTTPSToHTTPRedirect(shouldClearReferrerOnHTTPSToHTTPRedirect)
@@ -86,6 +94,42 @@
     }
 }
 
+void NetworkDataTask::didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend)
+{
+    if (m_client)
+        m_client->didSendData(totalBytesSent, totalBytesExpectedToSend);
+}
+
+void NetworkDataTask::didReceiveChallenge(const WebCore::AuthenticationChallenge& challenge, ChallengeCompletionHandler completionHandler)
+{
+    if (m_client)
+        m_client->didReceiveChallenge(challenge, completionHandler);
+}
+
+void NetworkDataTask::didCompleteWithError(const WebCore::ResourceError& error)
+{
+    if (m_client)
+        m_client->didCompleteWithError(error);
+}
+
+void NetworkDataTask::didReceiveResponse(const WebCore::ResourceResponse& response, ResponseCompletionHandler completionHandler)
+{
+    if (m_client)
+        m_client->didReceiveResponseNetworkSession(response, completionHandler);
+}
+
+void NetworkDataTask::didReceiveData(RefPtr<WebCore::SharedBuffer>&& data)
+{
+    if (m_client)
+        m_client->didReceiveData(WTFMove(data));
+}
+
+void NetworkDataTask::didBecomeDownload()
+{
+    if (m_client)
+        m_client->didBecomeDownload();
+}
+
 void NetworkDataTask::willPerformHTTPRedirection(const WebCore::ResourceResponse& redirectResponse, WebCore::ResourceRequest&& request, RedirectCompletionHandler completionHandler)
 {
     if (redirectResponse.httpStatusCode() == 307 || redirectResponse.httpStatusCode() == 308) {
@@ -116,7 +160,8 @@
         request.clearHTTPOrigin();
     }
     
-    client().willPerformHTTPRedirection(redirectResponse, request, completionHandler);
+    if (m_client)
+        m_client->willPerformHTTPRedirection(redirectResponse, request, completionHandler);
 }
     
 void NetworkDataTask::scheduleFailure(FailureType type)
@@ -133,11 +178,13 @@
     switch (m_scheduledFailureType) {
     case BlockedFailure:
         m_scheduledFailureType = NoFailure;
-        client().wasBlocked();
+        if (m_client)
+            m_client->wasBlocked();
         return;
     case InvalidURLFailure:
         m_scheduledFailureType = NoFailure;
-        client().cannotShowURL();
+        if (m_client)
+            m_client->cannotShowURL();
         return;
     case NoFailure:
         ASSERT_NOT_REACHED();
@@ -146,6 +193,22 @@
     ASSERT_NOT_REACHED();
 }
 
+void NetworkDataTask::findPendingDownloadLocation(ResponseCompletionHandler completionHandler)
+{
+    NetworkProcess::singleton().findPendingDownloadLocation(*this, m_task.get().response.suggestedFilename, completionHandler);
+}
+
+void NetworkDataTask::setPendingDownloadLocation(const WTF::String& filename, const SandboxExtension::Handle& sandboxExtensionHandle)
+{
+    ASSERT(!m_sandboxExtension);
+    m_sandboxExtension = SandboxExtension::create(sandboxExtensionHandle);
+    if (m_sandboxExtension)
+        m_sandboxExtension->consume();
+
+    m_pendingDownloadLocation = filename;
+    m_task.get()._pathToDownloadTaskFile = filename;
+}
+
 bool NetworkDataTask::tryPasswordBasedAuthentication(const WebCore::AuthenticationChallenge& challenge, ChallengeCompletionHandler completionHandler)
 {
     if (!challenge.protectionSpace().isPasswordBased())
@@ -166,6 +229,16 @@
     return false;
 }
 
+void NetworkDataTask::transferSandboxExtensionToDownload(Download& download)
+{
+    download.setSandboxExtension(WTFMove(m_sandboxExtension));
+}
+
+WebCore::ResourceRequest NetworkDataTask::currentRequest()
+{
+    return [m_task currentRequest];
+}
+
 void NetworkDataTask::cancel()
 {
     [m_task cancel];

Modified: trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm (196983 => 196984)


--- trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm	2016-02-23 18:17:17 UTC (rev 196983)
+++ trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm	2016-02-23 19:13:18 UTC (rev 196984)
@@ -29,6 +29,7 @@
 #if USE(NETWORK_SESSION)
 
 #import "CustomProtocolManager.h"
+#import "DataReference.h"
 #import "Download.h"
 #import "NetworkLoad.h"
 #import "NetworkProcess.h"
@@ -98,7 +99,7 @@
 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
 {
     if (auto* networkDataTask = _session->dataTaskForIdentifier(task.taskIdentifier))
-        networkDataTask->client().didSendData(totalBytesSent, totalBytesExpectedToSend);
+        networkDataTask->didSendData(totalBytesSent, totalBytesExpectedToSend);
 }
 
 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest *))completionHandler
@@ -125,14 +126,18 @@
         if (networkDataTask->tryPasswordBasedAuthentication(challenge, challengeCompletionHandler))
             return;
         
-        networkDataTask->client().didReceiveChallenge(challenge, challengeCompletionHandler);
+        networkDataTask->didReceiveChallenge(challenge, challengeCompletionHandler);
     }
 }
 
 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
 {
     if (auto* networkDataTask = _session->dataTaskForIdentifier(task.taskIdentifier))
-        networkDataTask->client().didCompleteWithError(error);
+        networkDataTask->didCompleteWithError(error);
+    else if (auto* download = WebKit::NetworkProcess::singleton().downloadManager().download(_session->downloadID(task.taskIdentifier))) {
+        if (error)
+            download->didFail(error, { }); // FIXME: Give some actual data here for resuming.
+    }
 }
 
 - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
@@ -142,7 +147,7 @@
         WebCore::ResourceResponse resourceResponse(response);
         copyTimingData([dataTask _timingData], resourceResponse.resourceLoadTiming());
         auto completionHandlerCopy = Block_copy(completionHandler);
-        networkDataTask->client().didReceiveResponseNetworkSession(resourceResponse, [completionHandlerCopy](WebCore::PolicyAction policyAction) {
+        networkDataTask->didReceiveResponse(resourceResponse, [completionHandlerCopy, resourceResponse](WebCore::PolicyAction policyAction) {
             completionHandlerCopy(toNSURLSessionResponseDisposition(policyAction));
             Block_release(completionHandlerCopy);
         });
@@ -152,13 +157,12 @@
 - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
 {
     if (auto* networkDataTask = _session->dataTaskForIdentifier(dataTask.taskIdentifier))
-        networkDataTask->client().didReceiveData(WebCore::SharedBuffer::wrapNSData(data));
+        networkDataTask->didReceiveData(WebCore::SharedBuffer::wrapNSData(data));
 }
 
 - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
 {
     auto downloadID = _session->takeDownloadID([downloadTask taskIdentifier]);
-    notImplemented();
     if (auto* download = WebKit::NetworkProcess::singleton().downloadManager().download(downloadID))
         download->didFinish();
 }
@@ -183,11 +187,13 @@
         auto downloadID = networkDataTask->pendingDownloadID();
         auto& downloadManager = WebKit::NetworkProcess::singleton().downloadManager();
         auto download = std::make_unique<WebKit::Download>(downloadManager, downloadID);
-        download->didStart([downloadTask currentRequest]);
+        networkDataTask->transferSandboxExtensionToDownload(*download);
+        ASSERT(WebCore::fileExists(networkDataTask->pendingDownloadLocation()));
+        download->didCreateDestination(networkDataTask->pendingDownloadLocation());
         download->didReceiveResponse([downloadTask response]);
         auto pendingDownload = downloadManager.dataTaskBecameDownloadTask(downloadID, WTFMove(download));
 
-        networkDataTask->client().didBecomeDownload();
+        networkDataTask->didBecomeDownload();
 
         _session->addDownloadID([downloadTask taskIdentifier], downloadID);
     }

Modified: trunk/Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp (196983 => 196984)


--- trunk/Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp	2016-02-23 18:17:17 UTC (rev 196983)
+++ trunk/Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp	2016-02-23 19:13:18 UTC (rev 196984)
@@ -36,6 +36,7 @@
 #include "WebProcessMessages.h"
 #include "WebProcessPool.h"
 #include "WebProtectionSpace.h"
+#include <WebCore/FileSystem.h>
 #include <wtf/text/CString.h>
 #include <wtf/text/WTFString.h>
 
@@ -170,6 +171,24 @@
     result = m_processPool->downloadClient().shouldDecodeSourceDataOfMIMEType(m_processPool.get(), this, mimeType);
 }
 
+#if USE(NETWORK_SESSION)
+void DownloadProxy::decideDestinationWithSuggestedFilenameAsync(DownloadID downloadID, const String& suggestedFilename)
+{
+    bool allowOverwrite = false;
+    
+    if (!m_processPool)
+        return;
+    
+    String destination = m_processPool->downloadClient().decideDestinationWithSuggestedFilename(m_processPool.get(), this, suggestedFilename, allowOverwrite);
+    
+    SandboxExtension::Handle sandboxExtensionHandle;
+    if (!destination.isNull())
+        SandboxExtension::createHandle(destination, SandboxExtension::ReadWrite, sandboxExtensionHandle);
+    
+    if (NetworkProcessProxy* networkProcess = m_processPool->networkProcess())
+        networkProcess->connection()->send(Messages::NetworkProcess::ContinueDecidePendingDownloadDestination(downloadID, destination, sandboxExtensionHandle), 0);
+}
+#else
 void DownloadProxy::decideDestinationWithSuggestedFilename(const String& filename, String& destination, bool& allowOverwrite, SandboxExtension::Handle& sandboxExtensionHandle)
 {
     allowOverwrite = false;
@@ -182,6 +201,7 @@
     if (!destination.isNull())
         SandboxExtension::createHandle(destination, SandboxExtension::ReadWrite, sandboxExtensionHandle);
 }
+#endif
 
 void DownloadProxy::didCreateDestination(const String& path)
 {

Modified: trunk/Source/WebKit2/UIProcess/Downloads/DownloadProxy.h (196983 => 196984)


--- trunk/Source/WebKit2/UIProcess/Downloads/DownloadProxy.h	2016-02-23 18:17:17 UTC (rev 196983)
+++ trunk/Source/WebKit2/UIProcess/Downloads/DownloadProxy.h	2016-02-23 19:13:18 UTC (rev 196984)
@@ -47,6 +47,7 @@
 
 namespace WebKit {
 
+class DownloadID;
 class DownloadProxyMap;
 class WebPageProxy;
 class WebProcessPool;
@@ -81,7 +82,9 @@
     void didReceiveResponse(const WebCore::ResourceResponse&);
     void didReceiveData(uint64_t length);
     void shouldDecodeSourceDataOfMIMEType(const String& mimeType, bool& result);
+#if !USE(NETWORK_SESSION)
     void decideDestinationWithSuggestedFilename(const String& filename, String& destination, bool& allowOverwrite, SandboxExtension::Handle& sandboxExtensionHandle);
+#endif
     void didCreateDestination(const String& path);
     void didFinish();
     void didFail(const WebCore::ResourceError&, const IPC::DataReference& resumeData);
@@ -89,6 +92,7 @@
 #if USE(NETWORK_SESSION)
     void canAuthenticateAgainstProtectionSpace(const WebCore::ProtectionSpace&);
     void willSendRequest(const WebCore::ResourceRequest& redirectRequest, const WebCore::ResourceResponse& redirectResponse);
+    void decideDestinationWithSuggestedFilenameAsync(DownloadID, const String& suggestedFilename);
 #endif
 
     DownloadProxyMap& m_downloadProxyMap;

Modified: trunk/Source/WebKit2/UIProcess/Downloads/DownloadProxy.messages.in (196983 => 196984)


--- trunk/Source/WebKit2/UIProcess/Downloads/DownloadProxy.messages.in	2016-02-23 18:17:17 UTC (rev 196983)
+++ trunk/Source/WebKit2/UIProcess/Downloads/DownloadProxy.messages.in	2016-02-23 19:13:18 UTC (rev 196984)
@@ -26,12 +26,15 @@
 #if USE(NETWORK_SESSION)
     WillSendRequest(WebCore::ResourceRequest redirectRequest, WebCore::ResourceResponse redirectResponse));
     CanAuthenticateAgainstProtectionSpace(WebCore::ProtectionSpace protectionSpace)
+    DecideDestinationWithSuggestedFilenameAsync(WebKit::DownloadID downloadID, String suggestedFilename)
 #endif
 
     DidReceiveResponse(WebCore::ResourceResponse response)
     DidReceiveData(uint64_t length)
     ShouldDecodeSourceDataOfMIMEType(String mimeType) -> (bool result)
+#if !USE(NETWORK_SESSION)
     DecideDestinationWithSuggestedFilename(String filename) -> (String destination, bool allowOverwrite, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
+#endif
     DidCreateDestination(String path)
     DidFinish()
     DidFail(WebCore::ResourceError error, IPC::DataReference resumeData)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to