Title: [226470] trunk/Source
Revision
226470
Author
wenson_hs...@apple.com
Date
2018-01-05 15:48:35 -0800 (Fri, 05 Jan 2018)

Log Message

[Attachment Support] Add a way to write blob data to a file URL from the UI process
https://bugs.webkit.org/show_bug.cgi?id=181236

Reviewed by Brady Eidson.

Source/WebCore:

Add support for writing a blob to a designated file path. See comments below for more detail. No new tests, as
there change in behavior yet. See part 2: https://bugs.webkit.org/show_bug.cgi?id=181199.

* page/DragController.cpp:
(WebCore::DragController::dragAttachmentElement):
* platform/PromisedBlobInfo.h:

Remove PromisedBlobData entirely. This was added with the premise of having the web process deliver blob data to
the UI process. However, the new approach I'm taking just has the UI process tell the network process to write
a blob to a given location, so a data structure to deliver blob data over IPC is no longer necessary.

(WebCore::PromisedBlobData::hasData const): Deleted.
(WebCore::PromisedBlobData::hasFile const): Deleted.
(WebCore::PromisedBlobData::operator bool const): Deleted.
(WebCore::PromisedBlobData::fulfills const): Deleted.
* platform/network/BlobRegistryImpl.cpp:
(WebCore::BlobRegistryImpl::populateBlobsForFileWriting):

Introduce a new helper to build a list of blob data for file writing.

(WebCore::writeFilePathsOrDataBuffersToFile):

Introduce a new static helper to write blob data (a list of file paths and data buffers) to a given file handle.
Automatically closes the given file handle upon exit.

(WebCore::BlobRegistryImpl::writeBlobsToTemporaryFiles):
(WebCore::BlobRegistryImpl::writeBlobToFilePath):

Pull out common logic in writeBlobsToTemporaryFiles and writeBlobToFilePath into helper methods (see above), and
refactor both methods to use the helpers.

* platform/network/BlobRegistryImpl.h:

Source/WebKit:

Add support for writing a blob to a designated file path. In WebKit, this is mainly plumbing writeBlobToFilePath
through WebPageProxy to the network process.

* NetworkProcess/FileAPI/NetworkBlobRegistry.cpp:
(WebKit::NetworkBlobRegistry::writeBlobToFilePath):

Call out to the BlobRegistryImpl to write blobs to the file path. Additionally grant sandbox extensions for any
file-backed blob parts corresponding to the given blob URL.

(WebKit::NetworkBlobRegistry::filesInBlob):

Introduce a version of filesInBlob that doesn't check against the NetworkConnectionToWebProcess. This is used
when the UI process is the driver for writing a blob.

* NetworkProcess/FileAPI/NetworkBlobRegistry.h:
* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::writeBlobToFilePath):

Temporarily grant sandbox access to the given file path.

* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkProcess.messages.in:
* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<PromisedBlobInfo>::encode):
(IPC::ArgumentCoder<PromisedBlobInfo>::decode):
(IPC::ArgumentCoder<PromisedBlobData>::encode): Deleted.
(IPC::ArgumentCoder<PromisedBlobData>::decode): Deleted.

Remove PromisedBlobData (see WebCore/ChangeLog for more information).

* Shared/WebCoreArgumentCoders.h:
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::didClose):

If the network process is terminated, flush any pending callbacks in m_writeBlobToFilePathCallbackMap, passing
in a failure result (success := false) and clearing the callback map.

(WebKit::NetworkProcessProxy::writeBlobToFilePath):
(WebKit::NetworkProcessProxy::didWriteBlobToFilePath):
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/Network/NetworkProcessProxy.messages.in:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::writeBlobToFilePath):
* UIProcess/WebPageProxy.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (226469 => 226470)


