Check IDB quota usage through QuotaManager
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / shared / InProcessIDBServer.cpp
1 /*
2  * Copyright (C) 2015 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 "InProcessIDBServer.h"
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "IDBConnectionToClient.h"
32 #include "IDBConnectionToServer.h"
33 #include "IDBCursorInfo.h"
34 #include "IDBGetRecordData.h"
35 #include "IDBIterateCursorData.h"
36 #include "IDBKeyRangeData.h"
37 #include "IDBOpenDBRequest.h"
38 #include "IDBRequestData.h"
39 #include "IDBResultData.h"
40 #include "IDBValue.h"
41 #include "Logging.h"
42 #include <wtf/FileSystem.h>
43 #include <wtf/RunLoop.h>
44
45 namespace WebCore {
46
47 Ref<InProcessIDBServer> InProcessIDBServer::create(PAL::SessionID sessionID)
48 {
49     Ref<InProcessIDBServer> server = adoptRef(*new InProcessIDBServer(sessionID));
50     server->m_server->registerConnection(server->connectionToClient());
51     return server;
52 }
53
54 Ref<InProcessIDBServer> InProcessIDBServer::create(PAL::SessionID sessionID, const String& databaseDirectoryPath)
55 {
56     Ref<InProcessIDBServer> server = adoptRef(*new InProcessIDBServer(sessionID, databaseDirectoryPath));
57     server->m_server->registerConnection(server->connectionToClient());
58     return server;
59 }
60
61 StorageQuotaManager* InProcessIDBServer::quotaManager(const ClientOrigin& origin)
62 {
63     return m_quotaManagers.ensure(origin, [] {
64         return std::make_unique<StorageQuotaManager>(StorageQuotaManager::defaultQuota(), [](uint64_t quota, uint64_t currentSpace, uint64_t spaceIncrease, auto callback) {
65             callback(quota + currentSpace + spaceIncrease);
66         });
67     }).iterator->value.get();
68 }
69
70 static inline IDBServer::IDBServer::QuotaManagerGetter storageQuotaManagerGetter(InProcessIDBServer& server)
71 {
72     return [&server, weakServer = makeWeakPtr(server)](PAL::SessionID, const auto& origin) {
73         return weakServer ? server.quotaManager(origin) : nullptr;
74     };
75 }
76
77 InProcessIDBServer::InProcessIDBServer(PAL::SessionID sessionID)
78     : m_server(IDBServer::IDBServer::create(sessionID, *this, storageQuotaManagerGetter(*this)))
79 {
80     relaxAdoptionRequirement();
81     m_connectionToServer = IDBClient::IDBConnectionToServer::create(*this);
82     m_connectionToClient = IDBServer::IDBConnectionToClient::create(*this);
83 }
84
85 InProcessIDBServer::InProcessIDBServer(PAL::SessionID sessionID, const String& databaseDirectoryPath)
86     : m_server(IDBServer::IDBServer::create(sessionID, databaseDirectoryPath, *this, storageQuotaManagerGetter(*this)))
87 {
88     relaxAdoptionRequirement();
89     m_connectionToServer = IDBClient::IDBConnectionToServer::create(*this);
90     m_connectionToClient = IDBServer::IDBConnectionToClient::create(*this);
91 }
92
93 uint64_t InProcessIDBServer::identifier() const
94 {
95     // An instance of InProcessIDBServer always has a 1:1 relationship with its instance of IDBServer.
96     // Therefore the connection identifier between the two can always be "1".
97     return 1;
98 }
99
100 IDBClient::IDBConnectionToServer& InProcessIDBServer::connectionToServer() const
101 {
102     return *m_connectionToServer;
103 }
104
105 IDBServer::IDBConnectionToClient& InProcessIDBServer::connectionToClient() const
106 {
107     return *m_connectionToClient;
108 }
109
110 void InProcessIDBServer::deleteDatabase(const IDBRequestData& requestData)
111 {
112     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData] {
113         m_server->deleteDatabase(requestData);
114     });
115 }
116
117 void InProcessIDBServer::didDeleteDatabase(const IDBResultData& resultData)
118 {
119     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
120         m_connectionToServer->didDeleteDatabase(resultData);
121     });
122 }
123
124 void InProcessIDBServer::openDatabase(const IDBRequestData& requestData)
125 {
126     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData] {
127         m_server->openDatabase(requestData);
128     });
129 }
130
131 void InProcessIDBServer::didOpenDatabase(const IDBResultData& resultData)
132 {
133     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
134         m_connectionToServer->didOpenDatabase(resultData);
135     });
136 }
137
138 void InProcessIDBServer::didAbortTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
139 {
140     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), transactionIdentifier, error] {
141         m_connectionToServer->didAbortTransaction(transactionIdentifier, error);
142     });
143 }
144
145 void InProcessIDBServer::didCommitTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
146 {
147     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), transactionIdentifier, error] {
148         m_connectionToServer->didCommitTransaction(transactionIdentifier, error);
149     });
150 }
151
152 void InProcessIDBServer::didCreateObjectStore(const IDBResultData& resultData)
153 {
154     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
155         m_connectionToServer->didCreateObjectStore(resultData);
156     });
157 }
158
159 void InProcessIDBServer::didDeleteObjectStore(const IDBResultData& resultData)
160 {
161     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
162         m_connectionToServer->didDeleteObjectStore(resultData);
163     });
164 }
165
166 void InProcessIDBServer::didRenameObjectStore(const IDBResultData& resultData)
167 {
168     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
169         m_connectionToServer->didRenameObjectStore(resultData);
170     });
171 }
172
173 void InProcessIDBServer::didClearObjectStore(const IDBResultData& resultData)
174 {
175     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
176         m_connectionToServer->didClearObjectStore(resultData);
177     });
178 }
179
180 void InProcessIDBServer::didCreateIndex(const IDBResultData& resultData)
181 {
182     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
183         m_connectionToServer->didCreateIndex(resultData);
184     });
185 }
186
187 void InProcessIDBServer::didDeleteIndex(const IDBResultData& resultData)
188 {
189     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
190         m_connectionToServer->didDeleteIndex(resultData);
191     });
192 }
193
194 void InProcessIDBServer::didRenameIndex(const IDBResultData& resultData)
195 {
196     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
197         m_connectionToServer->didRenameIndex(resultData);
198     });
199 }
200
201 void InProcessIDBServer::didPutOrAdd(const IDBResultData& resultData)
202 {
203     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
204         m_connectionToServer->didPutOrAdd(resultData);
205     });
206 }
207
208 void InProcessIDBServer::didGetRecord(const IDBResultData& resultData)
209 {
210     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
211         m_connectionToServer->didGetRecord(resultData);
212     });
213 }
214
215 void InProcessIDBServer::didGetAllRecords(const IDBResultData& resultData)
216 {
217     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
218         m_connectionToServer->didGetAllRecords(resultData);
219     });
220 }
221
222 void InProcessIDBServer::didGetCount(const IDBResultData& resultData)
223 {
224     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
225         m_connectionToServer->didGetCount(resultData);
226     });
227 }
228
229 void InProcessIDBServer::didDeleteRecord(const IDBResultData& resultData)
230 {
231     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
232         m_connectionToServer->didDeleteRecord(resultData);
233     });
234 }
235
236 void InProcessIDBServer::didOpenCursor(const IDBResultData& resultData)
237 {
238     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
239         m_connectionToServer->didOpenCursor(resultData);
240     });
241 }
242
243 void InProcessIDBServer::didIterateCursor(const IDBResultData& resultData)
244 {
245     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
246         m_connectionToServer->didIterateCursor(resultData);
247     });
248 }
249
250 void InProcessIDBServer::abortTransaction(const IDBResourceIdentifier& resourceIdentifier)
251 {
252     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resourceIdentifier] {
253         m_server->abortTransaction(resourceIdentifier);
254     });
255 }
256
257 void InProcessIDBServer::commitTransaction(const IDBResourceIdentifier& resourceIdentifier)
258 {
259     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resourceIdentifier] {
260         m_server->commitTransaction(resourceIdentifier);
261     });
262 }
263
264 void InProcessIDBServer::didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier)
265 {
266     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier, transactionIdentifier] {
267         m_server->didFinishHandlingVersionChangeTransaction(databaseConnectionIdentifier, transactionIdentifier);
268     });
269 }
270
271 void InProcessIDBServer::createObjectStore(const IDBRequestData& resultData, const IDBObjectStoreInfo& info)
272 {
273     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData, info] {
274         m_server->createObjectStore(resultData, info);
275     });
276 }
277
278 void InProcessIDBServer::deleteObjectStore(const IDBRequestData& requestData, const String& objectStoreName)
279 {
280     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, objectStoreName] {
281         m_server->deleteObjectStore(requestData, objectStoreName);
282     });
283 }
284
285 void InProcessIDBServer::renameObjectStore(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, const String& newName)
286 {
287     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, objectStoreIdentifier, newName] {
288         m_server->renameObjectStore(requestData, objectStoreIdentifier, newName);
289     });
290 }
291
292 void InProcessIDBServer::clearObjectStore(const IDBRequestData& requestData, uint64_t objectStoreIdentifier)
293 {
294     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, objectStoreIdentifier] {
295         m_server->clearObjectStore(requestData, objectStoreIdentifier);
296     });
297 }
298
299 void InProcessIDBServer::createIndex(const IDBRequestData& requestData, const IDBIndexInfo& info)
300 {
301     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, info] {
302         m_server->createIndex(requestData, info);
303     });
304 }
305
306 void InProcessIDBServer::deleteIndex(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, const String& indexName)
307 {
308     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, objectStoreIdentifier, indexName] {
309         m_server->deleteIndex(requestData, objectStoreIdentifier, indexName);
310     });
311 }
312
313 void InProcessIDBServer::renameIndex(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName)
314 {
315     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, objectStoreIdentifier, indexIdentifier, newName] {
316         m_server->renameIndex(requestData, objectStoreIdentifier, indexIdentifier, newName);
317     });
318 }
319
320 void InProcessIDBServer::putOrAdd(const IDBRequestData& requestData, const IDBKeyData& keyData, const IDBValue& value, const IndexedDB::ObjectStoreOverwriteMode overwriteMode)
321 {
322     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, keyData, value, overwriteMode] {
323         m_server->putOrAdd(requestData, keyData, value, overwriteMode);
324     });
325 }
326
327 void InProcessIDBServer::getRecord(const IDBRequestData& requestData, const IDBGetRecordData& getRecordData)
328 {
329     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, getRecordData] {
330         m_server->getRecord(requestData, getRecordData);
331     });
332 }
333
334 void InProcessIDBServer::getAllRecords(const IDBRequestData& requestData, const IDBGetAllRecordsData& getAllRecordsData)
335 {
336     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, getAllRecordsData] {
337         m_server->getAllRecords(requestData, getAllRecordsData);
338     });
339 }
340
341 void InProcessIDBServer::getCount(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData)
342 {
343     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, keyRangeData] {
344         m_server->getCount(requestData, keyRangeData);
345     });
346 }
347
348 void InProcessIDBServer::deleteRecord(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData)
349 {
350     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, keyRangeData] {
351         m_server->deleteRecord(requestData, keyRangeData);
352     });
353 }
354
355 void InProcessIDBServer::openCursor(const IDBRequestData& requestData, const IDBCursorInfo& info)
356 {
357     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, info] {
358         m_server->openCursor(requestData, info);
359     });
360 }
361
362 void InProcessIDBServer::iterateCursor(const IDBRequestData& requestData, const IDBIterateCursorData& data)
363 {
364     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, data] {
365         m_server->iterateCursor(requestData, data);
366     });
367 }
368
369 void InProcessIDBServer::establishTransaction(uint64_t databaseConnectionIdentifier, const IDBTransactionInfo& info)
370 {
371     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier, info] {
372         m_server->establishTransaction(databaseConnectionIdentifier, info);
373     });
374 }
375
376 void InProcessIDBServer::fireVersionChangeEvent(IDBServer::UniqueIDBDatabaseConnection& connection, const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion)
377 {
378     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier = connection.identifier(), requestIdentifier, requestedVersion] {
379         m_connectionToServer->fireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier, requestedVersion);
380     });
381 }
382
383 void InProcessIDBServer::didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
384 {
385     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), transactionIdentifier, error] {
386         m_connectionToServer->didStartTransaction(transactionIdentifier, error);
387     });
388 }
389
390 void InProcessIDBServer::didCloseFromServer(IDBServer::UniqueIDBDatabaseConnection& connection, const IDBError& error)
391 {
392     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier = connection.identifier(), error] {
393         m_connectionToServer->didCloseFromServer(databaseConnectionIdentifier, error);
394     });
395 }
396
397 void InProcessIDBServer::notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
398 {
399     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestIdentifier, oldVersion, newVersion] {
400         m_connectionToServer->notifyOpenDBRequestBlocked(requestIdentifier, oldVersion, newVersion);
401     });
402 }
403
404 void InProcessIDBServer::databaseConnectionPendingClose(uint64_t databaseConnectionIdentifier)
405 {
406     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier] {
407         m_server->databaseConnectionPendingClose(databaseConnectionIdentifier);
408     });
409 }
410
411 void InProcessIDBServer::databaseConnectionClosed(uint64_t databaseConnectionIdentifier)
412 {
413     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier] {
414         m_server->databaseConnectionClosed(databaseConnectionIdentifier);
415     });
416 }
417
418 void InProcessIDBServer::abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier)
419 {
420     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier, transactionIdentifier] {
421         m_server->abortOpenAndUpgradeNeeded(databaseConnectionIdentifier, transactionIdentifier);
422     });
423 }
424
425 void InProcessIDBServer::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier)
426 {
427     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier, requestIdentifier] {
428         m_server->didFireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier);
429     });
430 }
431
432 void InProcessIDBServer::openDBRequestCancelled(const IDBRequestData& requestData)
433 {
434     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData] {
435         m_server->openDBRequestCancelled(requestData);
436     });
437 }
438
439 void InProcessIDBServer::confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier)
440 {
441     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier] {
442         m_server->confirmDidCloseFromServer(databaseConnectionIdentifier);
443     });
444 }
445
446 void InProcessIDBServer::getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID)
447 {
448     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), mainFrameOrigin, openingOrigin, callbackID] {
449         m_server->getAllDatabaseNames(m_connectionToServer->identifier(), mainFrameOrigin, openingOrigin, callbackID);
450     });
451 }
452
453 void InProcessIDBServer::didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames)
454 {
455     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), callbackID, databaseNames] {
456         m_connectionToServer->didGetAllDatabaseNames(callbackID, databaseNames);
457     });
458 }
459
460 void InProcessIDBServer::accessToTemporaryFileComplete(const String& path)
461 {
462     FileSystem::deleteFile(path);
463 }
464
465 } // namespace WebCore
466
467 #endif // ENABLE(INDEXED_DATABASE)