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)