--- trunk/Source/WebCore/ChangeLog	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebCore/ChangeLog	2018-01-05 23:48:35 UTC (rev 226470)
@@ -1,3 +1,43 @@
+2018-01-05  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        [Attachment Support] Add a way to write blob data to a file URL from the UI process
+        https://bugs.webkit.org/show_bug.cgi?id=181236
+
+        Reviewed by Brady Eidson.
+
+        Add support for writing a blob to a designated file path. See comments below for more detail. No new tests, as
+        there change in behavior yet. See part 2: https://bugs.webkit.org/show_bug.cgi?id=181199.
+
+        * page/DragController.cpp:
+        (WebCore::DragController::dragAttachmentElement):
+        * platform/PromisedBlobInfo.h:
+
+        Remove PromisedBlobData entirely. This was added with the premise of having the web process deliver blob data to
+        the UI process. However, the new approach I'm taking just has the UI process tell the network process to write
+        a blob to a given location, so a data structure to deliver blob data over IPC is no longer necessary.
+
+        (WebCore::PromisedBlobData::hasData const): Deleted.
+        (WebCore::PromisedBlobData::hasFile const): Deleted.
+        (WebCore::PromisedBlobData::operator bool const): Deleted.
+        (WebCore::PromisedBlobData::fulfills const): Deleted.
+        * platform/network/BlobRegistryImpl.cpp:
+        (WebCore::BlobRegistryImpl::populateBlobsForFileWriting):
+
+        Introduce a new helper to build a list of blob data for file writing.
+
+        (WebCore::writeFilePathsOrDataBuffersToFile):
+
+        Introduce a new static helper to write blob data (a list of file paths and data buffers) to a given file handle.
+        Automatically closes the given file handle upon exit.
+
+        (WebCore::BlobRegistryImpl::writeBlobsToTemporaryFiles):
+        (WebCore::BlobRegistryImpl::writeBlobToFilePath):
+
+        Pull out common logic in writeBlobsToTemporaryFiles and writeBlobToFilePath into helper methods (see above), and
+        refactor both methods to use the helpers.
+
+        * platform/network/BlobRegistryImpl.h:
+
 2018-01-05  Alex Christensen  <achristen...@webkit.org>
 
         Forbid < and > in URL hosts

Modified: trunk/Source/WebCore/page/DragController.cpp (226469 => 226470)


--- trunk/Source/WebCore/page/DragController.cpp	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebCore/page/DragController.cpp	2018-01-05 23:48:35 UTC (rev 226470)
@@ -1289,10 +1289,7 @@
 #endif
 
     auto& file = *attachment.file();
-    auto blobURL = file.url().string();
-    bool isFileBacked = !file.path().isEmpty();
-    auto blobType = isFileBacked ? PromisedBlobType::FileBacked : PromisedBlobType::DataBacked;
-    m_client.prepareToDragPromisedBlob({ blobURL, file.type(), file.name(), blobType, additionalTypes, additionalData });
+    m_client.prepareToDragPromisedBlob({ file.url(), file.type(), file.name(), additionalTypes, additionalData });
 
     return true;
 }

Modified: trunk/Source/WebCore/platform/PromisedBlobInfo.h (226469 => 226470)


--- trunk/Source/WebCore/platform/PromisedBlobInfo.h	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebCore/platform/PromisedBlobInfo.h	2018-01-05 23:48:35 UTC (rev 226470)
@@ -25,17 +25,15 @@
 
 #pragma once
 
-#include "SharedBuffer.h"
-
 namespace WebCore {
 
-enum class PromisedBlobType { DataBacked, FileBacked };
+class SharedBuffer;
+class URL;
 
 struct PromisedBlobInfo {
-    String blobURL;
+    URL blobURL;
     String contentType;
     String filename;
-    PromisedBlobType blobType;
 
     Vector<String> additionalTypes;
     Vector<RefPtr<SharedBuffer>> additionalData;
@@ -43,29 +41,5 @@
     operator bool() const { return !blobURL.isEmpty(); }
 };
 
-struct PromisedBlobData {
-    String blobURL;
-    String filePath;
-    RefPtr<SharedBuffer> data;
-
-    bool hasData() const { return data; }
-    bool hasFile() const { return !filePath.isEmpty(); }
-    operator bool() const { return !blobURL.isEmpty(); }
-    bool fulfills(const PromisedBlobInfo& info) const { return *this && blobURL == info.blobURL; }
-};
-
 } // namespace WebCore
 
-namespace WTF {
-
-template<typename> struct EnumTraits;
-template<typename E, E...> struct EnumValues;
-
-template<> struct EnumTraits<WebCore::PromisedBlobType> {
-    using values = EnumValues<WebCore::PromisedBlobType,
-    WebCore::PromisedBlobType::DataBacked,
-    WebCore::PromisedBlobType::FileBacked
-    >;
-};
-
-} // namespace WTF

