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:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226470
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2018-01-05 Wenson Hsieh <wenson_hsieh@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 <achristensen@webkit.org>
Forbid < and > in URL hosts
#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;
}
#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;
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
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()) {
}
}
}
+ 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);
-
- 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 : 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;
- }
- }
- }
-
- filePaths.append(tempFilePath.isolatedCopy());
+ if (path.isEmpty() || !FileSystem::isHandleValid(file)) {
+ LOG_ERROR("Failed to open temporary file for writing a Blob");
+ 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;
+}
- return true;
- };
+void BlobRegistryImpl::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, Function<void(const Vector<String>& filePaths)>&& completionHandler)
+{
+ Vector<BlobForFileWriting> blobsForWriting;
+ if (!populateBlobsForFileWriting(blobURLs, blobsForWriting)) {
+ completionHandler({ });
+ return;
+ }
- if (!performWriting())
- filePaths.clear();
+ 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());
+ }
callOnMainThread([completionHandler = WTFMove(completionHandler), filePaths = WTFMove(filePaths)]() {
completionHandler(filePaths);
});
}
+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
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 {
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);
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;
};
+2018-01-05 Wenson Hsieh <wenson_hsieh@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 <mitz@apple.com>
Add injected bundle equivalents of DOMHTMLDocument (DOMHTMLDocumentExtensions)
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))
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()) {
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();
#include "LegacyCustomProtocolManager.h"
#endif
#include "Logging.h"
+#include "NetworkBlobRegistry.h"
#include "NetworkConnectionToWebProcess.h"
#include "NetworkProcessCreationParameters.h"
#include "NetworkProcessPlatformStrategies.h"
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)
{
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>&);
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)
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);
}
if (!decoder.decode(info.filename))
return false;
- if (!decoder.decode(info.blobType))
- return false;
-
if (!decodeTypesAndData(decoder, info.additionalTypes, info.additionalData))
return false;
struct PasteboardCustomData;
struct PasteboardURL;
struct PluginInfo;
-struct PromisedBlobData;
struct PromisedBlobInfo;
struct RecentSearch;
struct ResourceLoadStatistics;
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&);
m_tokenForHoldingLockedFiles = nullptr;
+ for (auto& callback : m_writeBlobToFilePathCallbackMap.values())
+ callback(false);
+ m_writeBlobToFilePathCallbackMap.clear();
+
// This may cause us to be deleted.
networkProcessCrashed();
}
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();
class ResourceRequest;
enum class ShouldSample;
class SecurityOrigin;
+class URL;
struct SecurityOriginData;
}
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);
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);
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;
};
DidDeleteWebsiteData(uint64_t callbackID)
DidDeleteWebsiteDataForOrigins(uint64_t callbackID)
+ DidWriteBlobToFilePath(bool success, uint64_t callbackID)
+
GrantSandboxExtensionsToStorageProcessForBlobs(uint64_t requestID, Vector<String> paths)
ProcessReadyToSuspend()
#include "NativeWebWheelEvent.h"
#include "NavigationActionData.h"
#include "NetworkProcessMessages.h"
+#include "NetworkProcessProxy.h"
#include "NotificationPermissionRequest.h"
#include "NotificationPermissionRequestManager.h"
#include "OptionalCallbackID.h"
#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)
{
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: