50d3136d0df02423ef82d34a5534a375320ab394
[WebKit-https.git] / Source / WebKit2 / NetworkProcess / FileAPI / NetworkBlobRegistry.cpp
1 /*
2  * Copyright (C) 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "NetworkBlobRegistry.h"
28
29 #include "BlobDataFileReferenceWithSandboxExtension.h"
30 #include "NetworkConnectionToWebProcess.h"
31 #include "SandboxExtension.h"
32 #include <WebCore/BlobPart.h>
33 #include <WebCore/BlobRegistryImpl.h>
34 #include <wtf/NeverDestroyed.h>
35 #include <wtf/RunLoop.h>
36
37 using namespace WebCore;
38
39 namespace WebKit {
40
41 NetworkBlobRegistry& NetworkBlobRegistry::singleton()
42 {
43     ASSERT(RunLoop::isMain());
44     static NeverDestroyed<NetworkBlobRegistry> registry;
45     return registry;
46 }
47
48 NetworkBlobRegistry::NetworkBlobRegistry()
49 {
50 }
51
52 void NetworkBlobRegistry::registerFileBlobURL(NetworkConnectionToWebProcess* connection, const URL& url, const String& path, RefPtr<SandboxExtension>&& sandboxExtension, const String& contentType)
53 {
54     blobRegistry().registerFileBlobURL(url, BlobDataFileReferenceWithSandboxExtension::create(path, sandboxExtension), contentType);
55
56     ASSERT(!m_blobsForConnection.get(connection).contains(url));
57     BlobForConnectionMap::iterator mapIterator = m_blobsForConnection.find(connection);
58     if (mapIterator == m_blobsForConnection.end())
59         mapIterator = m_blobsForConnection.add(connection, HashSet<URL>()).iterator;
60     mapIterator->value.add(url);
61 }
62
63 void NetworkBlobRegistry::registerBlobURL(NetworkConnectionToWebProcess* connection, const URL& url, Vector<WebCore::BlobPart> blobParts, const String& contentType)
64 {
65     blobRegistry().registerBlobURL(url, WTFMove(blobParts), contentType);
66
67     ASSERT(!m_blobsForConnection.get(connection).contains(url));
68     BlobForConnectionMap::iterator mapIterator = m_blobsForConnection.find(connection);
69     if (mapIterator == m_blobsForConnection.end())
70         mapIterator = m_blobsForConnection.add(connection, HashSet<URL>()).iterator;
71     mapIterator->value.add(url);
72 }
73
74 void NetworkBlobRegistry::registerBlobURL(NetworkConnectionToWebProcess* connection, const WebCore::URL& url, const WebCore::URL& srcURL)
75 {
76     // The connection may not be registered if NetworkProcess prevously crashed for any reason.
77     BlobForConnectionMap::iterator mapIterator = m_blobsForConnection.find(connection);
78     if (mapIterator == m_blobsForConnection.end())
79         return;
80
81     blobRegistry().registerBlobURL(url, srcURL);
82
83     ASSERT(mapIterator->value.contains(srcURL));
84     mapIterator->value.add(url);
85 }
86
87 void NetworkBlobRegistry::registerBlobURLOptionallyFileBacked(NetworkConnectionToWebProcess* connection, const URL& url, const URL& srcURL, const String& fileBackedPath)
88 {
89     auto fileReference = connection->getBlobDataFileReferenceForPath(fileBackedPath);
90     ASSERT(fileReference);
91
92     blobRegistry().registerBlobURLOptionallyFileBacked(url, srcURL, WTFMove(fileReference));
93
94     ASSERT(!m_blobsForConnection.get(connection).contains(url));
95     BlobForConnectionMap::iterator mapIterator = m_blobsForConnection.find(connection);
96     if (mapIterator == m_blobsForConnection.end())
97         mapIterator = m_blobsForConnection.add(connection, HashSet<URL>()).iterator;
98     mapIterator->value.add(url);
99 }
100
101 void NetworkBlobRegistry::registerBlobURLForSlice(NetworkConnectionToWebProcess* connection, const WebCore::URL& url, const WebCore::URL& srcURL, int64_t start, int64_t end)
102 {
103     // The connection may not be registered if NetworkProcess prevously crashed for any reason.
104     BlobForConnectionMap::iterator mapIterator = m_blobsForConnection.find(connection);
105     if (mapIterator == m_blobsForConnection.end())
106         return;
107
108     blobRegistry().registerBlobURLForSlice(url, srcURL, start, end);
109
110     ASSERT(mapIterator->value.contains(srcURL));
111     mapIterator->value.add(url);
112 }
113
114 void NetworkBlobRegistry::unregisterBlobURL(NetworkConnectionToWebProcess* connection, const WebCore::URL& url)
115 {
116     // The connection may not be registered if NetworkProcess prevously crashed for any reason.
117     BlobForConnectionMap::iterator mapIterator = m_blobsForConnection.find(connection);
118     if (mapIterator == m_blobsForConnection.end())
119         return;
120
121     blobRegistry().unregisterBlobURL(url);
122
123     ASSERT(mapIterator->value.contains(url));
124     mapIterator->value.remove(url);
125 }
126
127 uint64_t NetworkBlobRegistry::blobSize(NetworkConnectionToWebProcess* connection, const WebCore::URL& url)
128 {
129     if (!m_blobsForConnection.contains(connection) || !m_blobsForConnection.find(connection)->value.contains(url))
130         return 0;
131
132     return blobRegistry().blobSize(url);
133 }
134
135 void NetworkBlobRegistry::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void(const Vector<String>&)> completionHandler)
136 {
137     blobRegistry().writeBlobsToTemporaryFiles(blobURLs, completionHandler);
138 }
139
140 void NetworkBlobRegistry::connectionToWebProcessDidClose(NetworkConnectionToWebProcess* connection)
141 {
142     if (!m_blobsForConnection.contains(connection))
143         return;
144
145     HashSet<URL>& blobsForConnection = m_blobsForConnection.find(connection)->value;
146     for (HashSet<URL>::iterator iter = blobsForConnection.begin(), end = blobsForConnection.end(); iter != end; ++iter)
147         blobRegistry().unregisterBlobURL(*iter);
148
149     m_blobsForConnection.remove(connection);
150 }
151
152 Vector<RefPtr<BlobDataFileReference>> NetworkBlobRegistry::filesInBlob(NetworkConnectionToWebProcess& connection, const WebCore::URL& url)
153 {
154     if (!m_blobsForConnection.contains(&connection) || !m_blobsForConnection.find(&connection)->value.contains(url))
155         return Vector<RefPtr<BlobDataFileReference>>();
156
157     ASSERT(blobRegistry().isBlobRegistryImpl());
158     BlobData* blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(url);
159     if (!blobData)
160         return Vector<RefPtr<BlobDataFileReference>>();
161
162     Vector<RefPtr<BlobDataFileReference>> result;
163     for (const BlobDataItem& item : blobData->items()) {
164         if (item.type() == BlobDataItem::Type::File)
165             result.append(item.file());
166     }
167
168     return result;
169 }
170
171 }