Modified: trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp (226469 => 226470)


--- trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp	2018-01-05 23:48:35 UTC (rev 226470)
@@ -245,24 +245,15 @@
     return queue;
 }
 
-struct BlobForFileWriting {
-    String blobURL;
-    Vector<std::pair<String, ThreadSafeDataBuffer>> filePathsOrDataBuffers;
-};
-
-void BlobRegistryImpl::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, Function<void (const Vector<String>& filePaths)>&& completionHandler)
+bool BlobRegistryImpl::populateBlobsForFileWriting(const Vector<String>& blobURLs, Vector<BlobForFileWriting>& blobsForWriting)
 {
-    Vector<BlobForFileWriting> blobsForWriting;
     for (auto& url : blobURLs) {
         blobsForWriting.append({ });
         blobsForWriting.last().blobURL = url.isolatedCopy();
 
         auto* blobData = getBlobDataFromURL({ ParsedURLString, url });
-        if (!blobData) {
-            Vector<String> filePaths;
-            completionHandler(filePaths);
-            return;
-        }
+        if (!blobData)
+            return false;
 
         for (auto& item : blobData->items()) {
             switch (item.type()) {
@@ -277,49 +268,58 @@
             }
         }
     }
+    return true;
+}
 
-    blobUtilityQueue().dispatch([blobsForWriting = WTFMove(blobsForWriting), completionHandler = WTFMove(completionHandler)]() mutable {
-        Vector<String> filePaths;
+static bool writeFilePathsOrDataBuffersToFile(const Vector<std::pair<String, ThreadSafeDataBuffer>>& filePathsOrDataBuffers, FileSystem::PlatformFileHandle file, const String& path)
+{
+    auto fileCloser = WTF::makeScopeExit([file]() mutable {
+        FileSystem::closeFile(file);
+    });
 
-        auto performWriting = [blobsForWriting = WTFMove(blobsForWriting), &filePaths]() {
-            for (auto& blob : blobsForWriting) {
-                FileSystem::PlatformFileHandle file;
-                String tempFilePath = FileSystem::openTemporaryFile(ASCIILiteral("Blob"), file);
+    if (path.isEmpty() || !FileSystem::isHandleValid(file)) {
+        LOG_ERROR("Failed to open temporary file for writing a Blob");
+        return false;
+    }
 
-                auto fileCloser = WTF::makeScopeExit([file]() mutable {
-                    FileSystem::closeFile(file);
-                });
-                
-                if (tempFilePath.isEmpty() || !FileSystem::isHandleValid(file)) {
-                    LOG_ERROR("Failed to open temporary file for writing a Blob to IndexedDB");
-                    return false;
-                }
+    for (auto& part : filePathsOrDataBuffers) {
+        if (part.second.data()) {
+            int length = part.second.data()->size();
+            if (FileSystem::writeToFile(file, reinterpret_cast<const char*>(part.second.data()->data()), length) != length) {
+                LOG_ERROR("Failed writing a Blob to temporary file");
+                return false;
+            }
+        } else {
+            ASSERT(!part.first.isEmpty());
+            if (!FileSystem::appendFileContentsToFileHandle(part.first, file)) {
+                LOG_ERROR("Failed copying File contents to a Blob temporary file (%s to %s)", part.first.utf8().data(), path.utf8().data());
+                return false;
+            }
+        }
+    }
+    return true;
+}
 
-                for (auto& part : blob.filePathsOrDataBuffers) {
-                    if (part.second.data()) {
-                        int length = part.second.data()->size();
-                        if (FileSystem::writeToFile(file, reinterpret_cast<const char*>(part.second.data()->data()), length) != length) {
-                            LOG_ERROR("Failed writing a Blob to temporary file for storage in IndexedDB");
-                            return false;
-                        }
-                    } else {
-                        ASSERT(!part.first.isEmpty());
-                        if (!FileSystem::appendFileContentsToFileHandle(part.first, file)) {
-                            LOG_ERROR("Failed copying File contents to a Blob temporary file for storage in IndexedDB (%s to %s)", part.first.utf8().data(), tempFilePath.utf8().data());
-                            return false;
-                        }
-                    }
-                }
+void BlobRegistryImpl::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, Function<void(const Vector<String>& filePaths)>&& completionHandler)
+{
+    Vector<BlobForFileWriting> blobsForWriting;
+    if (!populateBlobsForFileWriting(blobURLs, blobsForWriting)) {
+        completionHandler({ });
+        return;
+    }
 
-                filePaths.append(tempFilePath.isolatedCopy());
+    blobUtilityQueue().dispatch([blobsForWriting = WTFMove(blobsForWriting), completionHandler = WTFMove(completionHandler)]() mutable {
+        Vector<String> filePaths;
+        for (auto& blob : blobsForWriting) {
+            FileSystem::PlatformFileHandle file;
+            String tempFilePath = FileSystem::openTemporaryFile(ASCIILiteral("Blob"), file);
+            if (!writeFilePathsOrDataBuffersToFile(blob.filePathsOrDataBuffers, file, tempFilePath)) {
+                filePaths.clear();
+                break;
             }
+            filePaths.append(tempFilePath.isolatedCopy());
+        }
 
-            return true;
-        };
-
-        if (!performWriting())
-            filePaths.clear();
-
         callOnMainThread([completionHandler = WTFMove(completionHandler), filePaths = WTFMove(filePaths)]() {
             completionHandler(filePaths);
         });
@@ -326,4 +326,20 @@
     });
 }
 
+void BlobRegistryImpl::writeBlobToFilePath(const URL& blobURL, const String& path, Function<void(bool success)>&& completionHandler)
+{
+    Vector<BlobForFileWriting> blobsForWriting;
+    if (!populateBlobsForFileWriting({ blobURL }, blobsForWriting) || blobsForWriting.size() != 1) {
+        completionHandler(false);
+        return;
+    }
+
+    blobUtilityQueue().dispatch([path, blobsForWriting = WTFMove(blobsForWriting), completionHandler = WTFMove(completionHandler)]() mutable {
+        bool success = writeFilePathsOrDataBuffersToFile(blobsForWriting.first().filePathsOrDataBuffers, FileSystem::openFile(path, FileSystem::FileOpenMode::Write), path);
+        callOnMainThread([success, completionHandler = WTFMove(completionHandler)]() {
+            completionHandler(success);
+        });
+    });
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/network/BlobRegistryImpl.h (226469 => 226470)


--- trunk/Source/WebCore/platform/network/BlobRegistryImpl.h	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebCore/platform/network/BlobRegistryImpl.h	2018-01-05 23:48:35 UTC (rev 226470)
@@ -44,6 +44,7 @@
 class ResourceHandle;
 class ResourceHandleClient;
 class ResourceRequest;
+class ThreadSafeDataBuffer;
 
 // BlobRegistryImpl is not thread-safe. It should only be called from main thread.
 class WEBCORE_EXPORT BlobRegistryImpl final : public BlobRegistry {
@@ -54,6 +55,7 @@
     BlobData* getBlobDataFromURL(const URL&) const;
 
     Ref<ResourceHandle> createResourceHandle(const ResourceRequest&, ResourceHandleClient*);
+    void writeBlobToFilePath(const URL& blobURL, const String& path, Function<void(bool success)>&& completionHandler);
 
 private:
     void appendStorageItems(BlobData*, const BlobDataItemList&, long long offset, long long length);
@@ -70,6 +72,13 @@
 
     void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, Function<void (const Vector<String>& filePaths)>&& completionHandler) override;
 
+    struct BlobForFileWriting {
+        String blobURL;
+        Vector<std::pair<String, ThreadSafeDataBuffer>> filePathsOrDataBuffers;
+    };
+
+    bool populateBlobsForFileWriting(const Vector<String>& blobURLs, Vector<BlobForFileWriting>&);
+
     HashMap<String, RefPtr<BlobData>> m_blobs;
 };
 

Modified: trunk/Source/WebKit/ChangeLog (226469 => 226470)


--- trunk/Source/WebKit/ChangeLog	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebKit/ChangeLog	2018-01-05 23:48:35 UTC (rev 226470)
@@ -1,3 +1,55 @@
+2018-01-05  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        [Attachment Support] Add a way to write blob data to a file URL from the UI process
+        https://bugs.webkit.org/show_bug.cgi?id=181236
+
+        Reviewed by Brady Eidson.
+
+        Add support for writing a blob to a designated file path. In WebKit, this is mainly plumbing writeBlobToFilePath
+        through WebPageProxy to the network process.
+
+        * NetworkProcess/FileAPI/NetworkBlobRegistry.cpp:
+        (WebKit::NetworkBlobRegistry::writeBlobToFilePath):
+
+        Call out to the BlobRegistryImpl to write blobs to the file path. Additionally grant sandbox extensions for any
+        file-backed blob parts corresponding to the given blob URL.
+
+        (WebKit::NetworkBlobRegistry::filesInBlob):
+
+        Introduce a version of filesInBlob that doesn't check against the NetworkConnectionToWebProcess. This is used
+        when the UI process is the driver for writing a blob.
+
+        * NetworkProcess/FileAPI/NetworkBlobRegistry.h:
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::writeBlobToFilePath):
+
+        Temporarily grant sandbox access to the given file path.
+
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/NetworkProcess.messages.in:
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder<PromisedBlobInfo>::encode):
+        (IPC::ArgumentCoder<PromisedBlobInfo>::decode):
+        (IPC::ArgumentCoder<PromisedBlobData>::encode): Deleted.
+        (IPC::ArgumentCoder<PromisedBlobData>::decode): Deleted.
+
+        Remove PromisedBlobData (see WebCore/ChangeLog for more information).
+
+        * Shared/WebCoreArgumentCoders.h:
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::didClose):
+
+        If the network process is terminated, flush any pending callbacks in m_writeBlobToFilePathCallbackMap, passing
+        in a failure result (success := false) and clearing the callback map.
+
+        (WebKit::NetworkProcessProxy::writeBlobToFilePath):
+        (WebKit::NetworkProcessProxy::didWriteBlobToFilePath):
+        * UIProcess/Network/NetworkProcessProxy.h:
+        * UIProcess/Network/NetworkProcessProxy.messages.in:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::writeBlobToFilePath):
+        * UIProcess/WebPageProxy.h:
+
 2018-01-05  Dan Bernstein  <m...@apple.com>
 
         Add injected bundle equivalents of DOMHTMLDocument (DOMHTMLDocumentExtensions)

Modified: trunk/Source/WebKit/NetworkProcess/FileAPI/NetworkBlobRegistry.cpp (226469 => 226470)


--- trunk/Source/WebKit/NetworkProcess/FileAPI/NetworkBlobRegistry.cpp	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebKit/NetworkProcess/FileAPI/NetworkBlobRegistry.cpp	2018-01-05 23:48:35 UTC (rev 226470)
@@ -140,6 +140,25 @@
     blobRegistry().writeBlobsToTemporaryFiles(blobURLs, WTFMove(completionHandler));
 }
 
+void NetworkBlobRegistry::writeBlobToFilePath(const URL& blobURL, const String& path, Function<void(bool success)>&& completionHandler)
+{
+    if (!blobRegistry().isBlobRegistryImpl()) {
+        completionHandler(false);
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    auto blobFiles = filesInBlob({ ParsedURLString, blobURL });
+    for (auto& file : blobFiles)
+        file->prepareForFileAccess();
+
+    static_cast<BlobRegistryImpl&>(blobRegistry()).writeBlobToFilePath(blobURL, path, [blobFiles = WTFMove(blobFiles), completionHandler = WTFMove(completionHandler)] (bool success) {
+        for (auto& file : blobFiles)
+            file->revokeFileAccess();
+        completionHandler(success);
+    });
+}
+
 void NetworkBlobRegistry::connectionToWebProcessDidClose(NetworkConnectionToWebProcess* connection)
 {
     if (!m_blobsForConnection.contains(connection))
@@ -155,12 +174,17 @@
 Vector<RefPtr<BlobDataFileReference>> NetworkBlobRegistry::filesInBlob(NetworkConnectionToWebProcess& connection, const WebCore::URL& url)
 {
     if (!m_blobsForConnection.contains(&connection) || !m_blobsForConnection.find(&connection)->value.contains(url))
-        return Vector<RefPtr<BlobDataFileReference>>();
+        return { };
 
+    return filesInBlob(url);
+}
+
+Vector<RefPtr<BlobDataFileReference>> NetworkBlobRegistry::filesInBlob(const URL& url)
+{
     ASSERT(blobRegistry().isBlobRegistryImpl());
     BlobData* blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(url);
     if (!blobData)
-        return Vector<RefPtr<BlobDataFileReference>>();
+        return { };
 
     Vector<RefPtr<BlobDataFileReference>> result;
     for (const BlobDataItem& item : blobData->items()) {

Modified: trunk/Source/WebKit/NetworkProcess/FileAPI/NetworkBlobRegistry.h (226469 => 226470)


--- trunk/Source/WebKit/NetworkProcess/FileAPI/NetworkBlobRegistry.h	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebKit/NetworkProcess/FileAPI/NetworkBlobRegistry.h	2018-01-05 23:48:35 UTC (rev 226470)
@@ -54,10 +54,12 @@
     void unregisterBlobURL(NetworkConnectionToWebProcess*, const WebCore::URL&);
     uint64_t blobSize(NetworkConnectionToWebProcess*, const WebCore::URL&);
     void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, Function<void (const Vector<String>&)>&& completionHandler);
+    void writeBlobToFilePath(const WebCore::URL& blobURL, const String& path, Function<void(bool success)>&& completionHandler);
 
     void connectionToWebProcessDidClose(NetworkConnectionToWebProcess*);
 
     Vector<RefPtr<WebCore::BlobDataFileReference>> filesInBlob(NetworkConnectionToWebProcess&, const WebCore::URL&);
+    Vector<RefPtr<WebCore::BlobDataFileReference>> filesInBlob(const WebCore::URL&);
 
 private:
     ~NetworkBlobRegistry();

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (226469 => 226470)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2018-01-05 23:48:35 UTC (rev 226470)
@@ -36,6 +36,7 @@
 #include "LegacyCustomProtocolManager.h"
 #endif
 #include "Logging.h"
+#include "NetworkBlobRegistry.h"
 #include "NetworkConnectionToWebProcess.h"
 #include "NetworkProcessCreationParameters.h"
 #include "NetworkProcessPlatformStrategies.h"
@@ -332,6 +333,21 @@
         handler();
 }
 
+void NetworkProcess::writeBlobToFilePath(const WebCore::URL& url, const String& path, SandboxExtension::Handle&& handleForWriting, uint64_t requestID)
+{
+    auto extension = SandboxExtension::create(WTFMove(handleForWriting));
+    if (!extension) {
+        parentProcessConnection()->send(Messages::NetworkProcessProxy::DidWriteBlobToFilePath(false, requestID), 0);
+        return;
+    }
+
+    extension->consume();
+    NetworkBlobRegistry::singleton().writeBlobToFilePath(url, path, [this, extension = WTFMove(extension), requestID] (bool success) {
+        extension->revoke();
+        parentProcessConnection()->send(Messages::NetworkProcessProxy::DidWriteBlobToFilePath(success, requestID), 0);
+    });
+}
+
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
 void NetworkProcess::updatePrevalentDomainsToPartitionOrBlockCookies(PAL::SessionID sessionID, const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, bool shouldClearFirst)
 {

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (226469 => 226470)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2018-01-05 23:48:35 UTC (rev 226470)
@@ -225,6 +225,8 @@
 
     void didGrantSandboxExtensionsToStorageProcessForBlobs(uint64_t requestID);
 
+    void writeBlobToFilePath(const WebCore::URL&, const String& path, SandboxExtension::Handle&&, uint64_t requestID);
+
 #if USE(SOUP)
     void setIgnoreTLSErrors(bool);
     void userPreferredLanguagesChanged(const Vector<String>&);

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (226469 => 226470)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2018-01-05 23:48:35 UTC (rev 226470)
@@ -79,6 +79,8 @@
 
     DidGrantSandboxExtensionsToStorageProcessForBlobs(uint64_t requestID)
 
+    WriteBlobToFilePath(WebCore::URL blobURL, String path, WebKit::SandboxExtension::Handle handle, uint64_t callbackID)
+
     PreconnectTo(WebCore::URL url, enum WebCore::StoredCredentialsPolicy storedCredentialsPolicy);
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)

Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp (226469 => 226470)


--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp	2018-01-05 23:48:35 UTC (rev 226470)
@@ -2746,33 +2746,11 @@
     return {{ WTFMove(*displayName), WTFMove(*type) }};
 }
 
-void ArgumentCoder<PromisedBlobData>::encode(Encoder& encoder, const PromisedBlobData& data)
-{
-    encoder << data.blobURL;
-    encoder << data.filePath;
-    encodeSharedBuffer(encoder, data.data.get());
-}
-
-bool ArgumentCoder<PromisedBlobData>::decode(Decoder& decoder, PromisedBlobData& data)
-{
-    if (!decoder.decode(data.blobURL))
-        return false;
-
-    if (!decoder.decode(data.filePath))
-        return false;
-
-    if (!decodeSharedBuffer(decoder, data.data))
-        return false;
-
-    return true;
-}
-
 void ArgumentCoder<PromisedBlobInfo>::encode(Encoder& encoder, const PromisedBlobInfo& info)
 {
     encoder << info.blobURL;
     encoder << info.contentType;
     encoder << info.filename;
-    encoder.encodeEnum(info.blobType);
     encodeTypesAndData(encoder, info.additionalTypes, info.additionalData);
 }
 
@@ -2787,9 +2765,6 @@
     if (!decoder.decode(info.filename))
         return false;
 
-    if (!decoder.decode(info.blobType))
-        return false;
-
     if (!decodeTypesAndData(decoder, info.additionalTypes, info.additionalData))
         return false;
 

Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h (226469 => 226470)


--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h	2018-01-05 23:48:35 UTC (rev 226470)
@@ -103,7 +103,6 @@
 struct PasteboardCustomData;
 struct PasteboardURL;
 struct PluginInfo;
-struct PromisedBlobData;
 struct PromisedBlobInfo;
 struct RecentSearch;
 struct ResourceLoadStatistics;
@@ -685,11 +684,6 @@
     static std::optional<WebCore::MediaSelectionOption> decode(Decoder&);
 };
 
