/* * Copyright (C) 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "NetworkBlobRegistry.h" #include "BlobDataFileReferenceWithSandboxExtension.h" #include "SandboxExtension.h" #include #include #include #include using namespace WebCore; namespace WebKit { NetworkBlobRegistry& NetworkBlobRegistry::singleton() { ASSERT(RunLoop::isMain()); static NeverDestroyed registry; return registry; } NetworkBlobRegistry::NetworkBlobRegistry() { } void NetworkBlobRegistry::registerFileBlobURL(NetworkConnectionToWebProcess* connection, const URL& url, const String& path, RefPtr&& sandboxExtension, const String& contentType) { blobRegistry().registerFileBlobURL(url, BlobDataFileReferenceWithSandboxExtension::create(path, sandboxExtension), contentType); ASSERT(!m_blobsForConnection.get(connection).contains(url)); BlobForConnectionMap::iterator mapIterator = m_blobsForConnection.find(connection); if (mapIterator == m_blobsForConnection.end()) mapIterator = m_blobsForConnection.add(connection, HashSet()).iterator; mapIterator->value.add(url); } void NetworkBlobRegistry::registerBlobURL(NetworkConnectionToWebProcess* connection, const URL& url, Vector blobParts, const String& contentType) { blobRegistry().registerBlobURL(url, WTFMove(blobParts), contentType); ASSERT(!m_blobsForConnection.get(connection).contains(url)); BlobForConnectionMap::iterator mapIterator = m_blobsForConnection.find(connection); if (mapIterator == m_blobsForConnection.end()) mapIterator = m_blobsForConnection.add(connection, HashSet()).iterator; mapIterator->value.add(url); } void NetworkBlobRegistry::registerBlobURL(NetworkConnectionToWebProcess* connection, const WebCore::URL& url, const WebCore::URL& srcURL) { // The connection may not be registered if NetworkProcess prevously crashed for any reason. BlobForConnectionMap::iterator mapIterator = m_blobsForConnection.find(connection); if (mapIterator == m_blobsForConnection.end()) return; blobRegistry().registerBlobURL(url, srcURL); ASSERT(mapIterator->value.contains(srcURL)); mapIterator->value.add(url); } void NetworkBlobRegistry::registerBlobURLForSlice(NetworkConnectionToWebProcess* connection, const WebCore::URL& url, const WebCore::URL& srcURL, int64_t start, int64_t end) { // The connection may not be registered if NetworkProcess prevously crashed for any reason. BlobForConnectionMap::iterator mapIterator = m_blobsForConnection.find(connection); if (mapIterator == m_blobsForConnection.end()) return; blobRegistry().registerBlobURLForSlice(url, srcURL, start, end); ASSERT(mapIterator->value.contains(srcURL)); mapIterator->value.add(url); } void NetworkBlobRegistry::unregisterBlobURL(NetworkConnectionToWebProcess* connection, const WebCore::URL& url) { // The connection may not be registered if NetworkProcess prevously crashed for any reason. BlobForConnectionMap::iterator mapIterator = m_blobsForConnection.find(connection); if (mapIterator == m_blobsForConnection.end()) return; blobRegistry().unregisterBlobURL(url); ASSERT(mapIterator->value.contains(url)); mapIterator->value.remove(url); } uint64_t NetworkBlobRegistry::blobSize(NetworkConnectionToWebProcess* connection, const WebCore::URL& url) { if (!m_blobsForConnection.contains(connection) || !m_blobsForConnection.find(connection)->value.contains(url)) return 0; return blobRegistry().blobSize(url); } void NetworkBlobRegistry::connectionToWebProcessDidClose(NetworkConnectionToWebProcess* connection) { if (!m_blobsForConnection.contains(connection)) return; HashSet& blobsForConnection = m_blobsForConnection.find(connection)->value; for (HashSet::iterator iter = blobsForConnection.begin(), end = blobsForConnection.end(); iter != end; ++iter) blobRegistry().unregisterBlobURL(*iter); m_blobsForConnection.remove(connection); } Vector> NetworkBlobRegistry::filesInBlob(NetworkConnectionToWebProcess& connection, const WebCore::URL& url) { if (!m_blobsForConnection.contains(&connection) || !m_blobsForConnection.find(&connection)->value.contains(url)) return Vector>(); ASSERT(blobRegistry().isBlobRegistryImpl()); BlobData* blobData = static_cast(blobRegistry()).getBlobDataFromURL(url); if (!blobData) return Vector>(); Vector> result; for (const BlobDataItem& item : blobData->items()) { if (item.type() == BlobDataItem::Type::File) result.append(item.file()); } return result; } }