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 ALLOW_DEPRECATED_DECLARATIONS_BEGIN
136 g_value_set_string(value, webkit_website_data_manager_get_websql_directory(manager));
137 ALLOW_DEPRECATED_DECLARATIONS_END
138 break;
139 case PROP_IS_EPHEMERAL:
140 g_value_set_boolean(value, webkit_website_data_manager_is_ephemeral(manager));
141 break;
142 default:
143 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec);
144 }
145}
146
147static void webkitWebsiteDataManagerSetProperty(GObject* object, guint propID, const GValue* value, GParamSpec* paramSpec)
148{
149 WebKitWebsiteDataManager* manager = WEBKIT_WEBSITE_DATA_MANAGER(object);
150
151 switch (propID) {
152 case PROP_BASE_DATA_DIRECTORY:
153 manager->priv->baseDataDirectory.reset(g_value_dup_string(value));
154 break;
155 case PROP_BASE_CACHE_DIRECTORY:
156 manager->priv->baseCacheDirectory.reset(g_value_dup_string(value));
157 break;
158 case PROP_LOCAL_STORAGE_DIRECTORY:
159 manager->priv->localStorageDirectory.reset(g_value_dup_string(value));
160 break;
161 case PROP_DISK_CACHE_DIRECTORY:
162 manager->priv->diskCacheDirectory.reset(g_value_dup_string(value));
163 break;
164 case PROP_APPLICATION_CACHE_DIRECTORY:
165 manager->priv->applicationCacheDirectory.reset(g_value_dup_string(value));
166 break;
167 case PROP_INDEXEDDB_DIRECTORY:
168 manager->priv->indexedDBDirectory.reset(g_value_dup_string(value));
169 break;
170 case PROP_WEBSQL_DIRECTORY:
171 manager->priv->webSQLDirectory.reset(g_value_dup_string(value));
172 break;
173 case PROP_IS_EPHEMERAL:
174 if (g_value_get_boolean(value))
175 manager->priv->websiteDataStore = API::WebsiteDataStore::createNonPersistentDataStore();
176 break;
177 default:
178 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec);
179 }
180}
181
182static void webkitWebsiteDataManagerConstructed(GObject* object)
183{
184 G_OBJECT_CLASS(webkit_website_data_manager_parent_class)->constructed(object);
185
186 WebKitWebsiteDataManagerPrivate* priv = WEBKIT_WEBSITE_DATA_MANAGER(object)->priv;
187 if (priv->baseDataDirectory) {
188 if (!priv->localStorageDirectory)
189 priv->localStorageDirectory.reset(g_build_filename(priv->baseDataDirectory.get(), "localstorage", nullptr));
190 if (!priv->indexedDBDirectory)
191 priv->indexedDBDirectory.reset(g_build_filename(priv->baseDataDirectory.get(), "databases", "indexeddb", nullptr));
192 if (!priv->webSQLDirectory)
193 priv->webSQLDirectory.reset(g_build_filename(priv->baseDataDirectory.get(), "databases", nullptr));
194 }
195
196 if (priv->baseCacheDirectory) {
197 if (!priv->diskCacheDirectory)
198 priv->diskCacheDirectory.reset(g_strdup(priv->baseCacheDirectory.get()));
199 if (!priv->applicationCacheDirectory)
200 priv->applicationCacheDirectory.reset(g_build_filename(priv->baseCacheDirectory.get(), "applications", nullptr));
201 }
202}
203
204static void webkit_website_data_manager_class_init(WebKitWebsiteDataManagerClass* findClass)
205{
206 GObjectClass* gObjectClass = G_OBJECT_CLASS(findClass);
207
208 gObjectClass->get_property = webkitWebsiteDataManagerGetProperty;
209 gObjectClass->set_property = webkitWebsiteDataManagerSetProperty;
210 gObjectClass->constructed = webkitWebsiteDataManagerConstructed;
211
212 /**
213 * WebKitWebsiteDataManager:base-data-directory:
214 *
215 * The base directory for Website data. This is used as a base directory
216 * for any Website data when no specific data directory has been provided.
217 *
218 * Since: 2.10
219 */
220 g_object_class_install_property(
221 gObjectClass,
222 PROP_BASE_DATA_DIRECTORY,
223 g_param_spec_string(
224 "base-data-directory",
225 _("Base Data Directory"),
226 _("The base directory for Website data"),
227 nullptr,
228 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
229
230 /**
231 * WebKitWebsiteDataManager:base-cache-directory:
232 *
233 * The base directory for Website cache. This is used as a base directory
234 * for any Website cache when no specific cache directory has been provided.
235 *
236 * Since: 2.10
237 */
238 g_object_class_install_property(
239 gObjectClass,
240 PROP_BASE_CACHE_DIRECTORY,
241 g_param_spec_string(
242 "base-cache-directory",
243 _("Base Cache Directory"),
244 _("The base directory for Website cache"),
245 nullptr,
246 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
247
248 /**
249 * WebKitWebsiteDataManager:local-storage-directory:
250 *
251 * The directory where local storage data will be stored.
252 *
253 * Since: 2.10
254 */
255 g_object_class_install_property(
256 gObjectClass,
257 PROP_LOCAL_STORAGE_DIRECTORY,
258 g_param_spec_string(
259 "local-storage-directory",
260 _("Local Storage Directory"),
261 _("The directory where local storage data will be stored"),
262 nullptr,
263 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
264
265 /**
266 * WebKitWebsiteDataManager:disk-cache-directory:
267 *
268 * The directory where HTTP disk cache will be stored.
269 *
270 * Since: 2.10
271 */
272 g_object_class_install_property(
273 gObjectClass,
274 PROP_DISK_CACHE_DIRECTORY,
275 g_param_spec_string(
276 "disk-cache-directory",
277 _("Disk Cache Directory"),
278 _("The directory where HTTP disk cache will be stored"),
279 nullptr,
280 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
281
282 /**
283 * WebKitWebsiteDataManager:offline-application-cache-directory:
284 *
285 * The directory where offline web application cache will be stored.
286 *
287 * Since: 2.10
288 */
289 g_object_class_install_property(
290 gObjectClass,
291 PROP_APPLICATION_CACHE_DIRECTORY,
292 g_param_spec_string(
293 "offline-application-cache-directory",
294 _("Offline Web Application Cache Directory"),
295 _("The directory where offline web application cache will be stored"),
296 nullptr,
297 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
298
299 /**
300 * WebKitWebsiteDataManager:indexeddb-directory:
301 *
302 * The directory where IndexedDB databases will be stored.
303 *
304 * Since: 2.10
305 */
306 g_object_class_install_property(
307 gObjectClass,
308 PROP_INDEXEDDB_DIRECTORY,
309 g_param_spec_string(
310 "indexeddb-directory",
311 _("IndexedDB Directory"),
312 _("The directory where IndexedDB databases will be stored"),
313 nullptr,
314 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
315
316 /**
317 * WebKitWebsiteDataManager:websql-directory:
318 *
319 * The directory where WebSQL databases will be stored.
320 *
321 * Since: 2.10
322 *
323 * Deprecated: 2.24. WebSQL is no longer supported. Use IndexedDB instead.
324 */
325 g_object_class_install_property(
326 gObjectClass,
327 PROP_WEBSQL_DIRECTORY,
328 g_param_spec_string(
329 "websql-directory",
330 _("WebSQL Directory"),
331 _("The directory where WebSQL databases will be stored"),
332 nullptr,
333 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_DEPRECATED)));
334
335 /**
336 * WebKitWebsiteDataManager:is-ephemeral:
337 *
338 * Whether the #WebKitWebsiteDataManager is ephemeral. An ephemeral #WebKitWebsiteDataManager
339 * handles all websites data as non-persistent, and nothing will be written to the client
340 * storage. Note that if you create an ephemeral #WebKitWebsiteDataManager all other construction
341 * parameters to configure data directories will be ignored.
342 *
343 * Since: 2.16
344 */
345 g_object_class_install_property(
346 gObjectClass,
347 PROP_IS_EPHEMERAL,
348 g_param_spec_boolean(
349 "is-ephemeral",
350 "Is Ephemeral",
351 _("Whether the WebKitWebsiteDataManager is ephemeral"),
352 FALSE,
353 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
354}
355
356WebKitWebsiteDataManager* webkitWebsiteDataManagerCreate(Ref<WebsiteDataStoreConfiguration>&& configuration)
357{
358 WebKitWebsiteDataManager* manager = WEBKIT_WEBSITE_DATA_MANAGER(g_object_new(WEBKIT_TYPE_WEBSITE_DATA_MANAGER, nullptr));
359 manager->priv->websiteDataStore = API::WebsiteDataStore::createLegacy(WTFMove(configuration));
360
361 return manager;
362}
363
364API::WebsiteDataStore& webkitWebsiteDataManagerGetDataStore(WebKitWebsiteDataManager* manager)
365{
366 WebKitWebsiteDataManagerPrivate* priv = manager->priv;
367 if (!priv->websiteDataStore) {
368 auto configuration = WebsiteDataStoreConfiguration::create();
369 configuration->setLocalStorageDirectory(!priv->localStorageDirectory ?
370 API::WebsiteDataStore::defaultLocalStorageDirectory() : FileSystem::stringFromFileSystemRepresentation(priv->localStorageDirectory.get()));
371 configuration->setNetworkCacheDirectory(!priv->diskCacheDirectory ?
372 API::WebsiteDataStore::defaultNetworkCacheDirectory() : FileSystem::pathByAppendingComponent(FileSystem::stringFromFileSystemRepresentation(priv->diskCacheDirectory.get()), networkCacheSubdirectory));
373 configuration->setApplicationCacheDirectory(!priv->applicationCacheDirectory ?
374 API::WebsiteDataStore::defaultApplicationCacheDirectory() : FileSystem::stringFromFileSystemRepresentation(priv->applicationCacheDirectory.get()));
375 configuration->setWebSQLDatabaseDirectory(!priv->webSQLDirectory ?
376 API::WebsiteDataStore::defaultWebSQLDatabaseDirectory() : FileSystem::stringFromFileSystemRepresentation(priv->webSQLDirectory.get()));
377 configuration->setMediaKeysStorageDirectory(API::WebsiteDataStore::defaultMediaKeysStorageDirectory());
378 priv->websiteDataStore = API::WebsiteDataStore::createLegacy(WTFMove(configuration));
379 }
380
381 return *priv->websiteDataStore;
382}
383
384void webkitWebsiteDataManagerAddProcessPool(WebKitWebsiteDataManager* manager, WebProcessPool& processPool)
385{
386 ASSERT(!manager->priv->processPools.contains(&processPool));
387 manager->priv->processPools.append(&processPool);
388}
389
390void webkitWebsiteDataManagerRemoveProcessPool(WebKitWebsiteDataManager* manager, WebProcessPool& processPool)
391{
392 ASSERT(manager->priv->processPools.contains(&processPool));
393 manager->priv->processPools.removeFirst(&processPool);
394}
395
396const Vector<WebProcessPool*>& webkitWebsiteDataManagerGetProcessPools(WebKitWebsiteDataManager* manager)
397{
398 return manager->priv->processPools;
399}
400
401/**
402 * webkit_website_data_manager_new:
403 * @first_option_name: name of the first option to set
404 * @...: value of first option, followed by more options, %NULL-terminated
405 *
406 * Creates a new #WebKitWebsiteDataManager with the given options. It must
407 * be passed as construction parameter of a #WebKitWebContext.
408 *
409 * Returns: (transfer full): the newly created #WebKitWebsiteDataManager
410 *
411 * Since: 2.10
412 */
413WebKitWebsiteDataManager* webkit_website_data_manager_new(const gchar* firstOptionName, ...)
414{
415 va_list args;
416 va_start(args, firstOptionName);
417 WebKitWebsiteDataManager* manager = WEBKIT_WEBSITE_DATA_MANAGER(g_object_new_valist(WEBKIT_TYPE_WEBSITE_DATA_MANAGER, firstOptionName, args));
418 va_end(args);
419
420 return manager;
421}
422
423/**
424 * webkit_website_data_manager_new_ephemeral:
425 *
426 * Creates an ephemeral #WebKitWebsiteDataManager. See #WebKitWebsiteDataManager:is-ephemeral for more details.
427 *
428 * Returns: (transfer full): a new ephemeral #WebKitWebsiteDataManager.
429 *
430 * Since: 2.16
431 */
432WebKitWebsiteDataManager* webkit_website_data_manager_new_ephemeral()
433{
434 return WEBKIT_WEBSITE_DATA_MANAGER(g_object_new(WEBKIT_TYPE_WEBSITE_DATA_MANAGER, "is-ephemeral", TRUE, nullptr));
435}
436
437/**
438 * webkit_website_data_manager_is_ephemeral:
439 * @manager: a #WebKitWebsiteDataManager
440 *
441 * Get whether a #WebKitWebsiteDataManager is ephemeral. See #WebKitWebsiteDataManager:is-ephemeral for more details.
442 *
443 * Returns: %TRUE if @manager is epheral or %FALSE otherwise.
444 *
445 * Since: 2.16
446 */
447gboolean webkit_website_data_manager_is_ephemeral(WebKitWebsiteDataManager* manager)
448{
449 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), FALSE);
450
451 return manager->priv->websiteDataStore && !manager->priv->websiteDataStore->isPersistent();
452}
453
454/**
455 * webkit_website_data_manager_get_base_data_directory:
456 * @manager: a #WebKitWebsiteDataManager
457 *
458 * Get the #WebKitWebsiteDataManager:base-data-directory property.
459 *
460 * Returns: (allow-none): the base directory for Website data, or %NULL if
461 * #WebKitWebsiteDataManager:base-data-directory was not provided or @manager is ephemeral.
462 *
463 * Since: 2.10
464 */
465const gchar* webkit_website_data_manager_get_base_data_directory(WebKitWebsiteDataManager* manager)
466{
467 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
468
469 if (manager->priv->websiteDataStore && !manager->priv->websiteDataStore->isPersistent())
470 return nullptr;
471
472 return manager->priv->baseDataDirectory.get();
473}
474
475/**
476 * webkit_website_data_manager_get_base_cache_directory:
477 * @manager: a #WebKitWebsiteDataManager
478 *
479 * Get the #WebKitWebsiteDataManager:base-cache-directory property.
480 *
481 * Returns: (allow-none): the base directory for Website cache, or %NULL if
482 * #WebKitWebsiteDataManager:base-cache-directory was not provided or @manager is ephemeral.
483 *
484 * Since: 2.10
485 */
486const gchar* webkit_website_data_manager_get_base_cache_directory(WebKitWebsiteDataManager* manager)
487{
488 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
489
490 if (manager->priv->websiteDataStore && !manager->priv->websiteDataStore->isPersistent())
491 return nullptr;
492
493 return manager->priv->baseCacheDirectory.get();
494}
495
496/**
497 * webkit_website_data_manager_get_local_storage_directory:
498 * @manager: a #WebKitWebsiteDataManager
499 *
500 * Get the #WebKitWebsiteDataManager:local-storage-directory property.
501 *
502 * Returns: (allow-none): the directory where local storage data is stored or %NULL if @manager is ephemeral.
503 *
504 * Since: 2.10
505 */
506const gchar* webkit_website_data_manager_get_local_storage_directory(WebKitWebsiteDataManager* manager)
507{
508 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
509
510 WebKitWebsiteDataManagerPrivate* priv = manager->priv;
511 if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent())
512 return nullptr;
513
514 if (!priv->localStorageDirectory)
515 priv->localStorageDirectory.reset(g_strdup(API::WebsiteDataStore::defaultLocalStorageDirectory().utf8().data()));
516 return priv->localStorageDirectory.get();
517}
518
519/**
520 * webkit_website_data_manager_get_disk_cache_directory:
521 * @manager: a #WebKitWebsiteDataManager
522 *
523 * Get the #WebKitWebsiteDataManager:disk-cache-directory property.
524 *
525 * Returns: (allow-none): the directory where HTTP disk cache is stored or %NULL if @manager is ephemeral.
526 *
527 * Since: 2.10
528 */
529const gchar* webkit_website_data_manager_get_disk_cache_directory(WebKitWebsiteDataManager* manager)
530{
531 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
532
533 WebKitWebsiteDataManagerPrivate* priv = manager->priv;
534 if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent())
535 return nullptr;
536
537 if (!priv->diskCacheDirectory) {
538 // The default directory already has the subdirectory.
539 priv->diskCacheDirectory.reset(g_strdup(FileSystem::directoryName(API::WebsiteDataStore::defaultNetworkCacheDirectory()).utf8().data()));
540 }
541 return priv->diskCacheDirectory.get();
542}
543
544/**
545 * webkit_website_data_manager_get_offline_application_cache_directory:
546 * @manager: a #WebKitWebsiteDataManager
547 *
548 * Get the #WebKitWebsiteDataManager:offline-application-cache-directory property.
549 *
550 * Returns: (allow-none): the directory where offline web application cache is stored or %NULL if @manager is ephemeral.
551 *
552 * Since: 2.10
553 */
554const gchar* webkit_website_data_manager_get_offline_application_cache_directory(WebKitWebsiteDataManager* manager)
555{
556 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
557
558 WebKitWebsiteDataManagerPrivate* priv = manager->priv;
559 if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent())
560 return nullptr;
561
562 if (!priv->applicationCacheDirectory)
563 priv->applicationCacheDirectory.reset(g_strdup(API::WebsiteDataStore::defaultApplicationCacheDirectory().utf8().data()));
564 return priv->applicationCacheDirectory.get();
565}
566
567/**
568 * webkit_website_data_manager_get_indexeddb_directory:
569 * @manager: a #WebKitWebsiteDataManager
570 *
571 * Get the #WebKitWebsiteDataManager:indexeddb-directory property.
572 *
573 * Returns: (allow-none): the directory where IndexedDB databases are stored or %NULL if @manager is ephemeral.
574 *
575 * Since: 2.10
576 */
577const gchar* webkit_website_data_manager_get_indexeddb_directory(WebKitWebsiteDataManager* manager)
578{
579 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
580
581 WebKitWebsiteDataManagerPrivate* priv = manager->priv;
582 if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent())
583 return nullptr;
584
585 if (!priv->indexedDBDirectory)
586 priv->indexedDBDirectory.reset(g_strdup(API::WebsiteDataStore::defaultIndexedDBDatabaseDirectory().utf8().data()));
587 return priv->indexedDBDirectory.get();
588}
589
590/**
591 * webkit_website_data_manager_get_websql_directory:
592 * @manager: a #WebKitWebsiteDataManager
593 *
594 * Get the #WebKitWebsiteDataManager:websql-directory property.
595 *
596 * Returns: (allow-none): the directory where WebSQL databases are stored or %NULL if @manager is ephemeral.
597 *
598 * Since: 2.10
599 *
600 * Deprecated: 2.24. WebSQL is no longer supported. Use IndexedDB instead.
601 */
602const gchar* webkit_website_data_manager_get_websql_directory(WebKitWebsiteDataManager* manager)
603{
604 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
605
606 WebKitWebsiteDataManagerPrivate* priv = manager->priv;
607 if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent())
608 return nullptr;
609
610 if (!priv->webSQLDirectory)
611 priv->webSQLDirectory.reset(g_strdup(API::WebsiteDataStore::defaultWebSQLDatabaseDirectory().utf8().data()));
612 return priv->webSQLDirectory.get();
613}
614
615/**
616 * webkit_website_data_manager_get_cookie_manager:
617 * @manager: a #WebKitWebsiteDataManager
618 *
619 * Get the #WebKitCookieManager of @manager.
620 *
621 * Returns: (transfer none): a #WebKitCookieManager
622 *
623 * Since: 2.16
624 */
625WebKitCookieManager* webkit_website_data_manager_get_cookie_manager(WebKitWebsiteDataManager* manager)
626{
627 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
628
629 if (!manager->priv->cookieManager)
630 manager->priv->cookieManager = adoptGRef(webkitCookieManagerCreate(manager));
631
632 return manager->priv->cookieManager.get();
633}
634
635static OptionSet<WebsiteDataType> toWebsiteDataTypes(WebKitWebsiteDataTypes types)
636{
637 OptionSet<WebsiteDataType> returnValue;
638 if (types & WEBKIT_WEBSITE_DATA_MEMORY_CACHE)
639 returnValue.add(WebsiteDataType::MemoryCache);
640 if (types & WEBKIT_WEBSITE_DATA_DISK_CACHE)
641 returnValue.add(WebsiteDataType::DiskCache);
642 if (types & WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE)
643 returnValue.add(WebsiteDataType::OfflineWebApplicationCache);
644 if (types & WEBKIT_WEBSITE_DATA_SESSION_STORAGE)
645 returnValue.add(WebsiteDataType::SessionStorage);
646 if (types & WEBKIT_WEBSITE_DATA_LOCAL_STORAGE)
647 returnValue.add(WebsiteDataType::LocalStorage);
648 if (types & WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES)
649 returnValue.add(WebsiteDataType::WebSQLDatabases);
650 if (types & WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES)
651 returnValue.add(WebsiteDataType::IndexedDBDatabases);
652#if ENABLE(NETSCAPE_PLUGIN_API)
653 if (types & WEBKIT_WEBSITE_DATA_PLUGIN_DATA)
654 returnValue.add(WebsiteDataType::PlugInData);
655#endif
656 if (types & WEBKIT_WEBSITE_DATA_COOKIES)
657 returnValue.add(WebsiteDataType::Cookies);
658 if (types & WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT)
659 returnValue.add(WebsiteDataType::DeviceIdHashSalt);
660 return returnValue;
661}
662
663/**
664 * webkit_website_data_manager_fetch:
665 * @manager: a #WebKitWebsiteDataManager
666 * @types: #WebKitWebsiteDataTypes
667 * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
668 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
669 * @user_data: (closure): the data to pass to callback function
670 *
671 * Asynchronously get the list of #WebKitWebsiteData for the given @types.
672 *
673 * When the operation is finished, @callback will be called. You can then call
674 * webkit_website_data_manager_fetch_finish() to get the result of the operation.
675 *
676 * Since: 2.16
677 */
678void webkit_website_data_manager_fetch(WebKitWebsiteDataManager* manager, WebKitWebsiteDataTypes types, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
679{
680 g_return_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager));
681
682 GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData));
683 manager->priv->websiteDataStore->websiteDataStore().fetchData(toWebsiteDataTypes(types), WebsiteDataFetchOption::ComputeSizes, [task = WTFMove(task)] (Vector<WebsiteDataRecord> records) {
684 GList* dataList = nullptr;
685 while (!records.isEmpty()) {
686 if (auto* data = webkitWebsiteDataCreate(records.takeLast()))
687 dataList = g_list_prepend(dataList, data);
688 }
689
690 g_task_return_pointer(task.get(), dataList, [](gpointer data) {
691 g_list_free_full(static_cast<GList*>(data), reinterpret_cast<GDestroyNotify>(webkit_website_data_unref));
692 });
693 });
694}
695
696/**
697 * webkit_website_data_manager_fetch_finish:
698 * @manager: a #WebKitWebsiteDataManager
699 * @result: a #GAsyncResult
700 * @error: return location for error or %NULL to ignore
701 *
702 * Finish an asynchronous operation started with webkit_website_data_manager_fetch().
703 *
704 * Returns: (element-type WebKitWebsiteData) (transfer full): a #GList of #WebKitWebsiteData. You must free the #GList with
705 * g_list_free() and unref the #WebKitWebsiteData<!-- -->s with webkit_website_data_unref() when you're done with them.
706 *
707 * Since: 2.16
708 */
709GList* webkit_website_data_manager_fetch_finish(WebKitWebsiteDataManager* manager, GAsyncResult* result, GError** error)
710{
711 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
712 g_return_val_if_fail(g_task_is_valid(result, manager), nullptr);
713
714 return static_cast<GList*>(g_task_propagate_pointer(G_TASK(result), error));
715}
716
717/**
718 * webkit_website_data_manager_remove:
719 * @manager: a #WebKitWebsiteDataManager
720 * @types: #WebKitWebsiteDataTypes
721 * @website_data: (element-type WebKitWebsiteData): a #GList of #WebKitWebsiteData
722 * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
723 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
724 * @user_data: (closure): the data to pass to callback function
725 *
726 * Asynchronously removes the website data of the for the given @types for websites in the given @website_data list.
727 * Use webkit_website_data_manager_clear() if you want to remove the website data for all sites.
728 *
729 * When the operation is finished, @callback will be called. You can then call
730 * webkit_website_data_manager_remove_finish() to get the result of the operation.
731 *
732 * Since: 2.16
733 */
734void webkit_website_data_manager_remove(WebKitWebsiteDataManager* manager, WebKitWebsiteDataTypes types, GList* websiteData, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
735{
736 g_return_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager));
737 g_return_if_fail(websiteData);
738
739 // We have to remove the hash salts when cookies are removed.
740 if (types & WEBKIT_WEBSITE_DATA_COOKIES)
741 types = static_cast<WebKitWebsiteDataTypes>(types | WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT);
742
743 Vector<WebsiteDataRecord> records;
744 for (GList* item = websiteData; item; item = g_list_next(item)) {
745 WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(item->data);
746
747 if (webkit_website_data_get_types(data) & types)
748 records.append(webkitWebsiteDataGetRecord(data));
749 }
750
751 GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData));
752 if (records.isEmpty()) {
753 g_task_return_boolean(task.get(), TRUE);
754 return;
755 }
756
757 manager->priv->websiteDataStore->websiteDataStore().removeData(toWebsiteDataTypes(types), records, [task = WTFMove(task)] {
758 g_task_return_boolean(task.get(), TRUE);
759 });
760}
761
762/**
763 * webkit_website_data_manager_remove_finish:
764 * @manager: a #WebKitWebsiteDataManager
765 * @result: a #GAsyncResult
766 * @error: return location for error or %NULL to ignore
767 *
768 * Finish an asynchronous operation started with webkit_website_data_manager_remove().
769 *
770 * Returns: %TRUE if website data resources were successfully removed, or %FALSE otherwise.
771 *
772 * Since: 2.16
773 */
774gboolean webkit_website_data_manager_remove_finish(WebKitWebsiteDataManager* manager, GAsyncResult* result, GError** error)
775{
776 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), FALSE);
777 g_return_val_if_fail(g_task_is_valid(result, manager), FALSE);
778
779 return g_task_propagate_boolean(G_TASK(result), error);
780}
781
782/**
783 * webkit_website_data_manager_clear:
784 * @manager: a #WebKitWebsiteDataManager
785 * @types: #WebKitWebsiteDataTypes
786 * @timespan: a #GTimeSpan
787 * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
788 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
789 * @user_data: (closure): the data to pass to callback function
790 *
791 * Asynchronously clear the website data of the given @types modified in the past @timespan.
792 * If @timespan is 0, all website data will be removed.
793 *
794 * When the operation is finished, @callback will be called. You can then call
795 * webkit_website_data_manager_clear_finish() to get the result of the operation.
796 *
797 * Due to implementation limitations, this function does not currently delete
798 * any stored cookies if @timespan is nonzero. This behavior may change in the
799 * future.
800 *
801 * Since: 2.16
802 */
803void webkit_website_data_manager_clear(WebKitWebsiteDataManager* manager, WebKitWebsiteDataTypes types, GTimeSpan timeSpan, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
804{
805 g_return_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager));
806
807 WallTime timePoint = timeSpan ? WallTime::now() - Seconds::fromMicroseconds(timeSpan) : WallTime::fromRawSeconds(0);
808 GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData));
809 manager->priv->websiteDataStore->websiteDataStore().removeData(toWebsiteDataTypes(types), timePoint, [task = WTFMove(task)] {
810 g_task_return_boolean(task.get(), TRUE);
811 });
812}
813
814/**
815 * webkit_website_data_manager_clear_finish:
816 * @manager: a #WebKitWebsiteDataManager
817 * @result: a #GAsyncResult
818 * @error: return location for error or %NULL to ignore
819 *
820 * Finish an asynchronous operation started with webkit_website_data_manager_clear()
821 *
822 * Returns: %TRUE if website data was successfully cleared, or %FALSE otherwise.
823 *
824 * Since: 2.16
825 */
826gboolean webkit_website_data_manager_clear_finish(WebKitWebsiteDataManager* manager, GAsyncResult* result, GError** error)
827{
828 g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), FALSE);
829 g_return_val_if_fail(g_task_is_valid(result, manager), FALSE);
830
831 return g_task_propagate_boolean(G_TASK(result), error);
832}
833