-template<> struct ArgumentCoder<WebCore::PromisedBlobData> {
-    static void encode(Encoder&, const WebCore::PromisedBlobData&);
-    static bool decode(Decoder&, WebCore::PromisedBlobData&);
-};
-
 template<> struct ArgumentCoder<WebCore::PromisedBlobInfo> {
     static void encode(Encoder&, const WebCore::PromisedBlobInfo&);
     static bool decode(Decoder&, WebCore::PromisedBlobInfo&);

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (226469 => 226470)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2018-01-05 23:48:35 UTC (rev 226470)
@@ -245,6 +245,10 @@
 
     m_tokenForHoldingLockedFiles = nullptr;
 
+    for (auto& callback : m_writeBlobToFilePathCallbackMap.values())
+        callback(false);
+    m_writeBlobToFilePathCallbackMap.clear();
+
     // This may cause us to be deleted.
     networkProcessCrashed();
 }
@@ -458,6 +462,30 @@
         send(Messages::NetworkProcess::ProcessDidResume(), 0);
 }
 
+void NetworkProcessProxy::writeBlobToFilePath(const WebCore::URL& url, const String& path, CompletionHandler<void(bool)>&& callback)
+{
+    if (!canSendMessage()) {
+        callback(false);
+        return;
+    }
+
+    static uint64_t writeBlobToFilePathCallbackIdentifiers = 0;
+    uint64_t callbackID = ++writeBlobToFilePathCallbackIdentifiers;
+    m_writeBlobToFilePathCallbackMap.add(callbackID, WTFMove(callback));
+
+    SandboxExtension::Handle handleForWriting;
+    SandboxExtension::createHandle(path, SandboxExtension::Type::ReadWrite, handleForWriting);
+    send(Messages::NetworkProcess::WriteBlobToFilePath(url, path, handleForWriting, callbackID), 0);
+}
+
+void NetworkProcessProxy::didWriteBlobToFilePath(bool success, uint64_t callbackID)
+{
+    if (auto handler = m_writeBlobToFilePathCallbackMap.take(callbackID))
+        handler(success);
+    else
+        ASSERT_NOT_REACHED();
+}
+
 void NetworkProcessProxy::processReadyToSuspend()
 {
     m_throttler.processReadyToSuspend();

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h (226469 => 226470)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2018-01-05 23:48:35 UTC (rev 226470)
@@ -47,6 +47,7 @@
 class ResourceRequest;
 enum class ShouldSample;
 class SecurityOrigin;
+class URL;
 struct SecurityOriginData;
 }
 
