Title: [174987] trunk/Source/WebKit2
Revision
174987
Author
je...@apple.com
Date
2014-10-21 10:46:11 -0700 (Tue, 21 Oct 2014)

Log Message

WKContext needs to provide an API to resume a download
https://bugs.webkit.org/show_bug.cgi?id=137507

Reviewed by Darin Adler.

This patch adds WKContextResumeDownload(), which is only supported on the Mac, and requires the
resume data from WKDownloadGetResumeData().

We have to create a sandbox extension for the partially downloaded file in the UI process so the
network or web process can resume writing to it.

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::resumeDownload):
Added, calls through to DownloadManager::resumeDownload().

* NetworkProcess/NetworkProcess.h:
Added resumeDownload().

* NetworkProcess/NetworkProcess.messages.in:
Added ResumeDownload message.

* Shared/Downloads/Download.h:
Added resume().

* Shared/Downloads/DownloadManager.cpp:
(WebKit::DownloadManager::resumeDownload):
Added. The URL being downloaded is part of the opaque resumeData, so we can't specify it when the
Download is constructed.

* Shared/Downloads/DownloadManager.h:
Added resumeDownload().

* Shared/Downloads/ios/DownloadIOS.mm:
(WebKit::Download::resume):
Added, not implemented on this platform.

* Shared/Downloads/mac/DownloadMac.mm:
(WebKit::Download::resume):
Added. Consumes the sandbox extension, resumes the download, and sets m_request after the
NSURLDownload has been created. Note that we already have code to revoke the sandbox extension when
the download is finished, canceled, or fails.

* Shared/Downloads/soup/DownloadSoup.cpp:
(WebKit::Download::resume):
Added, not implemented on this platform.

* UIProcess/API/C/WKContext.cpp:
(WKContextResumeDownload):
Added.

* UIProcess/API/C/WKContext.h:
Added WKContextResumeDownload().

* UIProcess/WebContext.cpp:
(WebKit::WebContext::resumeDownload):
Added. Creates a sandbox extension for the existing file and includes it in the message to the
network or web process.

* UIProcess/WebContext.h:
Added resumeDownload().

* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::resumeDownload):
Added, calls through to DownloadManager::resumeDownload().

* WebProcess/WebProcess.h:
Added resumeDownload().

* WebProcess/WebProcess.messages.in:
Added ResumeDownload message.

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (174986 => 174987)


--- trunk/Source/WebKit2/ChangeLog	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/ChangeLog	2014-10-21 17:46:11 UTC (rev 174987)
@@ -1,3 +1,76 @@
+2014-10-21  Jeff Miller  <je...@apple.com>
+
+        WKContext needs to provide an API to resume a download
+        https://bugs.webkit.org/show_bug.cgi?id=137507
+
+        Reviewed by Darin Adler.
+
+        This patch adds WKContextResumeDownload(), which is only supported on the Mac, and requires the
+        resume data from WKDownloadGetResumeData().
+
+        We have to create a sandbox extension for the partially downloaded file in the UI process so the
+        network or web process can resume writing to it.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::resumeDownload):
+        Added, calls through to DownloadManager::resumeDownload().
+
+        * NetworkProcess/NetworkProcess.h:
+        Added resumeDownload().
+
+        * NetworkProcess/NetworkProcess.messages.in:
+        Added ResumeDownload message.
+
+        * Shared/Downloads/Download.h:
+        Added resume().
+
+        * Shared/Downloads/DownloadManager.cpp:
+        (WebKit::DownloadManager::resumeDownload):
+        Added. The URL being downloaded is part of the opaque resumeData, so we can't specify it when the
+        Download is constructed.
+
+        * Shared/Downloads/DownloadManager.h:
+        Added resumeDownload().
+
+        * Shared/Downloads/ios/DownloadIOS.mm:
+        (WebKit::Download::resume):
+        Added, not implemented on this platform.
+
+        * Shared/Downloads/mac/DownloadMac.mm:
+        (WebKit::Download::resume):
+        Added. Consumes the sandbox extension, resumes the download, and sets m_request after the
+        NSURLDownload has been created. Note that we already have code to revoke the sandbox extension when
+        the download is finished, canceled, or fails.
+
+        * Shared/Downloads/soup/DownloadSoup.cpp:
+        (WebKit::Download::resume):
+        Added, not implemented on this platform.
+
+        * UIProcess/API/C/WKContext.cpp:
+        (WKContextResumeDownload):
+        Added.
+
+        * UIProcess/API/C/WKContext.h:
+        Added WKContextResumeDownload().
+
+        * UIProcess/WebContext.cpp:
+        (WebKit::WebContext::resumeDownload):
+        Added. Creates a sandbox extension for the existing file and includes it in the message to the
+        network or web process.
+
+        * UIProcess/WebContext.h:
+        Added resumeDownload().
+
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::resumeDownload):
+        Added, calls through to DownloadManager::resumeDownload().
+
+        * WebProcess/WebProcess.h:
+        Added resumeDownload().
+
+        * WebProcess/WebProcess.messages.in:
+        Added ResumeDownload message.
+
 2014-10-20  Michael Catanzaro  <mcatanz...@igalia.com>
 
         Change the default TLS errors policy to WEBKIT_TLS_ERRORS_POLICY_FAIL

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp (174986 => 174987)


--- trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp	2014-10-21 17:46:11 UTC (rev 174987)
@@ -236,6 +236,11 @@
     downloadManager().startDownload(downloadID, request);
 }
 
+void NetworkProcess::resumeDownload(uint64_t downloadID, const IPC::DataReference& resumeData, const String& path, const WebKit::SandboxExtension::Handle& sandboxExtensionHandle)
+{
+    downloadManager().resumeDownload(downloadID, resumeData, path, sandboxExtensionHandle);
+}
+
 void NetworkProcess::cancelDownload(uint64_t downloadID)
 {
     downloadManager().cancelDownload(downloadID);

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkProcess.h (174986 => 174987)


--- trunk/Source/WebKit2/NetworkProcess/NetworkProcess.h	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkProcess.h	2014-10-21 17:46:11 UTC (rev 174987)
@@ -113,6 +113,7 @@
     void ensurePrivateBrowsingSession(WebCore::SessionID);
     void destroyPrivateBrowsingSession(WebCore::SessionID);
     void downloadRequest(uint64_t downloadID, const WebCore::ResourceRequest&);
+    void resumeDownload(uint64_t downloadID, const IPC::DataReference& resumeData, const String& path, const SandboxExtension::Handle&);
     void cancelDownload(uint64_t downloadID);
     void setCacheModel(uint32_t);
     void allowSpecificHTTPSCertificateForHost(const WebCore::CertificateInfo&, const String& host);

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in (174986 => 174987)


--- trunk/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in	2014-10-21 17:46:11 UTC (rev 174987)
@@ -38,6 +38,7 @@
     DestroyPrivateBrowsingSession(WebCore::SessionID sessionID)
 
     DownloadRequest(uint64_t downloadID, WebCore::ResourceRequest request)
+    ResumeDownload(uint64_t downloadID, IPC::DataReference resumeData, String path, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
     CancelDownload(uint64_t downloadID)
 
     SetProcessSuppressionEnabled(bool flag)

Modified: trunk/Source/WebKit2/Shared/Downloads/Download.h (174986 => 174987)


--- trunk/Source/WebKit2/Shared/Downloads/Download.h	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/Shared/Downloads/Download.h	2014-10-21 17:46:11 UTC (rev 174987)
@@ -27,6 +27,7 @@
 #define Download_h
 
 #include "MessageSender.h"
+#include "SandboxExtension.h"
 #include <WebCore/ResourceRequest.h>
 #include <wtf/Noncopyable.h>
 
@@ -63,7 +64,6 @@
 
 class DownloadAuthenticationClient;
 class DownloadManager;
-class SandboxExtension;
 class WebPage;
 
 class Download : public IPC::MessageSender {
@@ -74,6 +74,7 @@
 
     void start();
     void startWithHandle(WebCore::ResourceHandle*, const WebCore::ResourceResponse&);
+    void resume(const IPC::DataReference& resumeData, const String& path, const SandboxExtension::Handle&);
     void cancel();
 
     uint64_t downloadID() const { return m_downloadID; }

Modified: trunk/Source/WebKit2/Shared/Downloads/DownloadManager.cpp (174986 => 174987)


--- trunk/Source/WebKit2/Shared/Downloads/DownloadManager.cpp	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/Shared/Downloads/DownloadManager.cpp	2014-10-21 17:46:11 UTC (rev 174987)
@@ -56,6 +56,16 @@
     m_downloads.add(downloadID, WTF::move(download));
 }
 
+void DownloadManager::resumeDownload(uint64_t downloadID, const IPC::DataReference& resumeData, const String& path, const SandboxExtension::Handle& sandboxExtensionHandle)
+{
+    // Download::resume() is responsible for setting the Download's resource request.
+    auto download = std::make_unique<Download>(*this, downloadID, ResourceRequest());
+
+    download->resume(resumeData, path, sandboxExtensionHandle);
+    ASSERT(!m_downloads.contains(downloadID));
+    m_downloads.add(downloadID, WTF::move(download));
+}
+
 void DownloadManager::cancelDownload(uint64_t downloadID)
 {
     Download* download = m_downloads.get(downloadID);

Modified: trunk/Source/WebKit2/Shared/Downloads/DownloadManager.h (174986 => 174987)


--- trunk/Source/WebKit2/Shared/Downloads/DownloadManager.h	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/Shared/Downloads/DownloadManager.h	2014-10-21 17:46:11 UTC (rev 174987)
@@ -26,6 +26,7 @@
 #ifndef DownloadManager_h
 #define DownloadManager_h
 
+#include "SandboxExtension.h"
 #include <wtf/Forward.h>
 #include <wtf/HashMap.h>
 #include <wtf/Noncopyable.h>
@@ -38,6 +39,7 @@
 
 namespace IPC {
 class Connection;
+class DataReference;
 }
 
 namespace WebKit {
@@ -65,6 +67,8 @@
     void startDownload(uint64_t downloadID, const WebCore::ResourceRequest&);
     void convertHandleToDownload(uint64_t downloadID, WebCore::ResourceHandle*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
 
+    void resumeDownload(uint64_t downloadID, const IPC::DataReference& resumeData, const String& path, const SandboxExtension::Handle&);
+
     void cancelDownload(uint64_t downloadID);
 
     void downloadFinished(Download*);

Modified: trunk/Source/WebKit2/Shared/Downloads/ios/DownloadIOS.mm (174986 => 174987)


--- trunk/Source/WebKit2/Shared/Downloads/ios/DownloadIOS.mm	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/Shared/Downloads/ios/DownloadIOS.mm	2014-10-21 17:46:11 UTC (rev 174987)
@@ -127,6 +127,11 @@
     notImplemented();
 }
 
+void Download::resume(const IPC::DataReference&, const String&, const SandboxExtension::Handle&)
+{
+    notImplemented();
+}
+
 void Download::startWithHandle(ResourceHandle* handle, const ResourceResponse& response)
 {
     // FIXME: For some reason the filename needs to be accessed or it may be incorrect after

Modified: trunk/Source/WebKit2/Shared/Downloads/mac/DownloadMac.mm (174986 => 174987)


--- trunk/Source/WebKit2/Shared/Downloads/mac/DownloadMac.mm	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/Shared/Downloads/mac/DownloadMac.mm	2014-10-21 17:46:11 UTC (rev 174987)
@@ -88,6 +88,26 @@
     [m_nsURLDownload setDeletesFileUponFailure:NO];
 }
 
+void Download::resume(const IPC::DataReference& resumeData, const String& path, const SandboxExtension::Handle& sandboxExtensionHandle)
+{
+    ASSERT(!m_nsURLDownload);
+    ASSERT(!m_delegate);
+
+    m_sandboxExtension = SandboxExtension::create(sandboxExtensionHandle);
+    if (m_sandboxExtension)
+        m_sandboxExtension->consume();
+
+    m_delegate = adoptNS([[WKDownloadAsDelegate alloc] initWithDownload:this]);
+
+    auto nsData = adoptNS([[NSData alloc] initWithBytes:resumeData.data() length:resumeData.size()]);
+    m_nsURLDownload = adoptNS([[NSURLDownload alloc] initWithResumeData:nsData.get() delegate:m_delegate.get() path:path]);
+
+    m_request = [m_nsURLDownload request];
+
+    // FIXME: Allow this to be changed by the client.
+    [m_nsURLDownload setDeletesFileUponFailure:NO];
+}
+
 void Download::cancel()
 {
     [m_nsURLDownload cancel];

Modified: trunk/Source/WebKit2/Shared/Downloads/soup/DownloadSoup.cpp (174986 => 174987)


--- trunk/Source/WebKit2/Shared/Downloads/soup/DownloadSoup.cpp	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/Shared/Downloads/soup/DownloadSoup.cpp	2014-10-21 17:46:11 UTC (rev 174987)
@@ -236,6 +236,11 @@
     static_cast<DownloadClient*>(m_downloadClient.get())->handleResponseLater(response);
 }
 
+void Download::resume(const IPC::DataReference&, const String&, const SandboxExtension::Handle&)
+{
+    notImplemented();
+}
+
 void Download::cancel()
 {
     if (!m_resourceHandle)

Modified: trunk/Source/WebKit2/UIProcess/API/C/WKContext.cpp (174986 => 174987)


--- trunk/Source/WebKit2/UIProcess/API/C/WKContext.cpp	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKContext.cpp	2014-10-21 17:46:11 UTC (rev 174987)
@@ -282,6 +282,11 @@
     return toAPI(toImpl(contextRef)->download(0, toImpl(requestRef)->resourceRequest()));
 }
 
+WKDownloadRef WKContextResumeDownload(WKContextRef contextRef, WKDataRef resumeData, WKStringRef path)
+{
+    return toAPI(toImpl(contextRef)->resumeDownload(toImpl(resumeData), toWTFString(path)));
+}
+
 void WKContextSetInitializationUserDataForInjectedBundle(WKContextRef contextRef,  WKTypeRef userDataRef)
 {
     toImpl(contextRef)->setInjectedBundleInitializationUserData(toImpl(userDataRef));

Modified: trunk/Source/WebKit2/UIProcess/API/C/WKContext.h (174986 => 174987)


--- trunk/Source/WebKit2/UIProcess/API/C/WKContext.h	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKContext.h	2014-10-21 17:46:11 UTC (rev 174987)
@@ -111,6 +111,7 @@
 WK_EXPORT void WKContextSetConnectionClient(WKContextRef context, const WKContextConnectionClientBase* client);
 
 WK_EXPORT WKDownloadRef WKContextDownloadURLRequest(WKContextRef context, const WKURLRequestRef request);
+WK_EXPORT WKDownloadRef WKContextResumeDownload(WKContextRef context, WKDataRef resumeData, WKStringRef path);
 
 WK_EXPORT void WKContextSetInitializationUserDataForInjectedBundle(WKContextRef context, WKTypeRef userData);
 WK_EXPORT void WKContextPostMessageToInjectedBundle(WKContextRef context, WKStringRef messageName, WKTypeRef messageBody);

Modified: trunk/Source/WebKit2/UIProcess/WebContext.cpp (174986 => 174987)


--- trunk/Source/WebKit2/UIProcess/WebContext.cpp	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/UIProcess/WebContext.cpp	2014-10-21 17:46:11 UTC (rev 174987)
@@ -889,6 +889,25 @@
     return downloadProxy;
 }
 
+DownloadProxy* WebContext::resumeDownload(const API::Data* resumeData, const String& path)
+{
+    DownloadProxy* downloadProxy = createDownloadProxy(ResourceRequest());
+
+    SandboxExtension::Handle sandboxExtensionHandle;
+    if (!path.isEmpty())
+        SandboxExtension::createHandle(path, SandboxExtension::ReadWrite, sandboxExtensionHandle);
+
+#if ENABLE(NETWORK_PROCESS)
+    if (usesNetworkProcess() && networkProcess()) {
+        networkProcess()->send(Messages::NetworkProcess::ResumeDownload(downloadProxy->downloadID(), resumeData->dataReference(), path, sandboxExtensionHandle), 0);
+        return downloadProxy;
+    }
+#endif
+
+    m_processes[0]->send(Messages::WebProcess::ResumeDownload(downloadProxy->downloadID(), resumeData->dataReference(), path, sandboxExtensionHandle), 0);
+    return downloadProxy;
+}
+
 void WebContext::postMessageToInjectedBundle(const String& messageName, API::Object* messageBody)
 {
     if (m_processes.isEmpty()) {

Modified: trunk/Source/WebKit2/UIProcess/WebContext.h (174986 => 174987)


--- trunk/Source/WebKit2/UIProcess/WebContext.h	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/UIProcess/WebContext.h	2014-10-21 17:46:11 UTC (rev 174987)
@@ -179,6 +179,7 @@
     const String& injectedBundlePath() const { return m_injectedBundlePath; }
 
     DownloadProxy* download(WebPageProxy* initiatingPage, const WebCore::ResourceRequest&);
+    DownloadProxy* resumeDownload(const API::Data* resumeData, const String& path);
 
     void setInjectedBundleInitializationUserData(PassRefPtr<API::Object> userData) { m_injectedBundleInitializationUserData = userData; }
 

Modified: trunk/Source/WebKit2/WebProcess/WebProcess.cpp (174986 => 174987)


--- trunk/Source/WebKit2/WebProcess/WebProcess.cpp	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.cpp	2014-10-21 17:46:11 UTC (rev 174987)
@@ -1057,6 +1057,11 @@
     downloadManager().startDownload(downloadID, requestWithOriginalURL);
 }
 
+void WebProcess::resumeDownload(uint64_t downloadID, const IPC::DataReference& resumeData, const String& path, const WebKit::SandboxExtension::Handle& sandboxExtensionHandle)
+{
+    downloadManager().resumeDownload(downloadID, resumeData, path, sandboxExtensionHandle);
+}
+
 void WebProcess::cancelDownload(uint64_t downloadID)
 {
     downloadManager().cancelDownload(downloadID);

Modified: trunk/Source/WebKit2/WebProcess/WebProcess.h (174986 => 174987)


--- trunk/Source/WebKit2/WebProcess/WebProcess.h	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.h	2014-10-21 17:46:11 UTC (rev 174987)
@@ -236,6 +236,7 @@
     void stopMemorySampler();
 
     void downloadRequest(uint64_t downloadID, uint64_t initiatingPageID, const WebCore::ResourceRequest&);
+    void resumeDownload(uint64_t downloadID, const IPC::DataReference& resumeData, const String& path, const SandboxExtension::Handle&);
     void cancelDownload(uint64_t downloadID);
 
     void setTextCheckerState(const TextCheckerState&);

Modified: trunk/Source/WebKit2/WebProcess/WebProcess.messages.in (174986 => 174987)


--- trunk/Source/WebKit2/WebProcess/WebProcess.messages.in	2014-10-21 17:32:09 UTC (rev 174986)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.messages.in	2014-10-21 17:46:11 UTC (rev 174987)
@@ -61,8 +61,9 @@
     void StopMemorySampler();
 
     # Downloads. This should really be in a Download.messages.in, but it seemed unnecessary to create a new file just for
-    # two messages.
+    # three messages.
     DownloadRequest(uint64_t downloadID, uint64_t initiatingPageID, WebCore::ResourceRequest request)
+    ResumeDownload(uint64_t downloadID, IPC::DataReference resumeData, String path, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
     CancelDownload(uint64_t downloadID)
 
     SetTextCheckerState(WebKit::TextCheckerState textCheckerState)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to