1/*
2 * Copyright (C) 2015 Igalia S.L.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2,1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "config.h"
21#include "WebKitWebsiteDataManager.h"
22
23#include "APIWebsiteDataStore.h"
24#include "WebKitCookieManagerPrivate.h"
25#include "WebKitPrivate.h"
26#include "WebKitWebsiteDataManagerPrivate.h"
27#include "WebKitWebsiteDataPrivate.h"
28#include "WebsiteDataFetchOption.h"
29#include <glib/gi18n-lib.h>
30#include <wtf/FileSystem.h>
31#include <wtf/glib/GUniquePtr.h>
32#include <wtf/glib/WTFGType.h>
33
34using namespace WebKit;
35
36/**
37 * SECTION: WebKitWebsiteDataManager
38 * @Short_description: Website data manager
39 * @Title: WebKitWebsiteDataManager
40 * @See_also: #WebKitWebContext, #WebKitWebsiteData
41 *
42 * WebKitWebsiteDataManager allows you to manage the data that websites
43 * can store in the client file system like databases or caches.
44 * You can use WebKitWebsiteDataManager to configure the local directories
45 * where the Website data will be stored, by creating a new manager with
46 * webkit_website_data_manager_new() passing the values you want to set.
47 * You can set all the possible configuration values or only some of them,
48 * a default value will be used automatically for the configuration options
49 * not provided. #WebKitWebsiteDataManager:base-data-directory and
50 * #WebKitWebsiteDataManager:base-cache-directory are two special properties
51 * that can be used to set a common base directory for all Website data and
52 * caches. It's possible to provide both, a base directory and a specific value,
53 * but in that case, the specific value takes precedence over the base directory.
54 * The newly created WebKitWebsiteDataManager must be passed as a construct property
55 * to a #WebKitWebContext, you can use webkit_web_context_new_with_website_data_manager()
56 * to create a new #WebKitWebContext with a WebKitWebsiteDataManager.
57 * In case you don't want to set any specific configuration, you don't need to create
58 * a WebKitWebsiteDataManager, the #WebKitWebContext will create a WebKitWebsiteDataManager
59 * with the default configuration. To get the WebKitWebsiteDataManager of a #WebKitWebContext
60 * you can use webkit_web_context_get_website_data_manager().
61 *
62 * A WebKitWebsiteDataManager can also be ephemeral and then all the directories configuration
63 * is not needed because website data will never persist. You can create an ephemeral WebKitWebsiteDataManager
64 * with webkit_website_data_manager_new_ephemeral(). Then you can pass an ephemeral WebKitWebsiteDataManager to
65 * a #WebKitWebContext to make it ephemeral or use webkit_web_context_new_ephemeral() and the WebKitWebsiteDataManager
66 * will be automatically created by the #WebKitWebContext.
67 *
68 * WebKitWebsiteDataManager can also be used to fetch websites data, remove data
69 * stored by particular websites, or clear data for all websites modified since a given
70 * period of time.
71 *
72 * Since: 2.10
73 */
74
75using namespace WebKit;
76
77enum {
78 PROP_0,
79
80 PROP_BASE_DATA_DIRECTORY,
81 PROP_BASE_CACHE_DIRECTORY,
82 PROP_LOCAL_STORAGE_DIRECTORY,
83 PROP_DISK_CACHE_DIRECTORY,
84 PROP_APPLICATION_CACHE_DIRECTORY,
85 PROP_INDEXEDDB_DIRECTORY,
86 PROP_WEBSQL_DIRECTORY,
87 PROP_IS_EPHEMERAL
88};
89
90struct _WebKitWebsiteDataManagerPrivate {
91 ~_WebKitWebsiteDataManagerPrivate()
92 {
93 ASSERT(processPools.isEmpty());
94 }
95
96 RefPtr<API::WebsiteDataStore> websiteDataStore;
97 GUniquePtr<char> baseDataDirectory;
98 GUniquePtr<char> baseCacheDirectory;
99 GUniquePtr<char> localStorageDirectory;
100 GUniquePtr<char> diskCacheDirectory;
101 GUniquePtr<char> applicationCacheDirectory;
102 GUniquePtr<char> indexedDBDirectory;
103 GUniquePtr<char> webSQLDirectory;
104
105 GRefPtr<WebKitCookieManager> cookieManager;
106 Vector<WebProcessPool*> processPools;
107};
108
109WEBKIT_DEFINE_TYPE(WebKitWebsiteDataManager, webkit_website_data_manager, G_TYPE_OBJECT)
110
111static void webkitWebsiteDataManagerGetProperty(GObject* object, guint propID, GValue* value, GParamSpec* paramSpec)
112{
113 WebKitWebsiteDataManager* manager = WEBKIT_WEBSITE_DATA_MANAGER(object);
114
115 switch (propID) {
116 case PROP_BASE_DATA_DIRECTORY:
117 g_value_set_string(value, webkit_website_data_manager_get_base_data_directory(manager));
118 break;
119 case PROP_BASE_CACHE_DIRECTORY:
120 g_value_set_string(value, webkit_website_data_manager_get_base_cache_directory(manager));
121 break;
122 case PROP_LOCAL_STORAGE_DIRECTORY:
123 g_value_set_string(value, webkit_website_data_manager_get_local_storage_directory(manager));
124 break;
125 case PROP_DISK_CACHE_DIRECTORY:
126 g_value_set_string(value, webkit_website_data_manager_get_disk_cache_directory(manager));
127 break;
128 case PROP_APPLICATION_CACHE_DIRECTORY:
129 g_value_set_string(value, webkit_website_data_manager_get_offline_application_cache_directory(manager));
130 break;
131 case PROP_INDEXEDDB_DIRECTORY:
132 g_value_set_string(value, webkit_website_data_manager_get_indexeddb_directory(manager));
133 break;
134 case PROP_WEBSQL_DIRECTORY:
135 g_value_set_string(value, webkit_website_data_manager_get_websql_directory(manager));
136 break;
137 case PROP_IS_EPHEMERAL:
138 g_value_set_boolean(value, webkit_website_data_manager_is_ephemeral(manager));
139 break;
140 default:
141 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec);
142 }
143}
144
145static void webkitWebsiteDataManagerSetProperty(GObject* object, guint propID, const GValue* value, GParamSpec* paramSpec)
146{
147 WebKitWebsiteDataManager* manager = WEBKIT_WEBSITE_DATA_MANAGER(object);
148
149 switch (propID) {
150 case PROP_BASE_DATA_DIRECTORY:
151 manager->priv->baseDataDirectory.reset(g_value_dup_string(value));
152 break;
153 case PROP_BASE_CACHE_DIRECTORY:
154 manager->priv->baseCacheDirectory.reset(g_value_dup_string(value));
155 break;
156 case PROP_LOCAL_STORAGE_DIRECTORY:
157 manager->priv->localStorageDirectory.reset(g_value_dup_string(value));
158 break;
159 case PROP_DISK_CACHE_DIRECTORY:
160 manager->priv->diskCacheDirectory.reset(g_value_dup_string(value));
161 break;
162 case PROP_APPLICATION_CACHE_DIRECTORY:
163 manager->priv->applicationCacheDirectory.reset(g_value_dup_string(value));
164 break;
165 case PROP_INDEXEDDB_DIRECTORY:
166 manager->priv->indexedDBDirectory.reset(g_value_dup_string(value));
167 break;
168 case PROP_WEBSQL_DIRECTORY:
169 manager->priv->webSQLDirectory.reset(g_value_dup_string(value));
170 break;
171 case PROP_IS_EPHEMERAL:
172 if (g_value_get_boolean(value))
173 manager->priv->websiteDataStore = API::WebsiteDataStore::createNonPersistentDataStore();
174 break;
175 default:
176 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec);
177 }
178}
179
180static void webkitWebsiteDataManagerConstructed(GObject* object)
181{
182 G_OBJECT_CLASS(webkit_website_data_manager_parent_class)->constructed(object);
183
184 WebKitWebsiteDataManagerPrivate* priv = WEBKIT_WEBSITE_DATA_MANAGER(object)->priv;
185 if (priv->baseDataDirectory) {
186 if (!priv->localStorageDirectory)
187 priv->localStorageDirectory.reset(g_build_filename(priv->baseDataDirectory.get(), "localstorage", nullptr));
188 if (!priv->indexedDBDirectory)
189 priv->indexedDBDirectory.reset(g_build_filename(priv->baseDataDirectory.get(), "databases", "indexeddb", nullptr));
190 if (!priv->webSQLDirectory)
191 priv->webSQLDirectory.reset(g_build_filename(priv->baseDataDirectory.get(), "databases", nullptr));
192 }
193
194 if (priv->baseCacheDirectory) {
195 if (!priv->diskCacheDirectory)
196 priv->diskCacheDirectory.reset(g_strdup(priv->baseCacheDirectory.get()));
197 if (!priv->applicationCacheDirectory)
198 priv->applicationCacheDirectory.reset(g_build_filename(priv->baseCacheDirectory.get(), "applications", nullptr));
199 }
200}
201
202static void webkit_website_data_manager_class_init(WebKitWebsiteDataManagerClass* findClass)
203{
204 GObjectClass* gObjectClass = G_OBJECT_CLASS(findClass);
205
206 gObjectClass->get_property = webkitWebsiteDataManagerGetProperty;
207 gObjectClass->set_property = webkitWebsiteDataManagerSetProperty;
208 gObjectClass->constructed = webkitWebsiteDataManagerConstructed;
209
210 /**
211 * WebKitWebsiteDataManager:base-data-directory:
212 *
213 * The base directory for Website data. This is used as a base directory
214 * for any Website data when no specific data directory has been provided.
215 *
216 * Since: 2.10
217 */
218 g_object_class_install_property(
219 gObjectClass,
220 PROP_BASE_DATA_DIRECTORY,
221 g_param_spec_string(
222 "base-data-directory",
223 _("Base Data Directory"),
224 _("The base directory for Website data"),
225 nullptr,
226 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
227
228 /**
229 * WebKitWebsiteDataManager:base-cache-directory:
230 *
231 * The base directory for Website cache. This is used as a base directory
232 * for any Website cache when no specific cache directory has been provided.
233 *
234 * Since: 2.10
235 */
236 g_object_class_install_property(
237 gObjectClass,
238 PROP_BASE_CACHE_DIRECTORY,
239 g_param_spec_string(
240 "base-cache-directory",
241 _("Base Cache Directory"),
242 _("The base directory for Website cache"),
243 nullptr,
244 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
245
246 /**
247 * WebKitWebsiteDataManager:local-storage-directory:
248 *
249 * The directory where local storage data will be stored.
250 *
251 * Since: 2.10
252 */
253 g_object_class_install_property(
254 gObjectClass,
255 PROP_LOCAL_STORAGE_DIRECTORY,
256 g_param_spec_string(
257 "local-storage-directory",
258 _("Local Storage Directory"),
259 _("The directory where local storage data will be stored"),
260 nullptr,
261 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
262
263 /**
264 * WebKitWebsiteDataManager:disk-cache-directory:
265 *
266 * The directory where HTTP disk cache will be stored.
267 *
268 * Since: 2.10
269 */
270 g_object_class_install_property(
271 gObjectClass,
272 PROP_DISK_CACHE_DIRECTORY,
273 g_param_spec_string(
274 "disk-cache-directory",
275 _("Disk Cache Directory"),
276 _("The directory where HTTP disk cache will be stored"),
277 nullptr,
278 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
279
280 /**
281 * WebKitWebsiteDataManager:offline-application-cache-directory:
282 *
283 * The directory where offline web application cache will be stored.
284 *
285 * Since: 2.10
286 */
287 g_object_class_install_property(
288 gObjectClass,
289 PROP_APPLICATION_CACHE_DIRECTORY,
290 g_param_spec_string(
291 "offline-application-cache-directory",
292 _("Offline Web Application Cache Directory"),
293 _("The directory where offline web application cache will be stored"),
294 nullptr,
295 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
296
297 /**
298 * WebKitWebsiteDataManager:indexeddb-directory:
299 *
300 * The directory where IndexedDB databases will be stored.
301 *
302 * Since: 2.10
303 */
304 g_object_class_install_property(
305 gObjectClass,
306 PROP_INDEXEDDB_DIRECTORY,
307 g_param_spec_string(
308 "indexeddb-directory",
309 _("IndexedDB Directory"),
310 _("The directory where IndexedDB databases will be stored"),
311 nullptr,
312 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
313
314 /**
315 * WebKitWebsiteDataManager:websql-directory:
316 *
317 * The directory where WebSQL databases will be stored.
318 *
319 * Since: 2.10
320 */
321 g_object_class_install_property(
322 gObjectClass,
323 PROP_WEBSQL_DIRECTORY,
324 g_param_spec_string(
325 "websql-directory",
326 _("WebSQL Directory"),
327 _("The directory where WebSQL databases will be stored"),
328 nullptr,
329 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
330
331 /**
332 * WebKitWebsiteDataManager:is-ephemeral:
333 *
334 * Whether the #WebKitWebsiteDataManager is ephemeral. An ephemeral #WebKitWebsiteDataManager
335 * handles all websites data as non-persistent, and nothing will be written to the client
336 * storage. Note that if you create an ephemeral #WebKitWebsiteDataManager all other construction
337 * parameters to configure data directories will be ignored.
338 *
339 * Since: 2.16
340 */
341 g_object_class_install_property(
342 gObjectClass,
343 PROP_IS_EPHEMERAL,
344 g_param_spec_boolean(
345 "is-ephemeral",
346 "Is Ephemeral",
347 _("Whether the WebKitWebsiteDataManager is ephemeral"),
348 FALSE,
349 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
350}
351
352WebKitWebsiteDataManager* webkitWebsiteDataManagerCreate(Ref<WebsiteDataStoreConfiguration>&& configuration)
353{
354 WebKitWebsiteDataManager* manager = WEBKIT_WEBSITE_DATA_MANAGER(g_object_new(WEBKIT_TYPE_WEBSITE_DATA_MANAGER, nullptr));
355 manager->priv->websiteDataStore = API::WebsiteDataStore::createLegacy(WTFMove(configuration));
356
357 return manager;
358}
359
360API::WebsiteDataStore& webkitWebsiteDataManagerGetDataStore(WebKitWebsiteDataManager* manager)
361{
362 WebKitWebsiteDataManagerPrivate* priv = manager->priv;
363 if (!priv->websiteDataStore) {
364 auto configuration = WebsiteDataStoreConfiguration::create();
365 configuration->setLocalStorageDirectory(!priv->localStorageDirectory ?
366 API::WebsiteDataStore::defaultLocalStorageDirectory() : FileSystem::stringFromFileSystemRepresentation(priv->localStorageDirectory.get()));
367 configuration->setNetworkCacheDirectory(!priv->diskCacheDirectory ?
368 API::WebsiteDataStore::defaultNetworkCacheDirectory() : FileSystem::pathByAppendingComponent(FileSystem::stringFromFileSystemRepresentation(priv->diskCacheDirectory.get()), networkCacheSubdirectory));
369 configuration->setApplicationCacheDirectory(!priv->applicationCacheDirectory ?
370 API::WebsiteDataStore::defaultApplicationCacheDirectory() : FileSystem::stringFromFileSystemRepresentation(priv->applicationCacheDirectory.get()));
371 configuration->setWebSQLDatabaseDirectory(!priv->webSQLDirectory ?
372 API::WebsiteDataStore::defaultWebSQLDatabaseDirectory() : FileSystem::stringFromFileSystemRepresentation(priv->webSQLDirectory.get()));
373 configuration->setMediaKeysStorageDirectory(API::WebsiteDataStore::defaultMediaKeysStorageDirectory());
374 priv->websiteDataStore = API::WebsiteDataStore::createLegacy(WTFMove(configuration));
375 }
376
377 return *priv->websiteDataStore;
378}
379
380void webkitWebsiteDataManagerAddProcessPool(WebKitWebsiteDataManager* manager, WebProcessPool& processPool)
381{
382 ASSERT(!manager->priv->processPools.contains(&processPool));
383 manager->priv->processPools.append(&processPool);
384}
385
386void webkitWebsiteDataManagerRemoveProcessPool(WebKitWebsiteDataManager* manager, WebProcessPool& processPool)
387{
388 ASSERT(manager->priv->processPools.contains(&processPool));
389 manager->priv->processPools.removeFirst(&processPool);
390}
391
392const Vector<WebProcessPool*>& webkitWebsiteDataManagerGetProcessPools(WebKitWebsiteDataManager* manager)
393{
394 return manager->priv->processPools;
395}
396
397/**
398 * webkit_website_data_manager_new:
399 * @first_option_name: name of the first option to set
400 * @...: value of first option, followed by more options, %NULL-terminated
401 *
402 * Creates a new #WebKitWebsiteDataManager with the given options. It must
403 * be passed as construction parameter of a #WebKitWebContext.
404 *
405 * Returns: (transfer full): the newly created #WebKitWebsiteDataManager
406 *
407 * Since: 2.10
408 */
409WebKitWebsiteDataManager* webkit_website_data_manager_new(const gchar* firstOptionName, ...)
410{
411 va_list args;
412 va_start(args, firstOptionName);
413 WebKitWebsiteDataManager* manager = WEBKIT_WEBSITE_DATA_MANAGER(g_object_new_valist(WEBKIT_TYPE_WEBSITE_DATA_MANAGER, firstOptionName, args));
414 va_end(args);
415
416 return manager;
417}
418
419/**
420 * webkit_website_data_manager_new_ephemeral:
421 *
422 * Creates an ephemeral #WebKitWebsiteDataManager. See #WebKitWebsiteDataManager:is-ephemeral for more details.
423 *
424 * Returns: (transfer full): a new ephemeral #WebKitWebsiteDataManager.
425 *
426 * Since: 2.16
427 */
428WebKitWebsiteDataManager* webkit_website_data_manager_new_ephemeral()
429{
430 return WEBKIT_WEBSITE_DATA_MANAGER(g_object_new(WEBKIT_TYPE_WEBSITE_DATA_MANAGER, "is-ephemeral", TRUE, nullptr));
431}
432
433/**
434 * webkit_website_data_manager_is_ephemeral:
435 * @manager: a #WebKitWebsiteDataManager
436 *
437 * Get whether a #WebKitWebsiteDataManager is ephemeral. See #WebKitWebsiteDataManager:is-ephemeral for more details.
438 *
439 * Returns: %TRUE if @manager is epheral or %FALSE otherwise.
440 *
441 * Since: 2.16
442 */
443gboolean webkit_website_data_manager_is_ephemeral(WebKitWebsiteDataManager* manager)
444{
445 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), FALSE);
446
447 return manager->priv->websiteDataStore && !manager->priv->websiteDataStore->isPersistent();
448}
449
450/**
451 * webkit_website_data_manager_get_base_data_directory:
452 * @manager: a #WebKitWebsiteDataManager
453 *
454 * Get the #WebKitWebsiteDataManager:base-data-directory property.
455 *
456 * Returns: (allow-none): the base directory for Website data, or %NULL if
457 * #WebKitWebsiteDataManager:base-data-directory was not provided or @manager is ephemeral.
458 *
459 * Since: 2.10
460 */
461const gchar* webkit_website_data_manager_get_base_data_directory(WebKitWebsiteDataManager* manager)
462{
463 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
464
465 if (manager->priv->websiteDataStore && !manager->priv->websiteDataStore->isPersistent())
466 return nullptr;
467
468 return manager->priv->baseDataDirectory.get();
469}
470
471/**
472 * webkit_website_data_manager_get_base_cache_directory:
473 * @manager: a #WebKitWebsiteDataManager
474 *
475 * Get the #WebKitWebsiteDataManager:base-cache-directory property.
476 *
477 * Returns: (allow-none): the base directory for Website cache, or %NULL if
478 * #WebKitWebsiteDataManager:base-cache-directory was not provided or @manager is ephemeral.
479 *
480 * Since: 2.10
481 */
482const gchar* webkit_website_data_manager_get_base_cache_directory(WebKitWebsiteDataManager* manager)
483{
484 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
485
486 if (manager->priv->websiteDataStore && !manager->priv->websiteDataStore->isPersistent())
487 return nullptr;
488
489 return manager->priv->baseCacheDirectory.get();
490}
491
492/**
493 * webkit_website_data_manager_get_local_storage_directory:
494 * @manager: a #WebKitWebsiteDataManager
495 *
496 * Get the #WebKitWebsiteDataManager:local-storage-directory property.
497 *
498 * Returns: (allow-none): the directory where local storage data is stored or %NULL if @manager is ephemeral.
499 *
500 * Since: 2.10
501 */
502const gchar* webkit_website_data_manager_get_local_storage_directory(WebKitWebsiteDataManager* manager)
503{
504 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
505
506 WebKitWebsiteDataManagerPrivate* priv = manager->priv;
507 if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent())
508 return nullptr;
509
510 if (!priv->localStorageDirectory)
511 priv->localStorageDirectory.reset(g_strdup(API::WebsiteDataStore::defaultLocalStorageDirectory().utf8().data()));
512 return priv->localStorageDirectory.get();
513}
514
515/**
516 * webkit_website_data_manager_get_disk_cache_directory:
517 * @manager: a #WebKitWebsiteDataManager
518 *
519 * Get the #WebKitWebsiteDataManager:disk-cache-directory property.
520 *
521 * Returns: (allow-none): the directory where HTTP disk cache is stored or %NULL if @manager is ephemeral.
522 *
523 * Since: 2.10
524 */
525const gchar* webkit_website_data_manager_get_disk_cache_directory(WebKitWebsiteDataManager* manager)
526{
527 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
528
529 WebKitWebsiteDataManagerPrivate* priv = manager->priv;
530 if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent())
531 return nullptr;
532
533 if (!priv->diskCacheDirectory) {
534 // The default directory already has the subdirectory.
535 priv->diskCacheDirectory.reset(g_strdup(FileSystem::directoryName(API::WebsiteDataStore::defaultNetworkCacheDirectory()).utf8().data()));
536 }
537 return priv->diskCacheDirectory.get();
538}
539
540/**
541 * webkit_website_data_manager_get_offline_application_cache_directory:
542 * @manager: a #WebKitWebsiteDataManager
543 *
544 * Get the #WebKitWebsiteDataManager:offline-application-cache-directory property.
545 *
546 * Returns: (allow-none): the directory where offline web application cache is stored or %NULL if @manager is ephemeral.
547 *
548 * Since: 2.10
549 */
550const gchar* webkit_website_data_manager_get_offline_application_cache_directory(WebKitWebsiteDataManager* manager)
551{
552 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
553
554 WebKitWebsiteDataManagerPrivate* priv = manager->priv;
555 if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent())
556 return nullptr;
557
558 if (!priv->applicationCacheDirectory)
559 priv->applicationCacheDirectory.reset(g_strdup(API::WebsiteDataStore::defaultApplicationCacheDirectory().utf8().data()));
560 return priv->applicationCacheDirectory.get();
561}
562
563/**
564 * webkit_website_data_manager_get_indexeddb_directory:
565 * @manager: a #WebKitWebsiteDataManager
566 *
567 * Get the #WebKitWebsiteDataManager:indexeddb-directory property.
568 *
569 * Returns: (allow-none): the directory where IndexedDB databases are stored or %NULL if @manager is ephemeral.
570 *
571 * Since: 2.10
572 */
573const gchar* webkit_website_data_manager_get_indexeddb_directory(WebKitWebsiteDataManager* manager)
574{
575 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
576
577 WebKitWebsiteDataManagerPrivate* priv = manager->priv;
578 if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent())
579 return nullptr;
580
581 if (!priv->indexedDBDirectory)
582 priv->indexedDBDirectory.reset(g_strdup(API::WebsiteDataStore::defaultIndexedDBDatabaseDirectory().utf8().data()));
583 return priv->indexedDBDirectory.get();
584}
585
586/**
587 * webkit_website_data_manager_get_websql_directory:
588 * @manager: a #WebKitWebsiteDataManager
589 *
590 * Get the #WebKitWebsiteDataManager:websql-directory property.
591 *
592 * Returns: (allow-none): the directory where WebSQL databases are stored or %NULL if @manager is ephemeral.
593 *
594 * Since: 2.10
595 */
596const gchar* webkit_website_data_manager_get_websql_directory(WebKitWebsiteDataManager* manager)
597{
598 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
599
600 WebKitWebsiteDataManagerPrivate* priv = manager->priv;
601 if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent())
602 return nullptr;
603
604 if (!priv->webSQLDirectory)
605 priv->webSQLDirectory.reset(g_strdup(API::WebsiteDataStore::defaultWebSQLDatabaseDirectory().utf8().data()));
606 return priv->webSQLDirectory.get();
607}
608
609/**
610 * webkit_website_data_manager_get_cookie_manager:
611 * @manager: a #WebKitWebsiteDataManager
612 *
613 * Get the #WebKitCookieManager of @manager.
614 *
615 * Returns: (transfer none): a #WebKitCookieManager
616 *
617 * Since: 2.16
618 */
619WebKitCookieManager* webkit_website_data_manager_get_cookie_manager(WebKitWebsiteDataManager* manager)
620{
621 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
622
623 if (!manager->priv->cookieManager)
624 manager->priv->cookieManager = adoptGRef(webkitCookieManagerCreate(manager));
625
626 return manager->priv->cookieManager.get();
627}
628
629static OptionSet<WebsiteDataType> toWebsiteDataTypes(WebKitWebsiteDataTypes types)
630{
631 OptionSet<WebsiteDataType> returnValue;
632 if (types & WEBKIT_WEBSITE_DATA_MEMORY_CACHE)
633 returnValue.add(WebsiteDataType::MemoryCache);
634 if (types & WEBKIT_WEBSITE_DATA_DISK_CACHE)
635 returnValue.add(WebsiteDataType::DiskCache);
636 if (types & WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE)
637 returnValue.add(WebsiteDataType::OfflineWebApplicationCache);
638 if (types & WEBKIT_WEBSITE_DATA_SESSION_STORAGE)
639 returnValue.add(WebsiteDataType::SessionStorage);
640 if (types & WEBKIT_WEBSITE_DATA_LOCAL_STORAGE)
641 returnValue.add(WebsiteDataType::LocalStorage);
642 if (types & WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES)
643 returnValue.add(WebsiteDataType::WebSQLDatabases);
644 if (types & WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES)
645 returnValue.add(WebsiteDataType::IndexedDBDatabases);
646#if ENABLE(NETSCAPE_PLUGIN_API)
647 if (types & WEBKIT_WEBSITE_DATA_PLUGIN_DATA)
648 returnValue.add(WebsiteDataType::PlugInData);
649#endif
650 if (types & WEBKIT_WEBSITE_DATA_COOKIES)
651 returnValue.add(WebsiteDataType::Cookies);
652 if (types & WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT)
653 returnValue.add(WebsiteDataType::DeviceIdHashSalt);
654 return returnValue;
655}
656
657/**
658 * webkit_website_data_manager_fetch:
659 * @manager: a #WebKitWebsiteDataManager
660 * @types: #WebKitWebsiteDataTypes
661 * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
662 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
663 * @user_data: (closure): the data to pass to callback function
664 *
665 * Asynchronously get the list of #WebKitWebsiteData for the given @types.
666 *
667 * When the operation is finished, @callback will be called. You can then call
668 * webkit_website_data_manager_fetch_finish() to get the result of the operation.
669 *
670 * Since: 2.16
671 */
672void webkit_website_data_manager_fetch(WebKitWebsiteDataManager* manager, WebKitWebsiteDataTypes types, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
673{
674 g_return_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager));
675
676 GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData));
677 manager->priv->websiteDataStore->websiteDataStore().fetchData(toWebsiteDataTypes(types), WebsiteDataFetchOption::ComputeSizes, [task = WTFMove(task)] (Vector<WebsiteDataRecord> records) {
678 GList* dataList = nullptr;
679 while (!records.isEmpty()) {
680 if (auto* data = webkitWebsiteDataCreate(records.takeLast()))
681 dataList = g_list_prepend(dataList, data);
682 }
683
684 g_task_return_pointer(task.get(), dataList, [](gpointer data) {
685 g_list_free_full(static_cast<GList*>(data), reinterpret_cast<GDestroyNotify>(webkit_website_data_unref));
686 });
687 });
688}
689
690/**
691 * webkit_website_data_manager_fetch_finish:
692 * @manager: a #WebKitWebsiteDataManager
693 * @result: a #GAsyncResult
694 * @error: return location for error or %NULL to ignore
695 *
696 * Finish an asynchronous operation started with webkit_website_data_manager_fetch().
697 *
698 * Returns: (element-type WebKitWebsiteData) (transfer full): a #GList of #WebKitWebsiteData. You must free the #GList with
699 * g_list_free() and unref the #WebKitWebsiteData<!-- -->s with webkit_website_data_unref() when you're done with them.
700 *
701 * Since: 2.16
702 */
703GList* webkit_website_data_manager_fetch_finish(WebKitWebsiteDataManager* manager, GAsyncResult* result, GError** error)
704{
705 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
706 g_return_val_if_fail(g_task_is_valid(result, manager), nullptr);
707
708 return static_cast<GList*>(g_task_propagate_pointer(G_TASK(result), error));
709}
710
711/**
712 * webkit_website_data_manager_remove:
713 * @manager: a #WebKitWebsiteDataManager
714 * @types: #WebKitWebsiteDataTypes
715 * @website_data: (element-type WebKitWebsiteData): a #GList of #WebKitWebsiteData
716 * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
717 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
718 * @user_data: (closure): the data to pass to callback function
719 *
720 * Asynchronously removes the website data of the for the given @types for websites in the given @website_data list.
721 * Use webkit_website_data_manager_clear() if you want to remove the website data for all sites.
722 *
723 * When the operation is finished, @callback will be called. You can then call
724 * webkit_website_data_manager_remove_finish() to get the result of the operation.
725 *
726 * Since: 2.16
727 */
728void webkit_website_data_manager_remove(WebKitWebsiteDataManager* manager, WebKitWebsiteDataTypes types, GList* websiteData, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
729{
730 g_return_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager));
731 g_return_if_fail(websiteData);
732
733 // We have to remove the hash salts when cookies are removed.
734 if (types & WEBKIT_WEBSITE_DATA_COOKIES)
735 types = static_cast<WebKitWebsiteDataTypes>(types | WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT);
736
737 Vector<WebsiteDataRecord> records;
738 for (GList* item = websiteData; item; item = g_list_next(item)) {
739 WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(item->data);
740
741 if (webkit_website_data_get_types(data) & types)
742 records.append(webkitWebsiteDataGetRecord(data));
743 }
744
745 GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData));
746 if (records.isEmpty()) {
747 g_task_return_boolean(task.get(), TRUE);
748 return;
749 }
750
751 manager->priv->websiteDataStore->websiteDataStore().removeData(toWebsiteDataTypes(types), records, [task = WTFMove(task)] {
752 g_task_return_boolean(task.get(), TRUE);
753 });
754}
755
756/**
757 * webkit_website_data_manager_remove_finish:
758 * @manager: a #WebKitWebsiteDataManager
759 * @result: a #GAsyncResult
760 * @error: return location for error or %NULL to ignore
761 *
762 * Finish an asynchronous operation started with webkit_website_data_manager_remove().
763 *
764 * Returns: %TRUE if website data resources were successfully removed, or %FALSE otherwise.
765 *
766 * Since: 2.16
767 */
768gboolean webkit_website_data_manager_remove_finish(WebKitWebsiteDataManager* manager, GAsyncResult* result, GError** error)
769{
770 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), FALSE);
771 g_return_val_if_fail(g_task_is_valid(result, manager), FALSE);
772
773 return g_task_propagate_boolean(G_TASK(result), error);
774}
775
776/**
777 * webkit_website_data_manager_clear:
778 * @manager: a #WebKitWebsiteDataManager
779 * @types: #WebKitWebsiteDataTypes
780 * @timespan: a #GTimeSpan
781 * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
782 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
783 * @user_data: (closure): the data to pass to callback function
784 *
785 * Asynchronously clear the website data of the given @types modified in the past @timespan.
786 * If @timespan is 0, all website data will be removed.
787 *
788 * When the operation is finished, @callback will be called. You can then call
789 * webkit_website_data_manager_clear_finish() to get the result of the operation.
790 *
791 * Due to implementation limitations, this function does not currently delete
792 * any stored cookies if @timespan is nonzero. This behavior may change in the
793 * future.
794 *
795 * Since: 2.16
796 */
797void webkit_website_data_manager_clear(WebKitWebsiteDataManager* manager, WebKitWebsiteDataTypes types, GTimeSpan timeSpan, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
798{
799 g_return_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager));
800
801 WallTime timePoint = timeSpan ? WallTime::now() - Seconds::fromMicroseconds(timeSpan) : WallTime::fromRawSeconds(0);
802 GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData));
803 manager->priv->websiteDataStore->websiteDataStore().removeData(toWebsiteDataTypes(types), timePoint, [task = WTFMove(task)] {
804 g_task_return_boolean(task.get(), TRUE);
805 });
806}
807
808/**
809 * webkit_website_data_manager_clear_finish:
810 * @manager: a #WebKitWebsiteDataManager
811 * @result: a #GAsyncResult
812 * @error: return location for error or %NULL to ignore
813 *
814 * Finish an asynchronous operation started with webkit_website_data_manager_clear()
815 *
816 * Returns: %TRUE if website data was successfully cleared, or %FALSE otherwise.
817 *
818 * Since: 2.16
819 */
820gboolean webkit_website_data_manager_clear_finish(WebKitWebsiteDataManager* manager, GAsyncResult* result, GError** error)
821{
822 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), FALSE);
823 g_return_val_if_fail(g_task_is_valid(result, manager), FALSE);
824
825 return g_task_propagate_boolean(G_TASK(result), error);
826}
827