@@ -82,6 +83,8 @@
     void updateStorageAccessForPrevalentDomains(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, bool value, CompletionHandler<void(bool)>&& callback);
 #endif
 
+    void writeBlobToFilePath(const WebCore::URL&, const String& path, CompletionHandler<void(bool)>&& callback);
+
     void processReadyToSuspend();
 
     void setIsHoldingLockedFiles(bool);
@@ -121,6 +124,7 @@
     void didFetchWebsiteData(uint64_t callbackID, const WebsiteData&);
     void didDeleteWebsiteData(uint64_t callbackID);
     void didDeleteWebsiteDataForOrigins(uint64_t callbackID);
+    void didWriteBlobToFilePath(bool success, uint64_t callbackID);
     void grantSandboxExtensionsToStorageProcessForBlobs(uint64_t requestID, const Vector<String>& paths);
     void logDiagnosticMessage(uint64_t pageID, const String& message, const String& description, WebCore::ShouldSample);
     void logDiagnosticMessageWithResult(uint64_t pageID, const String& message, const String& description, uint32_t result, WebCore::ShouldSample);
@@ -151,6 +155,7 @@
     ProcessThrottler m_throttler;
     ProcessThrottler::BackgroundActivityToken m_tokenForHoldingLockedFiles;
 
+    HashMap<uint64_t, CompletionHandler<void(bool success)>> m_writeBlobToFilePathCallbackMap;
     HashMap<uint64_t, WTF::CompletionHandler<void(bool wasGranted)>> m_storageAccessResponseCallbackMap;
 };
 

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in (226469 => 226470)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in	2018-01-05 23:48:35 UTC (rev 226470)
@@ -29,6 +29,8 @@
     DidDeleteWebsiteData(uint64_t callbackID)
     DidDeleteWebsiteDataForOrigins(uint64_t callbackID)
 
