⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 196984 in webkit


Ignore:
Timestamp:
Feb 23, 2016, 11:13:18 AM (11 years ago)
Author:
achristensen@apple.com
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:
Location:
trunk/Source/WebKit2
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r196980 r196984  
     12016-02-23  Alex Christensen  <achristensen@webkit.org>
     2
     3        Implement downloads with NetworkSession
     4        https://bugs.webkit.org/show_bug.cgi?id=154473
     5
     6        Reviewed by Brady Eidson.
     7
     8        * NetworkProcess/Downloads/Download.cpp:
     9        (WebKit::Download::~Download):
     10        (WebKit::Download::didStart):
     11        (WebKit::Download::shouldDecodeSourceDataOfMIMEType):
     12        (WebKit::Download::decideDestinationWithSuggestedFilename):
     13        (WebKit::Download::didCreateDestination):
     14        * NetworkProcess/Downloads/Download.h:
     15        (WebKit::Download::downloadID):
     16        (WebKit::Download::setSandboxExtension):
     17        * NetworkProcess/Downloads/DownloadManager.cpp:
     18        (WebKit::DownloadManager::startDownload):
     19        (WebKit::DownloadManager::dataTaskBecameDownloadTask):
     20        (WebKit::DownloadManager::continueCanAuthenticateAgainstProtectionSpace):
     21        (WebKit::DownloadManager::continueWillSendRequest):
     22        (WebKit::DownloadManager::willDecidePendingDownloadDestination):
     23        (WebKit::DownloadManager::continueDecidePendingDownloadDestination):
     24        (WebKit::DownloadManager::convertHandleToDownload):
     25        * NetworkProcess/Downloads/DownloadManager.h:
     26        * NetworkProcess/NetworkDataTask.h:
     27        (WebKit::NetworkDataTask::clearClient):
     28
     29        NetworkDataTasks can now outlive their client, so we need to make client a pointer
     30        with the ability to be nulled from the client's destructor.
     31
     32        (WebKit::NetworkDataTask::pendingDownloadID):
     33        (WebKit::NetworkDataTask::pendingDownload):
     34        (WebKit::NetworkDataTask::setPendingDownload):
     35        (WebKit::NetworkDataTask::pendingDownloadLocation):
     36        (WebKit::NetworkDataTask::client): Deleted.
     37        * NetworkProcess/NetworkLoad.cpp:
     38        (WebKit::NetworkLoad::~NetworkLoad):
     39        (WebKit::NetworkLoad::convertTaskToDownload):
     40        (WebKit::NetworkLoad::setPendingDownloadID):
     41        (WebKit::NetworkLoad::didReceiveResponseNetworkSession):
     42
     43        Don't call the didReceiveResponse completion handler immediately when we know we are
     44        going to turn the load into a download.  Instead, save the completion handler until
     45        after we have determined the download destination and set it in the NetworkDataTask.
     46
     47        * NetworkProcess/NetworkProcess.cpp:
     48        (WebKit::NetworkProcess::continueWillSendRequest):
     49        (WebKit::NetworkProcess::findPendingDownloadLocation):
     50        (WebKit::NetworkProcess::continueDecidePendingDownloadDestination):
     51        (WebKit::NetworkProcess::setCacheModel):
     52        * NetworkProcess/NetworkProcess.h:
     53        * NetworkProcess/NetworkProcess.messages.in:
     54        * NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
     55        (WebKit::NetworkDataTask::NetworkDataTask):
     56        (WebKit::NetworkDataTask::~NetworkDataTask):
     57        (WebKit::NetworkDataTask::didSendData):
     58        (WebKit::NetworkDataTask::didReceiveChallenge):
     59        (WebKit::NetworkDataTask::didCompleteWithError):
     60        (WebKit::NetworkDataTask::didReceiveResponse):
     61        (WebKit::NetworkDataTask::didReceiveData):
     62        (WebKit::NetworkDataTask::didBecomeDownload):
     63        (WebKit::NetworkDataTask::willPerformHTTPRedirection):
     64        (WebKit::NetworkDataTask::scheduleFailure):
     65        (WebKit::NetworkDataTask::failureTimerFired):
     66        (WebKit::NetworkDataTask::findPendingDownloadLocation):
     67        (WebKit::NetworkDataTask::setPendingDownloadLocation):
     68        (WebKit::NetworkDataTask::tryPasswordBasedAuthentication):
     69        (WebKit::NetworkDataTask::transferSandboxExtensionToDownload):
     70        (WebKit::NetworkDataTask::currentRequest):
     71        (WebKit::NetworkDataTask::cancel):
     72        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
     73        (-[WKNetworkSessionDelegate URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:]):
     74        (-[WKNetworkSessionDelegate URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:]):
     75        (-[WKNetworkSessionDelegate URLSession:task:didReceiveChallenge:completionHandler:]):
     76        (-[WKNetworkSessionDelegate URLSession:task:didCompleteWithError:]):
     77       
     78        This delegate callback is used for downloads, too.
     79
     80        (-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]):
     81        (-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveData:]):
     82        (-[WKNetworkSessionDelegate URLSession:downloadTask:didFinishDownloadingToURL:]):
     83        (-[WKNetworkSessionDelegate URLSession:dataTask:didBecomeDownloadTask:]):
     84       
     85        Call didCreateDestination now, which is after the file has been opened on the disk.
     86        A DownloadProxy::DidStart message is now sent from NetworkProcess::findPendingDownloadLocation before
     87        we ask the UIProcess where the download should end up on disk.
     88        Null check the NetworkDataTask's client before using it because it is now a pointer that could be null.
     89       
     90        * UIProcess/Downloads/DownloadProxy.cpp:
     91        (WebKit::DownloadProxy::shouldDecodeSourceDataOfMIMEType):
     92        (WebKit::DownloadProxy::decideDestinationWithSuggestedFilenameAsync):
     93        (WebKit::DownloadProxy::decideDestinationWithSuggestedFilename):
     94        (WebKit::DownloadProxy::didCreateDestination):
     95        * UIProcess/Downloads/DownloadProxy.h:
     96        * UIProcess/Downloads/DownloadProxy.messages.in:
     97
    1982016-02-23  Brian Burg  <bburg@apple.com>
    299
  • trunk/Source/WebKit2/NetworkProcess/Downloads/Download.cpp

    r194718 r196984  
    6767}
    6868
    69 #if USE(NETWORK_SESSION)
    70 void Download::didStart(const ResourceRequest& request)
    71 {
    72     send(Messages::DownloadProxy::DidStart(request));
    73 }
    74 #else
     69#if !USE(NETWORK_SESSION)
    7570void Download::didStart()
    7671{
    … …  
    105100}
    106101
     102#if !USE(NETWORK_SESSION)
    107103String Download::decideDestinationWithSuggestedFilename(const String& filename, bool& allowOverwrite)
    108104{
    … …  
    118114    return destination;
    119115}
     116#endif
    120117
    121118void Download::didCreateDestination(const String& path)
  • trunk/Source/WebKit2/NetworkProcess/Downloads/Download.h

    r196600 r196984  
    8383    ~Download();
    8484
    85 #if USE(NETWORK_SESSION) && PLATFORM(COCOA)
    86     void dataTaskDidBecomeDownloadTask(const NetworkSession&, RetainPtr<NSURLSessionDownloadTask>&&);
    87 #else
     85#if !USE(NETWORK_SESSION)
    8886    void start();
    8987    void startWithHandle(WebCore::ResourceHandle*, const WebCore::ResourceResponse&);
    … …  
    9593
    9694#if USE(NETWORK_SESSION)
    97     void didStart(const WebCore::ResourceRequest&);
     95    void setSandboxExtension(RefPtr<SandboxExtension>&& sandboxExtension) { m_sandboxExtension = WTFMove(sandboxExtension); }
    9896#else
    9997    void didStart();
    … …  
    103101    void didReceiveData(uint64_t length);
    104102    bool shouldDecodeSourceDataOfMIMEType(const String& mimeType);
     103#if !USE(NETWORK_SESSION)
    105104    String decideDestinationWithSuggestedFilename(const String& filename, bool& allowOverwrite);
     105#endif
    106106    void didCreateDestination(const String& path);
    107107    void didFinish();
  • trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.cpp

    r195357 r196984  
    6666
    6767#if USE(NETWORK_SESSION)
    68 std::unique_ptr<PendingDownload> DownloadManager::dataTaskBecameDownloadTask(DownloadID downloadID, std::unique_ptr<Download>&& download)
     68std::pair<RefPtr<NetworkDataTask>, std::unique_ptr<PendingDownload>> DownloadManager::dataTaskBecameDownloadTask(DownloadID downloadID, std::unique_ptr<Download>&& download)
    6969{
    7070    // This is needed for downloads started with startDownload, otherwise it will return nullptr.
    7171    auto pendingDownload = m_pendingDownloads.take(downloadID);
    7272
     73    // This is needed for downloads started with convertTaskToDownload, otherwise it will return nullptr.
     74    auto downloadAfterLocationDecided = m_downloadsAfterDestinationDecided.take(downloadID);
     75   
     76    ASSERT(!!pendingDownload != !!downloadAfterLocationDecided);
     77   
    7378    m_downloads.add(downloadID, WTFMove(download));
    74     return pendingDownload;
     79    return std::make_pair(WTFMove(downloadAfterLocationDecided), WTFMove(pendingDownload));
    7580}
    7681   
    … …  
    8994    if (pendingDownload)
    9095        pendingDownload->continueWillSendRequest(request);
     96}
     97
     98void DownloadManager::willDecidePendingDownloadDestination(NetworkDataTask& networkDataTask, ResponseCompletionHandler completionHandler)
     99{
     100    auto addResult = m_downloadsWaitingForDestination.set(networkDataTask.pendingDownloadID(), std::make_pair<RefPtr<NetworkDataTask>, ResponseCompletionHandler>(&networkDataTask, WTFMove(completionHandler)));
     101    ASSERT_UNUSED(addResult, addResult.isNewEntry);
     102}
     103
     104void DownloadManager::continueDecidePendingDownloadDestination(DownloadID downloadID, String destination, const SandboxExtension::Handle& sandboxExtensionHandle)
     105{
     106    auto pair = m_downloadsWaitingForDestination.take(downloadID);
     107    auto networkDataTask = pair.first;
     108    auto completionHandler = pair.second;
     109    if (!networkDataTask || !completionHandler) {
     110        ASSERT_NOT_REACHED();
     111        return;
     112    }
     113    networkDataTask->setPendingDownloadLocation(destination, sandboxExtensionHandle);
     114    completionHandler(PolicyDownload);
     115   
     116    ASSERT(!m_downloadsAfterDestinationDecided.contains(downloadID));
     117    m_downloadsAfterDestinationDecided.set(downloadID, networkDataTask);
    91118}
    92119#else
  • trunk/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.h

    r195357 r196984  
    2828
    2929#include "DownloadID.h"
     30#include "NetworkDataTask.h"
    3031#include "PendingDownload.h"
    3132#include "SandboxExtension.h"
    … …  
    7374    void startDownload(WebCore::SessionID, DownloadID, const WebCore::ResourceRequest&);
    7475#if USE(NETWORK_SESSION)
    75     std::unique_ptr<PendingDownload> dataTaskBecameDownloadTask(DownloadID, std::unique_ptr<Download>&&);
     76    std::pair<RefPtr<NetworkDataTask>, std::unique_ptr<PendingDownload>> dataTaskBecameDownloadTask(DownloadID, std::unique_ptr<Download>&&);
    7677    void continueCanAuthenticateAgainstProtectionSpace(DownloadID, bool canAuthenticate);
    7778    void continueWillSendRequest(DownloadID, const WebCore::ResourceRequest&);
     79    void willDecidePendingDownloadDestination(NetworkDataTask&, ResponseCompletionHandler);
     80    void continueDecidePendingDownloadDestination(DownloadID, String destination, const SandboxExtension::Handle&);
    7881#else
    7982    void convertHandleToDownload(DownloadID, WebCore::ResourceHandle*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
    … …  
    100103#if USE(NETWORK_SESSION)
    101104    HashMap<DownloadID, std::unique_ptr<PendingDownload>> m_pendingDownloads;
     105    HashMap<DownloadID, std::pair<RefPtr<NetworkDataTask>, ResponseCompletionHandler>> m_downloadsWaitingForDestination;
     106    HashMap<DownloadID, RefPtr<NetworkDataTask>> m_downloadsAfterDestinationDecided;
    102107#endif
    103108    HashMap<DownloadID, std::unique_ptr<Download>> m_downloads;
  • trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h

    r196671 r196984  
    2727#define NetworkDataTask_h
    2828
     29#include "SandboxExtension.h"
    2930#include <WebCore/FrameLoaderTypes.h>
    3031#include <WebCore/ResourceHandleTypes.h>
    … …  
    5051namespace WebKit {
    5152
     53class Download;
    5254class NetworkSession;
    5355class PendingDownload;
    … …  
    9698    ~NetworkDataTask();
    9799   
    98     NetworkDataTaskClient& client() { return m_client; }
     100    void didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend);
     101    void didReceiveChallenge(const WebCore::AuthenticationChallenge&, ChallengeCompletionHandler);
     102    void didCompleteWithError(const WebCore::ResourceError&);
     103    void didReceiveResponse(const WebCore::ResourceResponse&, ResponseCompletionHandler);
     104    void didReceiveData(RefPtr<WebCore::SharedBuffer>&&);
     105    void didBecomeDownload();
     106   
     107    void clearClient() { m_client = nullptr; }
    99108   
    100109    DownloadID pendingDownloadID() { return m_pendingDownloadID; }
    … …  
    111120        m_pendingDownload = &pendingDownload;
    112121    }
     122    void findPendingDownloadLocation(ResponseCompletionHandler);
     123    void setPendingDownloadLocation(const String& filename, const SandboxExtension::Handle&);
     124    const String& pendingDownloadLocation() { return m_pendingDownloadLocation; }
     125    WebCore::ResourceRequest currentRequest();
    113126    bool tryPasswordBasedAuthentication(const WebCore::AuthenticationChallenge&, ChallengeCompletionHandler);
    114127    void willPerformHTTPRedirection(const WebCore::ResourceResponse&, WebCore::ResourceRequest&&, RedirectCompletionHandler);
     128    void transferSandboxExtensionToDownload(Download&);
    115129   
    116130private:
    … …  
    128142   
    129143    NetworkSession& m_session;
    130     NetworkDataTaskClient& m_client;
     144    NetworkDataTaskClient* m_client;
    131145    PendingDownload* m_pendingDownload { nullptr };
    132146    DownloadID m_pendingDownloadID;
    … …  
    134148    String m_password;
    135149    String m_lastHTTPMethod;
     150    String m_pendingDownloadLocation;
    136151    WebCore::ResourceRequest m_firstRequest;
    137152    bool m_shouldClearReferrerOnHTTPSToHTTPRedirect;
     153    RefPtr<SandboxExtension> m_sandboxExtension;
    138154#if PLATFORM(COCOA)
    139155    RetainPtr<NSURLSessionDataTask> m_task;
  • trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp

    r196671 r196984  
    7272    if (m_responseCompletionHandler)
    7373        m_responseCompletionHandler(PolicyIgnore);
     74    if (m_task)
     75        m_task->clearClient();
    7476#endif
    7577    if (m_handle)
    … …  
    164166void NetworkLoad::convertTaskToDownload(DownloadID downloadID)
    165167{
     168    if (!m_task)
     169        return;
     170
    166171    m_task->setPendingDownloadID(downloadID);
    167172   
    168173    ASSERT(m_responseCompletionHandler);
    169     if (m_responseCompletionHandler) {
    170         m_responseCompletionHandler(PolicyDownload);
    171         m_responseCompletionHandler = nullptr;
    172     }
     174    if (m_responseCompletionHandler)
     175        m_task->findPendingDownloadLocation(WTFMove(m_responseCompletionHandler));
    173176}
    174177
    … …  
    219222    ASSERT(isMainThread());
    220223    if (m_task && m_task->pendingDownloadID().downloadID())
    221         completionHandler(PolicyDownload);
     224        m_task->findPendingDownloadLocation(completionHandler);
    222225    else if (sharedDidReceiveResponse(response) == NetworkLoadClient::ShouldContinueDidReceiveResponse::Yes)
    223226        completionHandler(PolicyUse);
  • trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp

    r196943 r196984  
    3232#include "ChildProcessMessages.h"
    3333#include "CustomProtocolManager.h"
     34#include "DownloadProxyMessages.h"
    3435#include "Logging.h"
    3536#include "NetworkConnectionToWebProcess.h"
    … …  
    4243#include "StatisticsData.h"
    4344#include "WebCookieManager.h"
     45#include "WebCoreArgumentCoders.h"
    4446#include "WebProcessPoolMessages.h"
    4547#include "WebsiteData.h"
    … …  
    469471    downloadManager().continueWillSendRequest(downloadID, request);
    470472}
     473
     474void NetworkProcess::findPendingDownloadLocation(NetworkDataTask& networkDataTask, String suggestedFilename, ResponseCompletionHandler completionHandler)
     475{
     476    uint64_t destinationID = networkDataTask.pendingDownloadID().downloadID();
     477    downloadProxyConnection()->send(Messages::DownloadProxy::DidStart(networkDataTask.currentRequest()), destinationID);
     478   
     479    downloadManager().willDecidePendingDownloadDestination(networkDataTask, completionHandler);
     480    downloadProxyConnection()->send(Messages::DownloadProxy::DecideDestinationWithSuggestedFilenameAsync(networkDataTask.pendingDownloadID(), suggestedFilename), destinationID);
     481}
     482   
     483void NetworkProcess::continueDecidePendingDownloadDestination(DownloadID downloadID, String destination, const SandboxExtension::Handle& sandboxExtensionHandle)
     484{
     485    downloadManager().continueDecidePendingDownloadDestination(downloadID, destination, sandboxExtensionHandle);
     486}
    471487#endif
    472488
  • trunk/Source/WebKit2/NetworkProcess/NetworkProcess.h

    r196943 r196984  
    4343
    4444namespace WebCore {
     45class DownloadID;
    4546class CertificateInfo;
    4647class NetworkStorageSession;
    … …  
    100101#endif
    101102
     103#if USE(NETWORK_SESSION)
     104    void findPendingDownloadLocation(NetworkDataTask&, String suggestedFilename, ResponseCompletionHandler);
     105#endif
     106   
    102107    void prefetchDNS(const String&);
    103108
    … …  
    158163    void continueCanAuthenticateAgainstProtectionSpace(DownloadID, bool canAuthenticate);
    159164    void continueWillSendRequest(DownloadID, const WebCore::ResourceRequest&);
     165    void continueDecidePendingDownloadDestination(DownloadID, String destination, const SandboxExtension::Handle& sandboxExtensionHandle);
    160166#endif
    161167    void setCacheModel(uint32_t);
  • trunk/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in

    r195589 r196984  
    4848    ContinueCanAuthenticateAgainstProtectionSpace(WebKit::DownloadID downloadID, bool canAuthenticate)
    4949    ContinueWillSendRequest(WebKit::DownloadID downloadID, WebCore::ResourceRequest request)
     50    ContinueDecidePendingDownloadDestination(WebKit::DownloadID downloadID, String destination, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
    5051#endif
    5152
  • trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm

    r196707 r196984  
    2929#if USE(NETWORK_SESSION)
    3030
     31#import "Download.h"
     32#import "DownloadProxyMessages.h"
     33#import "NetworkProcess.h"
     34#import "WebCoreArgumentCoders.h"
    3135#import <WebCore/AuthenticationChallenge.h>
    3236#import <WebCore/CFNetworkSPI.h>
    … …  
    3438#import <wtf/MainThread.h>
    3539
     40@interface NSURLSessionTask ()
     41@property (readwrite, copy) NSString *_pathToDownloadTaskFile;
     42@end
     43
    3644namespace WebKit {
    3745
    … …  
    3947    : m_failureTimer(*this, &NetworkDataTask::failureTimerFired)
    4048    , m_session(session)
    41     , m_client(client)
     49    , m_client(&client)
    4250    , m_lastHTTPMethod(requestWithCredentials.httpMethod())
    4351    , m_firstRequest(requestWithCredentials)
    … …  
    8593        m_session.m_dataTaskMap.remove(taskIdentifier());
    8694    }
     95}
     96
     97void NetworkDataTask::didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend)
     98{
     99    if (m_client)
     100        m_client->didSendData(totalBytesSent, totalBytesExpectedToSend);
     101}
     102
     103void NetworkDataTask::didReceiveChallenge(const WebCore::AuthenticationChallenge& challenge, ChallengeCompletionHandler completionHandler)
     104{
     105    if (m_client)
     106        m_client->didReceiveChallenge(challenge, completionHandler);
     107}
     108
     109void NetworkDataTask::didCompleteWithError(const WebCore::ResourceError& error)
     110{
     111    if (m_client)
     112        m_client->didCompleteWithError(error);
     113}
     114
     115void NetworkDataTask::didReceiveResponse(const WebCore::ResourceResponse& response, ResponseCompletionHandler completionHandler)
     116{
     117    if (m_client)
     118        m_client->didReceiveResponseNetworkSession(response, completionHandler);
     119}
     120
     121void NetworkDataTask::didReceiveData(RefPtr<WebCore::SharedBuffer>&& data)
     122{
     123    if (m_client)
     124        m_client->didReceiveData(WTFMove(data));
     125}
     126
     127void NetworkDataTask::didBecomeDownload()
     128{
     129    if (m_client)
     130        m_client->didBecomeDownload();
    87131}
    88132
    … …  
    117161    }
    118162   
    119     client().willPerformHTTPRedirection(redirectResponse, request, completionHandler);
     163    if (m_client)
     164        m_client->willPerformHTTPRedirection(redirectResponse, request, completionHandler);
    120165}
    121166   
    … …  
    134179    case BlockedFailure:
    135180        m_scheduledFailureType = NoFailure;
    136         client().wasBlocked();
     181        if (m_client)
     182            m_client->wasBlocked();
    137183        return;
    138184    case InvalidURLFailure:
    139185        m_scheduledFailureType = NoFailure;
    140         client().cannotShowURL();
     186        if (m_client)
     187            m_client->cannotShowURL();
    141188        return;
    142189    case NoFailure:
    … …  
    145192    }
    146193    ASSERT_NOT_REACHED();
     194}
     195
     196void NetworkDataTask::findPendingDownloadLocation(ResponseCompletionHandler completionHandler)
     197{
     198    NetworkProcess::singleton().findPendingDownloadLocation(*this, m_task.get().response.suggestedFilename, completionHandler);
     199}
     200
     201void NetworkDataTask::setPendingDownloadLocation(const WTF::String& filename, const SandboxExtension::Handle& sandboxExtensionHandle)
     202{
     203    ASSERT(!m_sandboxExtension);
     204    m_sandboxExtension = SandboxExtension::create(sandboxExtensionHandle);
     205    if (m_sandboxExtension)
     206        m_sandboxExtension->consume();
     207
     208    m_pendingDownloadLocation = filename;
     209    m_task.get()._pathToDownloadTaskFile = filename;
    147210}
    148211
    … …  
    167230}
    168231
     232void NetworkDataTask::transferSandboxExtensionToDownload(Download& download)
     233{
     234    download.setSandboxExtension(WTFMove(m_sandboxExtension));
     235}
     236
     237WebCore::ResourceRequest NetworkDataTask::currentRequest()
     238{
     239    return [m_task currentRequest];
     240}
     241
    169242void NetworkDataTask::cancel()
    170243{
  • trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm

    r196656 r196984  
    3030
    3131#import "CustomProtocolManager.h"
     32#import "DataReference.h"
    3233#import "Download.h"
    3334#import "NetworkLoad.h"
    … …  
    99100{
    100101    if (auto* networkDataTask = _session->dataTaskForIdentifier(task.taskIdentifier))
    101         networkDataTask->client().didSendData(totalBytesSent, totalBytesExpectedToSend);
     102        networkDataTask->didSendData(totalBytesSent, totalBytesExpectedToSend);
    102103}
    103104
    … …  
    126127            return;
    127128       
    128         networkDataTask->client().didReceiveChallenge(challenge, challengeCompletionHandler);
     129        networkDataTask->didReceiveChallenge(challenge, challengeCompletionHandler);
    129130    }
    130131}
    … …  
    133134{
    134135    if (auto* networkDataTask = _session->dataTaskForIdentifier(task.taskIdentifier))
    135         networkDataTask->client().didCompleteWithError(error);
     136        networkDataTask->didCompleteWithError(error);
     137    else if (auto* download = WebKit::NetworkProcess::singleton().downloadManager().download(_session->downloadID(task.taskIdentifier))) {
     138        if (error)
     139            download->didFail(error, { }); // FIXME: Give some actual data here for resuming.
     140    }
    136141}
    137142
    … …  
    143148        copyTimingData([dataTask _timingData], resourceResponse.resourceLoadTiming());
    144149        auto completionHandlerCopy = Block_copy(completionHandler);
    145         networkDataTask->client().didReceiveResponseNetworkSession(resourceResponse, [completionHandlerCopy](WebCore::PolicyAction policyAction) {
     150        networkDataTask->didReceiveResponse(resourceResponse, [completionHandlerCopy, resourceResponse](WebCore::PolicyAction policyAction) {
    146151            completionHandlerCopy(toNSURLSessionResponseDisposition(policyAction));
    147152            Block_release(completionHandlerCopy);
    … …  
    153158{
    154159    if (auto* networkDataTask = _session->dataTaskForIdentifier(dataTask.taskIdentifier))
    155         networkDataTask->client().didReceiveData(WebCore::SharedBuffer::wrapNSData(data));
     160        networkDataTask->didReceiveData(WebCore::SharedBuffer::wrapNSData(data));
    156161}
    157162
    … …  
    159164{
    160165    auto downloadID = _session->takeDownloadID([downloadTask taskIdentifier]);
    161     notImplemented();
    162166    if (auto* download = WebKit::NetworkProcess::singleton().downloadManager().download(downloadID))
    163167        download->didFinish();
    … …  
    184188        auto& downloadManager = WebKit::NetworkProcess::singleton().downloadManager();
    185189        auto download = std::make_unique<WebKit::Download>(downloadManager, downloadID);
    186         download->didStart([downloadTask currentRequest]);
     190        networkDataTask->transferSandboxExtensionToDownload(*download);
     191        ASSERT(WebCore::fileExists(networkDataTask->pendingDownloadLocation()));
     192        download->didCreateDestination(networkDataTask->pendingDownloadLocation());
    187193        download->didReceiveResponse([downloadTask response]);
    188194        auto pendingDownload = downloadManager.dataTaskBecameDownloadTask(downloadID, WTFMove(download));
    189195
    190         networkDataTask->client().didBecomeDownload();
     196        networkDataTask->didBecomeDownload();
    191197
    192198        _session->addDownloadID([downloadTask taskIdentifier], downloadID);
  • trunk/Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp

    r195357 r196984  
    3737#include "WebProcessPool.h"
    3838#include "WebProtectionSpace.h"
     39#include <WebCore/FileSystem.h>
    3940#include <wtf/text/CString.h>
    4041#include <wtf/text/WTFString.h>
    … …  
    171172}
    172173
    173 void DownloadProxy::decideDestinationWithSuggestedFilename(const String& filename, String& destination, bool& allowOverwrite, SandboxExtension::Handle& sandboxExtensionHandle)
    174 {
    175     allowOverwrite = false;
    176 
    177     if (!m_processPool)
    178         return;
    179 
    180     destination = m_processPool->downloadClient().decideDestinationWithSuggestedFilename(m_processPool.get(), this, filename, allowOverwrite);
    181 
     174#if USE(NETWORK_SESSION)
     175void DownloadProxy::decideDestinationWithSuggestedFilenameAsync(DownloadID downloadID, const String& suggestedFilename)
     176{
     177    bool allowOverwrite = false;
     178   
     179    if (!m_processPool)
     180        return;
     181   
     182    String destination = m_processPool->downloadClient().decideDestinationWithSuggestedFilename(m_processPool.get(), this, suggestedFilename, allowOverwrite);
     183   
     184    SandboxExtension::Handle sandboxExtensionHandle;
    182185    if (!destination.isNull())
    183186        SandboxExtension::createHandle(destination, SandboxExtension::ReadWrite, sandboxExtensionHandle);
    184 }
     187   
     188    if (NetworkProcessProxy* networkProcess = m_processPool->networkProcess())
     189        networkProcess->connection()->send(Messages::NetworkProcess::ContinueDecidePendingDownloadDestination(downloadID, destination, sandboxExtensionHandle), 0);
     190}
     191#else
     192void DownloadProxy::decideDestinationWithSuggestedFilename(const String& filename, String& destination, bool& allowOverwrite, SandboxExtension::Handle& sandboxExtensionHandle)
     193{
     194    allowOverwrite = false;
     195
     196    if (!m_processPool)
     197        return;
     198
     199    destination = m_processPool->downloadClient().decideDestinationWithSuggestedFilename(m_processPool.get(), this, filename, allowOverwrite);
     200
     201    if (!destination.isNull())
     202        SandboxExtension::createHandle(destination, SandboxExtension::ReadWrite, sandboxExtensionHandle);
     203}
     204#endif
    185205
    186206void DownloadProxy::didCreateDestination(const String& path)
  • trunk/Source/WebKit2/UIProcess/Downloads/DownloadProxy.h

    r195357 r196984  
    4848namespace WebKit {
    4949
     50class DownloadID;
    5051class DownloadProxyMap;
    5152class WebPageProxy;
    … …  
    8283    void didReceiveData(uint64_t length);
    8384    void shouldDecodeSourceDataOfMIMEType(const String& mimeType, bool& result);
     85#if !USE(NETWORK_SESSION)
    8486    void decideDestinationWithSuggestedFilename(const String& filename, String& destination, bool& allowOverwrite, SandboxExtension::Handle& sandboxExtensionHandle);
     87#endif
    8588    void didCreateDestination(const String& path);
    8689    void didFinish();
    … …  
    9093    void canAuthenticateAgainstProtectionSpace(const WebCore::ProtectionSpace&);
    9194    void willSendRequest(const WebCore::ResourceRequest& redirectRequest, const WebCore::ResourceResponse& redirectResponse);
     95    void decideDestinationWithSuggestedFilenameAsync(DownloadID, const String& suggestedFilename);
    9296#endif
    9397
  • trunk/Source/WebKit2/UIProcess/Downloads/DownloadProxy.messages.in

    r195357 r196984  
    2727    WillSendRequest(WebCore::ResourceRequest redirectRequest, WebCore::ResourceResponse redirectResponse));
    2828    CanAuthenticateAgainstProtectionSpace(WebCore::ProtectionSpace protectionSpace)
     29    DecideDestinationWithSuggestedFilenameAsync(WebKit::DownloadID downloadID, String suggestedFilename)
    2930#endif
    3031
    … …  
    3233    DidReceiveData(uint64_t length)
    3334    ShouldDecodeSourceDataOfMIMEType(String mimeType) -> (bool result)
     35#if !USE(NETWORK_SESSION)
    3436    DecideDestinationWithSuggestedFilename(String filename) -> (String destination, bool allowOverwrite, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
     37#endif
    3538    DidCreateDestination(String path)
    3639    DidFinish()
Note: See TracChangeset for help on using the changeset viewer.