| /* |
| * Copyright (C) 2017 Igalia S.L. |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public License |
| * along with this library; see the file COPYING.LIB. If not, write to |
| * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| */ |
| |
| #include "config.h" |
| |
| #include "WebKitTestServer.h" |
| #include "WebViewTest.h" |
| #include <WebCore/GUniquePtrSoup.h> |
| #include <glib/gstdio.h> |
| |
| static WebKitTestServer* kServer; |
| |
| static void serverCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer) |
| { |
| if (soup_server_message_get_method(message) != SOUP_METHOD_GET) { |
| soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr); |
| return; |
| } |
| |
| auto* responseBody = soup_server_message_get_response_body(message); |
| |
| if (g_str_equal(path, "/")) { |
| const char* html = "<html><body></body></html>"; |
| soup_message_body_append(responseBody, SOUP_MEMORY_STATIC, html, strlen(html)); |
| soup_message_body_complete(responseBody); |
| soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr); |
| } else if (g_str_equal(path, "/empty")) { |
| auto* responseHeaders = soup_server_message_get_response_headers(message); |
| soup_message_headers_replace(responseHeaders, "Set-Cookie", "foo=bar; Max-Age=60"); |
| soup_message_headers_replace(responseHeaders, "Strict-Transport-Security", "max-age=3600"); |
| static const char* emptyHTML = "<html><body></body></html>"; |
| soup_message_body_append(responseBody, SOUP_MEMORY_STATIC, emptyHTML, strlen(emptyHTML)); |
| soup_message_body_complete(responseBody); |
| soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr); |
| } else if (g_str_equal(path, "/sessionstorage")) { |
| static const char* sessionStorageHTML = "<html><body onload=\"sessionStorage.foo = 'bar';\"></body></html>"; |
| soup_message_body_append(responseBody, SOUP_MEMORY_STATIC, sessionStorageHTML, strlen(sessionStorageHTML)); |
| soup_message_body_complete(responseBody); |
| soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr); |
| } else if (g_str_equal(path, "/localstorage")) { |
| static const char* localStorageHTML = "<html><body onload=\"localStorage.foo = 'bar';\"></body></html>"; |
| soup_message_body_append(responseBody, SOUP_MEMORY_STATIC, localStorageHTML, strlen(localStorageHTML)); |
| soup_message_body_complete(responseBody); |
| soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr); |
| } else if (g_str_equal(path, "/enumeratedevices")) { |
| static const char* enumerateDevicesHTML = "<html><body onload=\"navigator.mediaDevices.enumerateDevices().then(function(devices) { document.title = 'Finished'; })\"></body></html>"; |
| soup_message_body_append(responseBody, SOUP_MEMORY_STATIC, enumerateDevicesHTML, strlen(enumerateDevicesHTML)); |
| soup_message_body_complete(responseBody); |
| soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr); |
| } else if (g_str_equal(path, "/service/register.html")) { |
| static const char* swRegisterHTML = "<html><body><script src=\"/service/register.js\"></script></body></html>"; |
| soup_message_body_append(responseBody, SOUP_MEMORY_STATIC, swRegisterHTML, strlen(swRegisterHTML)); |
| soup_message_body_complete(responseBody); |
| soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr); |
| } else if (g_str_equal(path, "/service/register.js")) { |
| static const char* swRegisterJS = |
| "async function test() { await navigator.serviceWorker.register(\"/service/empty-worker.js\"); } test();"; |
| soup_message_body_append(responseBody, SOUP_MEMORY_STATIC, swRegisterJS, strlen(swRegisterJS)); |
| soup_message_body_complete(responseBody); |
| soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr); |
| } else if (g_str_equal(path, "/service/empty-worker.js")) { |
| soup_message_body_complete(responseBody); |
| soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr); |
| } else |
| soup_server_message_set_status(message, SOUP_STATUS_NOT_FOUND, nullptr); |
| } |
| |
| class WebsiteDataTest : public WebViewTest { |
| public: |
| MAKE_GLIB_TEST_FIXTURE(WebsiteDataTest); |
| |
| WebsiteDataTest() |
| #if ENABLE(2022_GLIB_API) |
| : m_manager(webkit_network_session_get_website_data_manager(webkit_web_view_get_network_session(m_webView.get()))) |
| #else |
| : m_manager(webkit_web_context_get_website_data_manager(webkit_web_view_get_context(m_webView.get()))) |
| #endif |
| { |
| g_assert_true(WEBKIT_IS_WEBSITE_DATA_MANAGER(m_manager)); |
| assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_manager)); |
| // WebsiteDataStore creates a new WebProcessPool when used before any secondary process has been created. |
| // Ensure we have a web process by always loading about:blank here. |
| loadURI("about:blank"); |
| waitUntilLoadFinished(); |
| } |
| |
| ~WebsiteDataTest() |
| { |
| g_list_free_full(m_dataList, reinterpret_cast<GDestroyNotify>(webkit_website_data_unref)); |
| } |
| |
| GList* fetch(WebKitWebsiteDataTypes types) |
| { |
| if (m_dataList) { |
| g_list_free_full(m_dataList, reinterpret_cast<GDestroyNotify>(webkit_website_data_unref)); |
| m_dataList = nullptr; |
| } |
| webkit_website_data_manager_fetch(m_manager, types, nullptr, [](GObject*, GAsyncResult* result, gpointer userData) { |
| WebsiteDataTest* test = static_cast<WebsiteDataTest*>(userData); |
| test->m_dataList = webkit_website_data_manager_fetch_finish(test->m_manager, result, nullptr); |
| test->quitMainLoop(); |
| }, this); |
| g_main_loop_run(m_mainLoop); |
| return m_dataList; |
| } |
| |
| void remove(WebKitWebsiteDataTypes types, GList* dataList) |
| { |
| webkit_website_data_manager_remove(m_manager, types, dataList, nullptr, [](GObject*, GAsyncResult* result, gpointer userData) { |
| WebsiteDataTest* test = static_cast<WebsiteDataTest*>(userData); |
| g_assert_true(webkit_website_data_manager_remove_finish(test->m_manager, result, nullptr)); |
| test->quitMainLoop(); |
| }, this); |
| g_main_loop_run(m_mainLoop); |
| } |
| |
| void clear(WebKitWebsiteDataTypes types, GTimeSpan timeSpan) |
| { |
| webkit_website_data_manager_clear(m_manager, types, timeSpan, nullptr, [](GObject*, GAsyncResult* result, gpointer userData) { |
| WebsiteDataTest* test = static_cast<WebsiteDataTest*>(userData); |
| g_assert_true(webkit_website_data_manager_clear_finish(test->m_manager, result, nullptr)); |
| test->quitMainLoop(); |
| }, this); |
| g_main_loop_run(m_mainLoop); |
| } |
| |
| WebKitWebsiteDataManager* m_manager; |
| GList* m_dataList { nullptr }; |
| }; |
| |
| #if !ENABLE(2022_GLIB_API) |
| static void loadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent, WebViewTest* test) |
| { |
| if (loadEvent != WEBKIT_LOAD_FINISHED) |
| return; |
| g_signal_handlers_disconnect_by_func(webView, reinterpret_cast<void*>(loadChanged), test); |
| g_main_loop_quit(test->m_mainLoop); |
| } |
| #endif |
| |
| static void testWebsiteDataConfiguration(WebsiteDataTest* test, gconstpointer) |
| { |
| #if !ENABLE(2022_GLIB_API) |
| ALLOW_DEPRECATED_DECLARATIONS_BEGIN |
| #endif |
| |
| g_assert_cmpstr(webkit_website_data_manager_get_base_data_directory(test->m_manager), ==, Test::dataDirectory()); |
| g_assert_cmpstr(webkit_website_data_manager_get_base_cache_directory(test->m_manager), ==, Test::dataDirectory()); |
| |
| test->loadURI(kServer->getURIForPath("/empty").data()); |
| test->waitUntilLoadFinished(); |
| test->runJavaScriptAndWaitUntilFinished("window.localStorage.myproperty = 42;", nullptr); |
| #if !ENABLE(2022_GLIB_API) |
| GUniquePtr<char> localStorageDirectory(g_build_filename(Test::dataDirectory(), "localstorage", nullptr)); |
| g_assert_cmpstr(localStorageDirectory.get(), ==, webkit_website_data_manager_get_local_storage_directory(test->m_manager)); |
| #endif |
| #if ENABLE(2022_GLIB_API) |
| GUniquePtr<char> localStorageDirectory(g_build_filename(Test::dataDirectory(), "storage", nullptr)); |
| #endif |
| test->assertFileIsCreated(localStorageDirectory.get()); |
| g_assert_true(g_file_test(localStorageDirectory.get(), G_FILE_TEST_IS_DIR)); |
| test->runJavaScriptAndWaitUntilFinished("window.localStorage.clear();", nullptr); |
| |
| test->loadURI(kServer->getURIForPath("/empty").data()); |
| test->waitUntilLoadFinished(); |
| test->runJavaScriptAndWaitUntilFinished("window.indexedDB.open('TestDatabase');", nullptr); |
| #if !ENABLE(2022_GLIB_API) |
| GUniquePtr<char> indexedDBDirectory(g_build_filename(Test::dataDirectory(), "databases", "indexeddb", nullptr)); |
| g_assert_cmpstr(indexedDBDirectory.get(), ==, webkit_website_data_manager_get_indexeddb_directory(test->m_manager)); |
| #endif |
| #if ENABLE(2022_GLIB_API) |
| GUniquePtr<char> indexedDBDirectory(g_build_filename(Test::dataDirectory(), "storage", nullptr)); |
| #endif |
| test->assertFileIsCreated(indexedDBDirectory.get()); |
| g_assert_true(g_file_test(indexedDBDirectory.get(), G_FILE_TEST_IS_DIR)); |
| |
| GUniquePtr<char> diskCacheDirectory(g_build_filename(Test::dataDirectory(), nullptr)); |
| #if !ENABLE(2022_GLIB_API) |
| g_assert_cmpstr(diskCacheDirectory.get(), ==, webkit_website_data_manager_get_disk_cache_directory(test->m_manager)); |
| #endif |
| g_assert_true(g_file_test(diskCacheDirectory.get(), G_FILE_TEST_IS_DIR)); |
| |
| GUniquePtr<char> hstsCacheDirectory(g_build_filename(Test::dataDirectory(), nullptr)); |
| #if !ENABLE(2022_GLIB_API) |
| g_assert_cmpstr(hstsCacheDirectory.get(), ==, webkit_website_data_manager_get_hsts_cache_directory(test->m_manager)); |
| #endif |
| g_assert_true(g_file_test(hstsCacheDirectory.get(), G_FILE_TEST_IS_DIR)); |
| |
| #if !ENABLE(2022_GLIB_API) |
| GUniquePtr<char> itpDirectory(g_build_filename(Test::dataDirectory(), "itp", nullptr)); |
| g_assert_cmpstr(itpDirectory.get(), ==, webkit_website_data_manager_get_itp_directory(test->m_manager)); |
| #endif |
| |
| test->runJavaScriptAndWaitUntilFinished("navigator.serviceWorker.register('/service/empty-worker.js');", nullptr); |
| GUniquePtr<char> swRegistrationsDirectory(g_build_filename(Test::dataDirectory(), "serviceworkers", nullptr)); |
| #if !ENABLE(2022_GLIB_API) |
| g_assert_cmpstr(swRegistrationsDirectory.get(), ==, webkit_website_data_manager_get_service_worker_registrations_directory(test->m_manager)); |
| #endif |
| test->assertFileIsCreated(swRegistrationsDirectory.get()); |
| g_assert_true(g_file_test(swRegistrationsDirectory.get(), G_FILE_TEST_IS_DIR)); |
| |
| test->runJavaScriptAndWaitUntilFinished("let domCacheOpened = false; caches.open('my-cache').then(() => { domCacheOpened = true});", nullptr); |
| GUniquePtr<char> domCacheDirectory(g_build_filename(Test::dataDirectory(), "CacheStorage", nullptr)); |
| #if !ENABLE(2022_GLIB_API) |
| g_assert_cmpstr(domCacheDirectory.get(), ==, webkit_website_data_manager_get_dom_cache_directory(test->m_manager)); |
| #endif |
| test->assertFileIsCreated(domCacheDirectory.get()); |
| g_assert_true(g_file_test(domCacheDirectory.get(), G_FILE_TEST_IS_DIR)); |
| |
| // Make sure the cache was opened before asking to clear it to avoid it being re-created behind our backs. |
| test->assertJavaScriptBecomesTrue("domCacheOpened"); |
| |
| // Clear all persistent caches, since the data dir is common to all test cases. Note: not cleaning the HSTS cache here as its data |
| // is needed for the HSTS tests, where data cleaning will be tested. |
| static const WebKitWebsiteDataTypes persistentCaches = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_DISK_CACHE | WEBKIT_WEBSITE_DATA_LOCAL_STORAGE |
| | WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES | WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE | WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT | WEBKIT_WEBSITE_DATA_ITP |
| | WEBKIT_WEBSITE_DATA_SERVICE_WORKER_REGISTRATIONS | WEBKIT_WEBSITE_DATA_DOM_CACHE); |
| test->clear(persistentCaches, 0); |
| g_assert_null(test->fetch(persistentCaches)); |
| |
| // The default context or session should have a different manager with different configuration. |
| #if ENABLE(2022_GLIB_API) |
| auto* defaultManager = webkit_network_session_get_website_data_manager(webkit_network_session_get_default()); |
| #else |
| auto* defaultManager = webkit_web_context_get_website_data_manager(webkit_web_context_get_default()); |
| #endif |
| g_assert_true(WEBKIT_IS_WEBSITE_DATA_MANAGER(defaultManager)); |
| g_assert_true(test->m_manager != defaultManager); |
| g_assert_cmpstr(webkit_website_data_manager_get_base_data_directory(test->m_manager), !=, webkit_website_data_manager_get_base_data_directory(defaultManager)); |
| g_assert_cmpstr(webkit_website_data_manager_get_base_cache_directory(test->m_manager), !=, webkit_website_data_manager_get_base_cache_directory(defaultManager)); |
| #if ENABLE(2022_GLIB_API) |
| g_assert_nonnull(webkit_website_data_manager_get_base_data_directory(defaultManager)); |
| g_assert_nonnull(webkit_website_data_manager_get_base_cache_directory(defaultManager)); |
| #else |
| g_assert_null(webkit_website_data_manager_get_base_data_directory(defaultManager)); |
| g_assert_null(webkit_website_data_manager_get_base_cache_directory(defaultManager)); |
| g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(test->m_manager), !=, webkit_website_data_manager_get_local_storage_directory(defaultManager)); |
| g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(test->m_manager), !=, webkit_website_data_manager_get_indexeddb_directory(defaultManager)); |
| g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(test->m_manager), !=, webkit_website_data_manager_get_disk_cache_directory(defaultManager)); |
| g_assert_cmpstr(webkit_website_data_manager_get_hsts_cache_directory(test->m_manager), !=, webkit_website_data_manager_get_hsts_cache_directory(defaultManager)); |
| g_assert_cmpstr(webkit_website_data_manager_get_itp_directory(test->m_manager), !=, webkit_website_data_manager_get_itp_directory(defaultManager)); |
| g_assert_cmpstr(webkit_website_data_manager_get_service_worker_registrations_directory(test->m_manager), !=, webkit_website_data_manager_get_service_worker_registrations_directory(defaultManager)); |
| g_assert_cmpstr(webkit_website_data_manager_get_dom_cache_directory(test->m_manager), !=, webkit_website_data_manager_get_dom_cache_directory(defaultManager)); |
| #endif |
| |
| #if !ENABLE(2022_GLIB_API) |
| // Any specific configuration provided takes precedence over base dirs. |
| indexedDBDirectory.reset(g_build_filename(Test::dataDirectory(), "mycustomindexeddb", nullptr)); |
| GRefPtr<WebKitWebsiteDataManager> baseDataManager = adoptGRef(webkit_website_data_manager_new( |
| "base-data-directory", Test::dataDirectory(), "base-cache-directory", Test::dataDirectory(), |
| "indexeddb-directory", indexedDBDirectory.get(), |
| "origin-storage-ratio", 1.0, "total-storage-ratio", 1.0, |
| nullptr)); |
| g_assert_true(WEBKIT_IS_WEBSITE_DATA_MANAGER(baseDataManager.get())); |
| |
| g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(baseDataManager.get()), ==, indexedDBDirectory.get()); |
| // The result should be the same as previous manager. |
| g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(baseDataManager.get()), ==, localStorageDirectory.get()); |
| g_assert_cmpstr(webkit_website_data_manager_get_itp_directory(baseDataManager.get()), ==, itpDirectory.get()); |
| g_assert_cmpstr(webkit_website_data_manager_get_service_worker_registrations_directory(baseDataManager.get()), ==, swRegistrationsDirectory.get()); |
| g_assert_cmpstr(webkit_website_data_manager_get_dom_cache_directory(baseDataManager.get()), ==, domCacheDirectory.get()); |
| g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(baseDataManager.get()), ==, diskCacheDirectory.get()); |
| |
| ALLOW_DEPRECATED_DECLARATIONS_END |
| #endif |
| } |
| |
| static void testWebsiteDataOriginAndTotalStorageRatio(WebsiteDataTest* test, gconstpointer) |
| { |
| #if !ENABLE(2022_GLIB_API) |
| GUniquePtr<char> baseDirectory(g_build_filename(Test::dataDirectory(), "ShouldNotExist", nullptr)); |
| GUniquePtr<char> indexedDBDirectory(g_build_filename(baseDirectory.get(), "databases", "indexeddb", nullptr)); |
| |
| GRefPtr<WebKitWebsiteDataManager> baseDataManager = adoptGRef(webkit_website_data_manager_new( |
| "base-data-directory", baseDirectory.get(), "base-cache-directory", baseDirectory.get(), |
| "origin-storage-ratio", 0.0, "total-storage-ratio", 0.0, |
| nullptr)); |
| g_assert_true(WEBKIT_IS_WEBSITE_DATA_MANAGER(baseDataManager.get())); |
| |
| GRefPtr<WebKitWebContext> webContext = adoptGRef(webkit_web_context_new_with_website_data_manager(baseDataManager.get())); |
| auto webView = test->createWebView("web-context", webContext.get(), nullptr); |
| g_signal_connect(webView.get(), "load-changed", G_CALLBACK(loadChanged), test); |
| |
| webkit_web_view_load_uri(webView.get(), kServer->getURIForPath("/empty").data()); |
| test->waitUntilLoadFinished(webView.get()); |
| test->runJavaScriptAndWaitUntilFinished("window.indexedDB.open('TestDatabase');", nullptr, webView.get()); |
| test->assertFileIsNotCreated(indexedDBDirectory.get()); |
| #endif |
| } |
| |
| static void ephemeralViewloadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent, WebViewTest* test) |
| { |
| if (loadEvent != WEBKIT_LOAD_FINISHED) |
| return; |
| g_signal_handlers_disconnect_by_func(webView, reinterpret_cast<void*>(ephemeralViewloadChanged), test); |
| test->quitMainLoop(); |
| } |
| |
| static void testWebsiteDataEphemeral(WebViewTest* test, gconstpointer) |
| { |
| #if ENABLE(2022_GLIB_API) |
| GRefPtr<WebKitNetworkSession> session = adoptGRef(webkit_network_session_new_ephemeral()); |
| GRefPtr<WebKitWebsiteDataManager> manager = webkit_network_session_get_website_data_manager(session.get()); |
| #else |
| GRefPtr<WebKitWebsiteDataManager> manager = adoptGRef(webkit_website_data_manager_new_ephemeral()); |
| g_assert_true(webkit_website_data_manager_is_ephemeral(manager.get())); |
| #endif |
| g_assert_null(webkit_website_data_manager_get_base_data_directory(manager.get())); |
| g_assert_null(webkit_website_data_manager_get_base_cache_directory(manager.get())); |
| |
| #if !ENABLE(2022_GLIB_API) |
| ALLOW_DEPRECATED_DECLARATIONS_BEGIN |
| g_assert_null(webkit_website_data_manager_get_local_storage_directory(manager.get())); |
| g_assert_null(webkit_website_data_manager_get_disk_cache_directory(manager.get())); |
| g_assert_null(webkit_website_data_manager_get_indexeddb_directory(manager.get())); |
| g_assert_null(webkit_website_data_manager_get_hsts_cache_directory(manager.get())); |
| g_assert_null(webkit_website_data_manager_get_itp_directory(manager.get())); |
| g_assert_null(webkit_website_data_manager_get_service_worker_registrations_directory(manager.get())); |
| ALLOW_DEPRECATED_DECLARATIONS_END |
| |
| // Configuration is ignored when is-ephemeral is used. |
| manager = adoptGRef(WEBKIT_WEBSITE_DATA_MANAGER(g_object_new(WEBKIT_TYPE_WEBSITE_DATA_MANAGER, "base-data-directory", Test::dataDirectory(), "is-ephemeral", TRUE, nullptr))); |
| g_assert_true(webkit_website_data_manager_is_ephemeral(manager.get())); |
| g_assert_null(webkit_website_data_manager_get_base_data_directory(manager.get())); |
| #endif |
| |
| #if ENABLE(2022_GLIB_API) |
| webkit_network_session_set_itp_enabled(session.get(), TRUE); |
| g_assert_true(webkit_network_session_get_itp_enabled(session.get())); |
| #else |
| webkit_website_data_manager_set_itp_enabled(manager.get(), TRUE); |
| g_assert_true(webkit_website_data_manager_get_itp_enabled(manager.get())); |
| #endif |
| |
| // Non persistent data can be queried in an ephemeral manager. |
| #if ENABLE(2022_GLIB_API) |
| auto webView = test->createWebView("network-session", session.get(), nullptr); |
| g_assert_true(webkit_web_view_get_network_session(webView.get()) == session.get()); |
| #else |
| GRefPtr<WebKitWebContext> webContext = adoptGRef(webkit_web_context_new_with_website_data_manager(manager.get())); |
| g_assert_true(webkit_web_context_is_ephemeral(webContext.get())); |
| auto webView = test->createWebView("web-context", webContext.get(), nullptr); |
| g_assert_true(webkit_web_view_is_ephemeral(webView.get())); |
| g_assert_true(webkit_web_view_get_website_data_manager(webView.get()) == manager.get()); |
| #endif |
| |
| g_signal_connect(webView.get(), "load-changed", G_CALLBACK(ephemeralViewloadChanged), test); |
| webkit_web_view_load_uri(webView.get(), kServer->getURIForPath("/empty").data()); |
| g_main_loop_run(test->m_mainLoop); |
| |
| GUniquePtr<char> itpDirectory(g_build_filename(Test::dataDirectory(), "itp", nullptr)); |
| g_assert(!g_file_test(itpDirectory.get(), G_FILE_TEST_IS_DIR)); |
| |
| webkit_website_data_manager_fetch(manager.get(), WEBKIT_WEBSITE_DATA_MEMORY_CACHE, nullptr, [](GObject* manager, GAsyncResult* result, gpointer userData) { |
| auto* test = static_cast<WebViewTest*>(userData); |
| GList* dataList = webkit_website_data_manager_fetch_finish(WEBKIT_WEBSITE_DATA_MANAGER(manager), result, nullptr); |
| g_assert_nonnull(dataList); |
| g_assert_cmpuint(g_list_length(dataList), ==, 1); |
| WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_nonnull(data); |
| WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data()); |
| g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin)); |
| webkit_security_origin_unref(origin); |
| g_list_free_full(dataList, reinterpret_cast<GDestroyNotify>(webkit_website_data_unref)); |
| test->quitMainLoop(); |
| }, test); |
| g_main_loop_run(test->m_mainLoop); |
| |
| #if ENABLE(2022_GLIB_API) |
| webkit_network_session_set_itp_enabled(session.get(), FALSE); |
| #else |
| webkit_website_data_manager_set_itp_enabled(manager.get(), FALSE); |
| #endif |
| } |
| |
| static void testWebsiteDataCache(WebsiteDataTest* test, gconstpointer) |
| { |
| static const WebKitWebsiteDataTypes cacheTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE); |
| |
| test->clear(cacheTypes, 0); |
| |
| GList* dataList = test->fetch(cacheTypes); |
| g_assert_null(dataList); |
| |
| test->loadURI(kServer->getURIForPath("/empty").data()); |
| test->waitUntilLoadFinished(); |
| |
| // Disk cache delays the storing of initial resources for 1 second to avoid |
| // affecting early page load. So, wait here to make sure resources |
| // have already been stored. |
| test->wait(2); |
| |
| dataList = test->fetch(cacheTypes); |
| g_assert_nonnull(dataList); |
| g_assert_cmpuint(g_list_length(dataList), ==, 1); |
| WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_nonnull(data); |
| WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data()); |
| g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin)); |
| webkit_security_origin_unref(origin); |
| g_assert_cmpuint(webkit_website_data_get_types(data), ==, cacheTypes); |
| // Memory cache size is unknown. |
| g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_MEMORY_CACHE), ==, 0); |
| g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_DISK_CACHE), >, 0); |
| |
| // Try again but only getting disk cache. |
| dataList = test->fetch(WEBKIT_WEBSITE_DATA_DISK_CACHE); |
| g_assert_nonnull(dataList); |
| g_assert_cmpuint(g_list_length(dataList), ==, 1); |
| data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_nonnull(data); |
| g_assert_true(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_DISK_CACHE); |
| g_assert_false(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_MEMORY_CACHE); |
| |
| GUniquePtr<char> fileURL(g_strdup_printf("file://%s/simple.html", Test::getResourcesDir(Test::WebKit2Resources).data())); |
| test->loadURI(fileURL.get()); |
| test->waitUntilLoadFinished(); |
| |
| fileURL.reset(g_strdup_printf("file://%s/simple2.html", Test::getResourcesDir(Test::WebKit2Resources).data())); |
| test->loadURI(fileURL.get()); |
| test->waitUntilLoadFinished(); |
| |
| // Local files are grouped. |
| dataList = test->fetch(cacheTypes); |
| g_assert_nonnull(dataList); |
| g_assert_cmpuint(g_list_length(dataList), ==, 2); |
| GList* itemList = g_list_find_custom(dataList, nullptr, [](gconstpointer item, gconstpointer) -> int { |
| WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(const_cast<gpointer>(item)); |
| return g_strcmp0(webkit_website_data_get_name(data), "Local files"); |
| }); |
| g_assert_nonnull(itemList); |
| data = static_cast<WebKitWebsiteData*>(itemList->data); |
| g_assert_nonnull(data); |
| g_assert_true(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_MEMORY_CACHE); |
| // Local files are never stored in disk cache. |
| g_assert_false(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_DISK_CACHE); |
| |
| // Clear data modified since the last microsecond should not clear anything. |
| // Use disk-cache because memory cache ignores the modified since. |
| test->clear(WEBKIT_WEBSITE_DATA_DISK_CACHE, 1); |
| dataList = test->fetch(cacheTypes); |
| g_assert_nonnull(dataList); |
| g_assert_cmpuint(g_list_length(dataList), ==, 2); |
| |
| // Remove memory cache only for local files. |
| itemList = g_list_find_custom(dataList, nullptr, [](gconstpointer item, gconstpointer) -> int { |
| WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(const_cast<gpointer>(item)); |
| return g_strcmp0(webkit_website_data_get_name(data), "Local files"); |
| }); |
| g_assert_nonnull(itemList); |
| GList removeList = { itemList->data, nullptr, nullptr }; |
| test->remove(WEBKIT_WEBSITE_DATA_MEMORY_CACHE, &removeList); |
| dataList = test->fetch(cacheTypes); |
| g_assert_nonnull(dataList); |
| g_assert_cmpuint(g_list_length(dataList), ==, 1); |
| data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_true(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_DISK_CACHE); |
| |
| // Clear all. |
| test->clear(cacheTypes, 0); |
| dataList = test->fetch(cacheTypes); |
| g_assert_null(dataList); |
| } |
| |
| static void testWebsiteDataStorage(WebsiteDataTest* test, gconstpointer) |
| { |
| static const WebKitWebsiteDataTypes storageTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_SESSION_STORAGE | WEBKIT_WEBSITE_DATA_LOCAL_STORAGE); |
| GList* dataList = test->fetch(storageTypes); |
| g_assert_null(dataList); |
| |
| test->loadURI(kServer->getURIForPath("/sessionstorage").data()); |
| test->waitUntilLoadFinished(); |
| |
| test->loadURI(kServer->getURIForPath("/localstorage").data()); |
| test->waitUntilLoadFinished(); |
| |
| // Local storage uses a 1 second timer to update the database. |
| test->wait(1); |
| |
| dataList = test->fetch(storageTypes); |
| g_assert_nonnull(dataList); |
| g_assert_cmpuint(g_list_length(dataList), ==, 1); |
| WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_nonnull(data); |
| WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data()); |
| g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin)); |
| webkit_security_origin_unref(origin); |
| g_assert_cmpuint(webkit_website_data_get_types(data), ==, storageTypes); |
| // Storage sizes are unknown. |
| g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_SESSION_STORAGE), ==, 0); |
| g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_LOCAL_STORAGE), ==, 0); |
| |
| // Get also cached data, and clear it. |
| static const WebKitWebsiteDataTypes cacheAndStorageTypes = static_cast<WebKitWebsiteDataTypes>(storageTypes | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE); |
| dataList = test->fetch(cacheAndStorageTypes); |
| g_assert_nonnull(dataList); |
| g_assert_cmpuint(g_list_length(dataList), ==, 1); |
| data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_nonnull(data); |
| g_assert_cmpuint(webkit_website_data_get_types(data), ==, cacheAndStorageTypes); |
| test->clear(static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE), 0); |
| |
| // Get all types again, but only storage is retrieved now. |
| dataList = test->fetch(cacheAndStorageTypes); |
| g_assert_nonnull(dataList); |
| g_assert_cmpuint(g_list_length(dataList), ==, 1); |
| data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_nonnull(data); |
| g_assert_cmpuint(webkit_website_data_get_types(data), ==, storageTypes); |
| |
| // Remove the session storage. |
| GList removeList = { data, nullptr, nullptr }; |
| test->remove(WEBKIT_WEBSITE_DATA_SESSION_STORAGE, &removeList); |
| dataList = test->fetch(storageTypes); |
| g_assert_nonnull(dataList); |
| g_assert_cmpuint(g_list_length(dataList), ==, 1); |
| data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_false(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_SESSION_STORAGE); |
| g_assert_true(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_LOCAL_STORAGE); |
| |
| // Clear all. |
| test->clear(cacheAndStorageTypes, 0); |
| dataList = test->fetch(cacheAndStorageTypes); |
| g_assert_null(dataList); |
| } |
| |
| static void testWebsiteDataDatabases(WebsiteDataTest* test, gconstpointer) |
| { |
| static const WebKitWebsiteDataTypes databaseTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES); |
| GList* dataList = test->fetch(databaseTypes); |
| g_assert_null(dataList); |
| |
| test->loadURI(kServer->getURIForPath("/empty").data()); |
| test->waitUntilLoadFinished(); |
| test->runJavaScriptAndWaitUntilFinished("window.indexedDB.open('TestDatabase');", nullptr); |
| |
| test->wait(1); |
| |
| dataList = test->fetch(databaseTypes); |
| g_assert_nonnull(dataList); |
| g_assert_cmpuint(g_list_length(dataList), ==, 1); |
| WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_nonnull(data); |
| WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data()); |
| g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin)); |
| webkit_security_origin_unref(origin); |
| g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES); |
| // Database sizes are unknown. |
| g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES), ==, 0); |
| |
| test->runJavaScriptAndWaitUntilFinished("db = openDatabase(\"TestDatabase\", \"1.0\", \"TestDatabase\", 1);", nullptr); |
| dataList = test->fetch(databaseTypes); |
| g_assert_nonnull(dataList); |
| g_assert_cmpuint(g_list_length(dataList), ==, 1); |
| data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_nonnull(data); |
| g_assert_cmpuint(webkit_website_data_get_types(data), ==, databaseTypes); |
| // Database sizes are unknown. |
| g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES), ==, 0); |
| |
| // Remove all databases at once. |
| GList removeList = { data, nullptr, nullptr }; |
| test->remove(databaseTypes, &removeList); |
| dataList = test->fetch(databaseTypes); |
| g_assert_null(dataList); |
| |
| // Clear all. |
| static const WebKitWebsiteDataTypes cacheAndDatabaseTypes = static_cast<WebKitWebsiteDataTypes>(databaseTypes | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE); |
| test->clear(cacheAndDatabaseTypes, 0); |
| dataList = test->fetch(cacheAndDatabaseTypes); |
| g_assert_null(dataList); |
| } |
| |
| static void prepopulateHstsData() |
| { |
| // HSTS headers will be ignored in this test because the spec forbids STS policies from being honored for hosts with |
| // an IP address instead of a domain. In order to be able to test the data manager API with HSTS website data, we |
| // prepopulate the HSTS storage using the libsoup API directly. |
| |
| #if !ENABLE(2022_GLIB_API) |
| GUniquePtr<char> hstsDatabase(g_build_filename(Test::dataDirectory(), "hsts-storage.sqlite", nullptr)); |
| #else |
| GUniquePtr<char> hstsCacheDirectory(g_build_filename(Test::dataDirectory(), "HSTS", nullptr)); |
| GUniquePtr<char> hstsDatabase(g_build_filename(hstsCacheDirectory.get(), "hsts-storage.sqlite", nullptr)); |
| g_mkdir_with_parents(hstsCacheDirectory.get(), 0700); |
| #endif |
| GRefPtr<SoupHSTSEnforcer> enforcer = adoptGRef(soup_hsts_enforcer_db_new(hstsDatabase.get())); |
| GUniquePtr<SoupHSTSPolicy> policy(soup_hsts_policy_new("webkitgtk.org", 3600, true)); |
| soup_hsts_enforcer_set_policy(enforcer.get(), policy.get()); |
| |
| policy.reset(soup_hsts_policy_new("webkit.org", 3600, true)); |
| soup_hsts_enforcer_set_policy(enforcer.get(), policy.get()); |
| } |
| |
| static void testWebsiteDataHsts(WebsiteDataTest* test, gconstpointer) |
| { |
| GList* dataList = test->fetch(WEBKIT_WEBSITE_DATA_HSTS_CACHE); |
| g_assert_cmpuint(g_list_length(dataList), ==, 2); |
| WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_HSTS_CACHE); |
| // HSTS data size is unknown. |
| g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_HSTS_CACHE), ==, 0); |
| |
| GList removeList = { data, nullptr, nullptr }; |
| test->remove(WEBKIT_WEBSITE_DATA_HSTS_CACHE, &removeList); |
| dataList = test->fetch(WEBKIT_WEBSITE_DATA_HSTS_CACHE); |
| g_assert_cmpuint(g_list_length(dataList), ==, 1); |
| data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_HSTS_CACHE); |
| |
| // Remove all HSTS data. |
| test->clear(WEBKIT_WEBSITE_DATA_HSTS_CACHE, 0); |
| g_assert_null(test->fetch(WEBKIT_WEBSITE_DATA_HSTS_CACHE)); |
| } |
| |
| static void testWebsiteDataCookies(WebsiteDataTest* test, gconstpointer) |
| { |
| GList* dataList = test->fetch(WEBKIT_WEBSITE_DATA_COOKIES); |
| g_assert_null(dataList); |
| |
| test->loadURI(kServer->getURIForPath("/empty").data()); |
| test->waitUntilLoadFinished(); |
| |
| dataList = test->fetch(WEBKIT_WEBSITE_DATA_COOKIES); |
| g_assert_nonnull(dataList); |
| g_assert_cmpuint(g_list_length(dataList), ==, 1); |
| WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_nonnull(data); |
| g_assert_cmpstr(webkit_website_data_get_name(data), ==, "127.0.0.1"); |
| g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_COOKIES); |
| // Cookies size is unknown. |
| g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_COOKIES), ==, 0); |
| |
| GList removeList = { data, nullptr, nullptr }; |
| test->remove(WEBKIT_WEBSITE_DATA_COOKIES, &removeList); |
| dataList = test->fetch(WEBKIT_WEBSITE_DATA_COOKIES); |
| g_assert_null(dataList); |
| |
| // Clear all. |
| static const WebKitWebsiteDataTypes cacheAndCookieTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_COOKIES | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE); |
| test->clear(cacheAndCookieTypes, 0); |
| dataList = test->fetch(cacheAndCookieTypes); |
| g_assert_null(dataList); |
| } |
| |
| static void testWebsiteDataDeviceIdHashSalt(WebsiteDataTest* test, gconstpointer) |
| { |
| WebKitSettings* settings = webkit_web_view_get_settings(test->webView()); |
| gboolean enabled = webkit_settings_get_enable_media_stream(settings); |
| webkit_settings_set_enable_media_stream(settings, TRUE); |
| webkit_settings_set_enable_mock_capture_devices(settings, TRUE); |
| |
| test->clear(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT, 0); |
| |
| GList* dataList = test->fetch(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT); |
| g_assert_null(dataList); |
| |
| test->loadURI(kServer->getURIForPath("/enumeratedevices").data()); |
| test->waitUntilTitleChangedTo("Finished"); |
| |
| dataList = test->fetch(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT); |
| g_assert_nonnull(dataList); |
| |
| g_assert_cmpuint(g_list_length(dataList), ==, 1); |
| WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_nonnull(data); |
| WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data()); |
| g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin)); |
| webkit_security_origin_unref(origin); |
| g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT); |
| |
| GList removeList = { data, nullptr, nullptr }; |
| test->remove(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT, &removeList); |
| dataList = test->fetch(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT); |
| g_assert_null(dataList); |
| |
| test->loadURI("about:blank"); |
| test->waitUntilTitleChanged(); |
| |
| // Test removing the cookies. |
| test->loadURI(kServer->getURIForPath("/enumeratedevices").data()); |
| test->waitUntilTitleChangedTo("Finished"); |
| |
| dataList = test->fetch(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT); |
| g_assert_nonnull(dataList); |
| data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_nonnull(data); |
| |
| GList removeCookieList = { data, nullptr, nullptr }; |
| test->remove(WEBKIT_WEBSITE_DATA_COOKIES, &removeCookieList); |
| dataList = test->fetch(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT); |
| g_assert_null(dataList); |
| |
| // Clear all. |
| static const WebKitWebsiteDataTypes cacheAndAppcacheTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT); |
| test->clear(cacheAndAppcacheTypes, 0); |
| dataList = test->fetch(cacheAndAppcacheTypes); |
| g_assert_null(dataList); |
| |
| webkit_settings_set_enable_media_stream(settings, enabled); |
| webkit_settings_set_enable_mock_capture_devices(settings, enabled); |
| } |
| |
| static void testWebsiteDataITP(WebsiteDataTest* test, gconstpointer) |
| { |
| GUniquePtr<char> itpDirectory(g_build_filename(Test::dataDirectory(), "itp", nullptr)); |
| GUniquePtr<char> itpDatabaseFile(g_build_filename(itpDirectory.get(), "observations.db", nullptr)); |
| |
| // Delete any previous data. |
| g_unlink(itpDatabaseFile.get()); |
| g_rmdir(itpDirectory.get()); |
| |
| g_assert_false(g_file_test(itpDirectory.get(), G_FILE_TEST_IS_DIR)); |
| g_assert_false(g_file_test(itpDatabaseFile.get(), G_FILE_TEST_IS_REGULAR)); |
| |
| #if ENABLE(2022_GLIB_API) |
| g_assert_false(webkit_network_session_get_itp_enabled(test->m_networkSession.get())); |
| #else |
| g_assert_false(webkit_website_data_manager_get_itp_enabled(test->m_manager)); |
| #endif |
| test->loadURI(kServer->getURIForPath("/empty").data()); |
| test->waitUntilLoadFinished(); |
| |
| g_assert_false(g_file_test(itpDirectory.get(), G_FILE_TEST_IS_DIR)); |
| g_assert_false(g_file_test(itpDatabaseFile.get(), G_FILE_TEST_IS_REGULAR)); |
| |
| #if ENABLE(2022_GLIB_API) |
| webkit_network_session_set_itp_enabled(test->m_networkSession.get(), TRUE); |
| g_assert_true(webkit_network_session_get_itp_enabled(test->m_networkSession.get())); |
| #else |
| webkit_website_data_manager_set_itp_enabled(test->m_manager, TRUE); |
| g_assert_true(webkit_website_data_manager_get_itp_enabled(test->m_manager)); |
| #endif |
| |
| test->loadURI(kServer->getURIForPath("/empty").data()); |
| test->waitUntilLoadFinished(); |
| test->assertFileIsCreated(itpDatabaseFile.get()); |
| g_assert_true(g_file_test(itpDirectory.get(), G_FILE_TEST_IS_DIR)); |
| g_assert_true(g_file_test(itpDatabaseFile.get(), G_FILE_TEST_IS_REGULAR)); |
| |
| // Give some time for the database to be updated. |
| test->wait(1); |
| |
| GList* dataList = test->fetch(WEBKIT_WEBSITE_DATA_ITP); |
| g_assert_nonnull(dataList); |
| g_assert_cmpuint(g_list_length(dataList), ==, 1); |
| auto* data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_nonnull(data); |
| WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data()); |
| g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin)); |
| webkit_security_origin_unref(origin); |
| |
| // Remove the registration. |
| GList removeList = { data, nullptr, nullptr }; |
| test->remove(WEBKIT_WEBSITE_DATA_ITP, &removeList); |
| dataList = test->fetch(WEBKIT_WEBSITE_DATA_ITP); |
| g_assert_null(dataList); |
| |
| // Clear all. |
| static const WebKitWebsiteDataTypes cacheAndITP = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_ITP | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE); |
| test->clear(cacheAndITP, 0); |
| |
| #if ENABLE(2022_GLIB_API) |
| webkit_network_session_set_itp_enabled(test->m_networkSession.get(), FALSE); |
| g_assert_false(webkit_network_session_get_itp_enabled(test->m_networkSession.get())); |
| #else |
| webkit_website_data_manager_set_itp_enabled(test->m_manager, FALSE); |
| g_assert_false(webkit_website_data_manager_get_itp_enabled(test->m_manager)); |
| #endif |
| |
| g_rmdir(itpDirectory.get()); |
| } |
| |
| static void testWebsiteDataServiceWorkerRegistrations(WebsiteDataTest* test, gconstpointer) |
| { |
| GList* dataList = test->fetch(WEBKIT_WEBSITE_DATA_SERVICE_WORKER_REGISTRATIONS); |
| g_assert_null(dataList); |
| |
| test->loadURI(kServer->getURIForPath("/service/register.html").data()); |
| test->waitUntilLoadFinished(); |
| test->wait(1); |
| |
| dataList = test->fetch(WEBKIT_WEBSITE_DATA_SERVICE_WORKER_REGISTRATIONS); |
| g_assert_cmpuint(g_list_length(dataList), ==, 1); |
| g_assert_nonnull(dataList); |
| auto* data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_nonnull(data); |
| WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/service/register.html").data()); |
| g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin)); |
| webkit_security_origin_unref(origin); |
| |
| // Remove the registration. |
| GList removeList = { data, nullptr, nullptr }; |
| test->remove(WEBKIT_WEBSITE_DATA_SERVICE_WORKER_REGISTRATIONS, &removeList); |
| dataList = test->fetch(WEBKIT_WEBSITE_DATA_SERVICE_WORKER_REGISTRATIONS); |
| g_assert_null(dataList); |
| |
| // Clear all. |
| static const WebKitWebsiteDataTypes cacheAndRegistrations = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_SERVICE_WORKER_REGISTRATIONS | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE); |
| test->clear(cacheAndRegistrations, 0); |
| dataList = test->fetch(cacheAndRegistrations); |
| g_assert_null(dataList); |
| } |
| |
| static void testWebsiteDataDOMCache(WebsiteDataTest* test, gconstpointer) |
| { |
| GList* dataList = test->fetch(WEBKIT_WEBSITE_DATA_DOM_CACHE); |
| g_assert_null(dataList); |
| |
| test->loadURI(kServer->getURIForPath("/").data()); |
| test->waitUntilLoadFinished(); |
| test->runJavaScriptAndWaitUntilFinished("let domCacheOpened = false; window.caches.open('TestDOMCache').then(() => { domCacheOpened = true});", nullptr); |
| |
| // Make sure the cache was opened before asking for it |
| test->assertJavaScriptBecomesTrue("domCacheOpened"); |
| |
| dataList = test->fetch(WEBKIT_WEBSITE_DATA_DOM_CACHE); |
| g_assert_nonnull(dataList); |
| g_assert_cmpuint(g_list_length(dataList), ==, 1); |
| auto* data = static_cast<WebKitWebsiteData*>(dataList->data); |
| g_assert_nonnull(data); |
| WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data()); |
| g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin)); |
| webkit_security_origin_unref(origin); |
| |
| // Remove the cache. |
| GList removeList = { data, nullptr, nullptr }; |
| test->remove(WEBKIT_WEBSITE_DATA_DOM_CACHE, &removeList); |
| dataList = test->fetch(WEBKIT_WEBSITE_DATA_DOM_CACHE); |
| g_assert_null(dataList); |
| |
| // Clear all. |
| static const WebKitWebsiteDataTypes caches = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_DOM_CACHE | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE); |
| test->clear(caches, 0); |
| dataList = test->fetch(caches); |
| g_assert_null(dataList); |
| } |
| |
| static void testWebViewHandleCorruptedLocalStorage(WebsiteDataTest* test, gconstpointer) |
| { |
| const char html[] = "<html><script>let foo = (window.localStorage.length ? window.localStorage.getItem('item'):''); window.localStorage.setItem('item','value');</script></html>"; |
| auto waitForFooChanged = [&test](WebKitWebView* webView) { |
| GUniqueOutPtr<GError> error; |
| JSCValue* value = test->runJavaScriptAndWaitUntilFinished("foo;", &error.outPtr(), webView); |
| g_assert_no_error(error.get()); |
| GUniquePtr<char> fooValue(jsc_value_to_string(value)); |
| return fooValue; |
| }; |
| |
| // Create corrupted database file for local storage of "http://example.com". |
| const GUniquePtr<char> localStorageDirPath(g_build_filename(Test::dataDirectory(), "local-storage", nullptr)); |
| const GUniquePtr<char> localStorageFilePath(g_build_filename(localStorageDirPath.get(), "http_example.com_0.localstorage", nullptr)); |
| g_mkdir_with_parents(localStorageDirPath.get(), 0755); |
| g_file_set_contents(localStorageFilePath.get(), "GARBAGE", -1, nullptr); |
| |
| g_assert_true(g_file_test(localStorageFilePath.get(), G_FILE_TEST_EXISTS)); |
| |
| // Loading a web page to store an item in localStorage. |
| webkit_web_view_load_html(test->webView(), html, "http://example.com"); |
| test->waitUntilLoadFinished(); |
| auto fooValue(waitForFooChanged(test->webView())); |
| g_assert_cmpstr(fooValue.get(), ==, ""); |
| |
| // Creating a second web view and loading a web page with the same url to read the item from localStorage. |
| auto webView = test->createWebView(); |
| #if ENABLE(2022_GLIB_API) |
| g_assert_true(webkit_web_view_get_network_session(webView.get()) == test->m_networkSession.get()); |
| #endif |
| test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webView.get())); |
| webkit_web_view_load_html(webView.get(), html, "http://example.com"); |
| test->waitUntilLoadFinished(webView.get()); |
| fooValue = waitForFooChanged(webView.get()); |
| g_assert_cmpstr(fooValue.get(), ==, "value"); |
| } |
| |
| void beforeAll() |
| { |
| kServer = new WebKitTestServer(); |
| kServer->run(serverCallback); |
| |
| prepopulateHstsData(); |
| |
| WebsiteDataTest::add("WebKitWebsiteData", "configuration", testWebsiteDataConfiguration); |
| WebViewTest::add("WebKitWebsiteData", "ephemeral", testWebsiteDataEphemeral); |
| WebsiteDataTest::add("WebKitWebsiteData", "cache", testWebsiteDataCache); |
| WebsiteDataTest::add("WebKitWebsiteData", "storage", testWebsiteDataStorage); |
| WebsiteDataTest::add("WebKitWebsiteData", "databases", testWebsiteDataDatabases); |
| WebsiteDataTest::add("WebKitWebsiteData", "cookies", testWebsiteDataCookies); |
| WebsiteDataTest::add("WebKitWebsiteData", "hsts", testWebsiteDataHsts); |
| WebsiteDataTest::add("WebKitWebsiteData", "deviceidhashsalt", testWebsiteDataDeviceIdHashSalt); |
| WebsiteDataTest::add("WebKitWebsiteData", "itp", testWebsiteDataITP); |
| WebsiteDataTest::add("WebKitWebsiteData", "service-worker-registrations", testWebsiteDataServiceWorkerRegistrations); |
| WebsiteDataTest::add("WebKitWebsiteData", "dom-cache", testWebsiteDataDOMCache); |
| WebsiteDataTest::add("WebKitWebsiteData", "handle-corrupted-local-storage", testWebViewHandleCorruptedLocalStorage); |
| WebsiteDataTest::add("WebKitWebsiteData", "origin-and-total-storage-ratio", testWebsiteDataOriginAndTotalStorageRatio); |
| } |
| |
| void afterAll() |
| { |
| delete kServer; |
| } |