+    DidWriteBlobToFilePath(bool success, uint64_t callbackID)
+
     GrantSandboxExtensionsToStorageProcessForBlobs(uint64_t requestID, Vector<String> paths)
 
     ProcessReadyToSuspend()

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (226469 => 226470)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2018-01-05 23:48:35 UTC (rev 226470)
@@ -67,6 +67,7 @@
 #include "NativeWebWheelEvent.h"
 #include "NavigationActionData.h"
 #include "NetworkProcessMessages.h"
+#include "NetworkProcessProxy.h"
 #include "NotificationPermissionRequest.h"
 #include "NotificationPermissionRequestManager.h"
 #include "OptionalCallbackID.h"
@@ -7281,6 +7282,16 @@
 
 #endif // ENABLE(ATTACHMENT_ELEMENT)
 
+void WebPageProxy::writeBlobToFilePath(const URL& url, const String& path, Function<void(bool success)>&& callback)
+{
+    if (!isValid()) {
+        callback(false);
+        return;
+    }
+
+    m_process->processPool().ensureNetworkProcess().writeBlobToFilePath(url, path, WTFMove(callback));
+}
+
 #if ENABLE(APPLICATION_MANIFEST)
 void WebPageProxy::getApplicationManifest(Function<void(const std::optional<WebCore::ApplicationManifest>&, CallbackBase::Error)>&& callbackFunction)
 {

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (226469 => 226470)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2018-01-05 23:38:26 UTC (rev 226469)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2018-01-05 23:48:35 UTC (rev 226470)
@@ -1262,6 +1262,8 @@
     void getApplicationManifest(Function<void(const std::optional<WebCore::ApplicationManifest>&, CallbackBase::Error)>&&);
 #endif
 
+    void writeBlobToFilePath(const WebCore::URL& blobURL, const String& path, Function<void(bool success)>&&);
+
     WebPreferencesStore preferencesStore() const;
 
 private:
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to