1 | /* |
2 | * Copyright (C) 2017 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 | |
22 | #include "WebKitTestServer.h" |
23 | #include "WebViewTest.h" |
24 | #include <glib/gstdio.h> |
25 | |
26 | static WebKitTestServer* kServer; |
27 | |
28 | static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) |
29 | { |
30 | if (message->method != SOUP_METHOD_GET) { |
31 | soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); |
32 | return; |
33 | } |
34 | |
35 | if (g_str_equal(path, "/empty" )) { |
36 | static const char* emptyHTML = "<html><body></body></html>" ; |
37 | soup_message_headers_replace(message->response_headers, "Set-Cookie" , "foo=bar; Max-Age=60" ); |
38 | soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, emptyHTML, strlen(emptyHTML)); |
39 | soup_message_body_complete(message->response_body); |
40 | soup_message_set_status(message, SOUP_STATUS_OK); |
41 | } else if (g_str_equal(path, "/appcache" )) { |
42 | static const char* appcacheHTML = "<html manifest=appcache.manifest><body></body></html>" ; |
43 | soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, appcacheHTML, strlen(appcacheHTML)); |
44 | soup_message_body_complete(message->response_body); |
45 | soup_message_set_status(message, SOUP_STATUS_OK); |
46 | } else if (g_str_equal(path, "/appcache.manifest" )) { |
47 | static const char* appcacheManifest = "CACHE MANIFEST\nCACHE:\nappcache/foo.txt\n" ; |
48 | soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, appcacheManifest, strlen(appcacheManifest)); |
49 | soup_message_body_complete(message->response_body); |
50 | soup_message_set_status(message, SOUP_STATUS_OK); |
51 | } else if (g_str_equal(path, "/appcache/foo.txt" )) { |
52 | soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, "foo" , 3); |
53 | soup_message_body_complete(message->response_body); |
54 | soup_message_set_status(message, SOUP_STATUS_OK); |
55 | } else if (g_str_equal(path, "/sessionstorage" )) { |
56 | static const char* sessionStorageHTML = "<html><body onload=\"sessionStorage.foo = 'bar';\"></body></html>" ; |
57 | soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, sessionStorageHTML, strlen(sessionStorageHTML)); |
58 | soup_message_body_complete(message->response_body); |
59 | soup_message_set_status(message, SOUP_STATUS_OK); |
60 | } else if (g_str_equal(path, "/localstorage" )) { |
61 | static const char* localStorageHTML = "<html><body onload=\"localStorage.foo = 'bar';\"></body></html>" ; |
62 | soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, localStorageHTML, strlen(localStorageHTML)); |
63 | soup_message_body_complete(message->response_body); |
64 | soup_message_set_status(message, SOUP_STATUS_OK); |
65 | } else if (g_str_equal(path, "/enumeratedevices" )) { |
66 | static const char* enumerateDevicesHTML = "<html><body onload=\"navigator.mediaDevices.enumerateDevices().then(function(devices) { document.title = 'Finished'; })\"></body></html>" ; |
67 | soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, enumerateDevicesHTML, strlen(enumerateDevicesHTML)); |
68 | soup_message_body_complete(message->response_body); |
69 | soup_message_set_status(message, SOUP_STATUS_OK); |
70 | } else |
71 | soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); |
72 | } |
73 | |
74 | class WebsiteDataTest : public WebViewTest { |
75 | public: |
76 | MAKE_GLIB_TEST_FIXTURE(WebsiteDataTest); |
77 | |
78 | |
79 | WebsiteDataTest() |
80 | : m_manager(webkit_web_context_get_website_data_manager(webkit_web_view_get_context(m_webView))) |
81 | { |
82 | g_assert_true(WEBKIT_IS_WEBSITE_DATA_MANAGER(m_manager)); |
83 | assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_manager)); |
84 | // WebsiteDataStore creates a new WebProcessPool when used before any secondary process has been created. |
85 | // Ensure we have a web process by always loading about:blank here. |
86 | loadURI("about:blank" ); |
87 | waitUntilLoadFinished(); |
88 | } |
89 | |
90 | ~WebsiteDataTest() |
91 | { |
92 | g_list_free_full(m_dataList, reinterpret_cast<GDestroyNotify>(webkit_website_data_unref)); |
93 | } |
94 | |
95 | GList* fetch(WebKitWebsiteDataTypes types) |
96 | { |
97 | if (m_dataList) { |
98 | g_list_free_full(m_dataList, reinterpret_cast<GDestroyNotify>(webkit_website_data_unref)); |
99 | m_dataList = nullptr; |
100 | } |
101 | webkit_website_data_manager_fetch(m_manager, types, nullptr, [](GObject*, GAsyncResult* result, gpointer userData) { |
102 | WebsiteDataTest* test = static_cast<WebsiteDataTest*>(userData); |
103 | test->m_dataList = webkit_website_data_manager_fetch_finish(test->m_manager, result, nullptr); |
104 | test->quitMainLoop(); |
105 | }, this); |
106 | g_main_loop_run(m_mainLoop); |
107 | return m_dataList; |
108 | } |
109 | |
110 | void remove(WebKitWebsiteDataTypes types, GList* dataList) |
111 | { |
112 | webkit_website_data_manager_remove(m_manager, types, dataList, nullptr, [](GObject*, GAsyncResult* result, gpointer userData) { |
113 | WebsiteDataTest* test = static_cast<WebsiteDataTest*>(userData); |
114 | g_assert_true(webkit_website_data_manager_remove_finish(test->m_manager, result, nullptr)); |
115 | test->quitMainLoop(); |
116 | }, this); |
117 | g_main_loop_run(m_mainLoop); |
118 | } |
119 | |
120 | void clear(WebKitWebsiteDataTypes types, GTimeSpan timeSpan) |
121 | { |
122 | webkit_website_data_manager_clear(m_manager, types, timeSpan, nullptr, [](GObject*, GAsyncResult* result, gpointer userData) { |
123 | WebsiteDataTest* test = static_cast<WebsiteDataTest*>(userData); |
124 | g_assert_true(webkit_website_data_manager_clear_finish(test->m_manager, result, nullptr)); |
125 | test->quitMainLoop(); |
126 | }, this); |
127 | g_main_loop_run(m_mainLoop); |
128 | } |
129 | |
130 | WebKitWebsiteDataManager* m_manager; |
131 | GList* m_dataList { nullptr }; |
132 | }; |
133 | |
134 | static void testWebsiteDataConfiguration(WebsiteDataTest* test, gconstpointer) |
135 | { |
136 | // Base directories are not used by TestMain. |
137 | g_assert_null(webkit_website_data_manager_get_base_data_directory(test->m_manager)); |
138 | g_assert_null(webkit_website_data_manager_get_base_cache_directory(test->m_manager)); |
139 | |
140 | GUniquePtr<char> localStorageDirectory(g_build_filename(Test::dataDirectory(), "local-storage" , nullptr)); |
141 | g_assert_cmpstr(localStorageDirectory.get(), ==, webkit_website_data_manager_get_local_storage_directory(test->m_manager)); |
142 | g_assert_true(g_file_test(localStorageDirectory.get(), G_FILE_TEST_IS_DIR)); |
143 | |
144 | test->loadURI(kServer->getURIForPath("/empty" ).data()); |
145 | test->waitUntilLoadFinished(); |
146 | test->runJavaScriptAndWaitUntilFinished("window.indexedDB.open('TestDatabase');" , nullptr); |
147 | GUniquePtr<char> indexedDBDirectory(g_build_filename(Test::dataDirectory(), "indexeddb" , nullptr)); |
148 | g_assert_cmpstr(indexedDBDirectory.get(), ==, webkit_website_data_manager_get_indexeddb_directory(test->m_manager)); |
149 | g_assert_true(g_file_test(indexedDBDirectory.get(), G_FILE_TEST_IS_DIR)); |
150 | |
151 | GUniquePtr<char> webSQLDirectory(g_build_filename(Test::dataDirectory(), "websql" , nullptr)); |
152 | g_assert_cmpstr(webSQLDirectory.get(), ==, webkit_website_data_manager_get_websql_directory(test->m_manager)); |
153 | test->runJavaScriptAndWaitUntilFinished("db = openDatabase(\"TestDatabase\", \"1.0\", \"TestDatabase\", 1);" , nullptr); |
154 | g_assert_true(g_file_test(webSQLDirectory.get(), G_FILE_TEST_IS_DIR)); |
155 | |
156 | test->loadURI(kServer->getURIForPath("/appcache" ).data()); |
157 | test->waitUntilLoadFinished(); |
158 | GUniquePtr<char> applicationCacheDirectory(g_build_filename(Test::dataDirectory(), "appcache" , nullptr)); |
159 | g_assert_cmpstr(applicationCacheDirectory.get(), ==, webkit_website_data_manager_get_offline_application_cache_directory(test->m_manager)); |
160 | GUniquePtr<char> applicationCacheDatabase(g_build_filename(applicationCacheDirectory.get(), "ApplicationCache.db" , nullptr)); |
161 | unsigned triesCount = 4; |
162 | while (!g_file_test(applicationCacheDatabase.get(), G_FILE_TEST_IS_REGULAR) && --triesCount) |
163 | test->wait(0.25); |
164 | g_assert_cmpuint(triesCount, >, 0); |
165 | |
166 | GUniquePtr<char> diskCacheDirectory(g_build_filename(Test::dataDirectory(), "disk-cache" , nullptr)); |
167 | g_assert_cmpstr(diskCacheDirectory.get(), ==, webkit_website_data_manager_get_disk_cache_directory(test->m_manager)); |
168 | g_assert_true(g_file_test(diskCacheDirectory.get(), G_FILE_TEST_IS_DIR)); |
169 | |
170 | // Clear all persistent caches, since the data dir is common to all test cases. |
171 | static const WebKitWebsiteDataTypes persistentCaches = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_DISK_CACHE | WEBKIT_WEBSITE_DATA_LOCAL_STORAGE |
172 | | WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES | WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES | WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE | WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT); |
173 | test->clear(persistentCaches, 0); |
174 | g_assert_null(test->fetch(persistentCaches)); |
175 | |
176 | // The default context should have a different manager with different configuration. |
177 | WebKitWebsiteDataManager* defaultManager = webkit_web_context_get_website_data_manager(webkit_web_context_get_default()); |
178 | g_assert_true(WEBKIT_IS_WEBSITE_DATA_MANAGER(defaultManager)); |
179 | g_assert_true(test->m_manager != defaultManager); |
180 | g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(test->m_manager), !=, webkit_website_data_manager_get_local_storage_directory(defaultManager)); |
181 | g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(test->m_manager), !=, webkit_website_data_manager_get_indexeddb_directory(defaultManager)); |
182 | g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(test->m_manager), !=, webkit_website_data_manager_get_disk_cache_directory(defaultManager)); |
183 | g_assert_cmpstr(webkit_website_data_manager_get_offline_application_cache_directory(test->m_manager), !=, webkit_website_data_manager_get_offline_application_cache_directory(defaultManager)); |
184 | g_assert_cmpstr(webkit_website_data_manager_get_websql_directory(test->m_manager), !=, webkit_website_data_manager_get_websql_directory(defaultManager)); |
185 | |
186 | // Using Test::dataDirectory() we get the default configuration but for a differrent prefix. |
187 | GRefPtr<WebKitWebsiteDataManager> baseDataManager = adoptGRef(webkit_website_data_manager_new("base-data-directory" , Test::dataDirectory(), "base-cache-directory" , Test::dataDirectory(), nullptr)); |
188 | g_assert_true(WEBKIT_IS_WEBSITE_DATA_MANAGER(baseDataManager.get())); |
189 | |
190 | localStorageDirectory.reset(g_build_filename(Test::dataDirectory(), "localstorage" , nullptr)); |
191 | g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(baseDataManager.get()), ==, localStorageDirectory.get()); |
192 | |
193 | indexedDBDirectory.reset(g_build_filename(Test::dataDirectory(), "databases" , "indexeddb" , nullptr)); |
194 | g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(baseDataManager.get()), ==, indexedDBDirectory.get()); |
195 | |
196 | applicationCacheDirectory.reset(g_build_filename(Test::dataDirectory(), "applications" , nullptr)); |
197 | g_assert_cmpstr(webkit_website_data_manager_get_offline_application_cache_directory(baseDataManager.get()), ==, applicationCacheDirectory.get()); |
198 | |
199 | webSQLDirectory.reset(g_build_filename(Test::dataDirectory(), "databases" , nullptr)); |
200 | g_assert_cmpstr(webkit_website_data_manager_get_websql_directory(baseDataManager.get()), ==, webSQLDirectory.get()); |
201 | |
202 | g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(baseDataManager.get()), ==, Test::dataDirectory()); |
203 | |
204 | // Any specific configuration provided takes precedence over base dirs. |
205 | indexedDBDirectory.reset(g_build_filename(Test::dataDirectory(), "mycustomindexeddb" , nullptr)); |
206 | applicationCacheDirectory.reset(g_build_filename(Test::dataDirectory(), "mycustomappcache" , nullptr)); |
207 | baseDataManager = adoptGRef(webkit_website_data_manager_new("base-data-directory" , Test::dataDirectory(), "base-cache-directory" , Test::dataDirectory(), |
208 | "indexeddb-directory" , indexedDBDirectory.get(), "offline-application-cache-directory" , applicationCacheDirectory.get(), nullptr)); |
209 | g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(baseDataManager.get()), ==, indexedDBDirectory.get()); |
210 | g_assert_cmpstr(webkit_website_data_manager_get_offline_application_cache_directory(baseDataManager.get()), ==, applicationCacheDirectory.get()); |
211 | // The result should be the same as previous manager. |
212 | g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(baseDataManager.get()), ==, localStorageDirectory.get()); |
213 | g_assert_cmpstr(webkit_website_data_manager_get_websql_directory(baseDataManager.get()), ==, webSQLDirectory.get()); |
214 | g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(baseDataManager.get()), ==, Test::dataDirectory()); |
215 | } |
216 | |
217 | static void ephemeralViewloadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent, WebViewTest* test) |
218 | { |
219 | if (loadEvent != WEBKIT_LOAD_FINISHED) |
220 | return; |
221 | g_signal_handlers_disconnect_by_func(webView, reinterpret_cast<void*>(ephemeralViewloadChanged), test); |
222 | test->quitMainLoop(); |
223 | } |
224 | |
225 | static void testWebsiteDataEphemeral(WebViewTest* test, gconstpointer) |
226 | { |
227 | GRefPtr<WebKitWebsiteDataManager> manager = adoptGRef(webkit_website_data_manager_new_ephemeral()); |
228 | g_assert_true(webkit_website_data_manager_is_ephemeral(manager.get())); |
229 | g_assert_null(webkit_website_data_manager_get_base_data_directory(manager.get())); |
230 | g_assert_null(webkit_website_data_manager_get_base_cache_directory(manager.get())); |
231 | g_assert_null(webkit_website_data_manager_get_local_storage_directory(manager.get())); |
232 | g_assert_null(webkit_website_data_manager_get_disk_cache_directory(manager.get())); |
233 | g_assert_null(webkit_website_data_manager_get_offline_application_cache_directory(manager.get())); |
234 | g_assert_null(webkit_website_data_manager_get_indexeddb_directory(manager.get())); |
235 | g_assert_null(webkit_website_data_manager_get_websql_directory(manager.get())); |
236 | |
237 | // Configuration is ignored when is-ephemeral is used. |
238 | manager = adoptGRef(WEBKIT_WEBSITE_DATA_MANAGER(g_object_new(WEBKIT_TYPE_WEBSITE_DATA_MANAGER, "base-data-directory" , Test::dataDirectory(), "is-ephemeral" , TRUE, nullptr))); |
239 | g_assert_true(webkit_website_data_manager_is_ephemeral(manager.get())); |
240 | g_assert_null(webkit_website_data_manager_get_base_data_directory(manager.get())); |
241 | |
242 | // Non persistent data can be queried in an ephemeral manager. |
243 | GRefPtr<WebKitWebContext> webContext = adoptGRef(webkit_web_context_new_with_website_data_manager(manager.get())); |
244 | g_assert_true(webkit_web_context_is_ephemeral(webContext.get())); |
245 | auto webView = Test::adoptView(Test::createWebView(webContext.get())); |
246 | g_assert_true(webkit_web_view_is_ephemeral(webView.get())); |
247 | g_assert_true(webkit_web_view_get_website_data_manager(webView.get()) == manager.get()); |
248 | |
249 | g_signal_connect(webView.get(), "load-changed" , G_CALLBACK(ephemeralViewloadChanged), test); |
250 | webkit_web_view_load_uri(webView.get(), kServer->getURIForPath("/empty" ).data()); |
251 | g_main_loop_run(test->m_mainLoop); |
252 | |
253 | webkit_website_data_manager_fetch(manager.get(), WEBKIT_WEBSITE_DATA_MEMORY_CACHE, nullptr, [](GObject* manager, GAsyncResult* result, gpointer userData) { |
254 | auto* test = static_cast<WebViewTest*>(userData); |
255 | GList* dataList = webkit_website_data_manager_fetch_finish(WEBKIT_WEBSITE_DATA_MANAGER(manager), result, nullptr); |
256 | g_assert_nonnull(dataList); |
257 | g_assert_cmpuint(g_list_length(dataList), ==, 1); |
258 | WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data); |
259 | g_assert_nonnull(data); |
260 | WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/" ).data()); |
261 | g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin)); |
262 | webkit_security_origin_unref(origin); |
263 | g_list_free_full(dataList, reinterpret_cast<GDestroyNotify>(webkit_website_data_unref)); |
264 | test->quitMainLoop(); |
265 | }, test); |
266 | g_main_loop_run(test->m_mainLoop); |
267 | } |
268 | |
269 | static void testWebsiteDataCache(WebsiteDataTest* test, gconstpointer) |
270 | { |
271 | static const WebKitWebsiteDataTypes cacheTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE); |
272 | GList* dataList = test->fetch(cacheTypes); |
273 | g_assert_null(dataList); |
274 | |
275 | test->loadURI(kServer->getURIForPath("/empty" ).data()); |
276 | test->waitUntilLoadFinished(); |
277 | |
278 | // Disk cache delays the storing of initial resources for 1 second to avoid |
279 | // affecting early page load. So, wait 1 second here to make sure resources |
280 | // have already been stored. |
281 | test->wait(1); |
282 | |
283 | dataList = test->fetch(cacheTypes); |
284 | g_assert_nonnull(dataList); |
285 | g_assert_cmpuint(g_list_length(dataList), ==, 1); |
286 | WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data); |
287 | g_assert_nonnull(data); |
288 | WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/" ).data()); |
289 | g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin)); |
290 | webkit_security_origin_unref(origin); |
291 | g_assert_cmpuint(webkit_website_data_get_types(data), ==, cacheTypes); |
292 | // Memory cache size is unknown. |
293 | g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_MEMORY_CACHE), ==, 0); |
294 | g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_DISK_CACHE), >, 0); |
295 | |
296 | // Try again but only getting disk cache. |
297 | dataList = test->fetch(WEBKIT_WEBSITE_DATA_DISK_CACHE); |
298 | g_assert_nonnull(dataList); |
299 | g_assert_cmpuint(g_list_length(dataList), ==, 1); |
300 | data = static_cast<WebKitWebsiteData*>(dataList->data); |
301 | g_assert_nonnull(data); |
302 | g_assert_true(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_DISK_CACHE); |
303 | g_assert_false(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_MEMORY_CACHE); |
304 | |
305 | GUniquePtr<char> fileURL(g_strdup_printf("file://%s/simple.html" , Test::getResourcesDir(Test::WebKit2Resources).data())); |
306 | test->loadURI(fileURL.get()); |
307 | test->waitUntilLoadFinished(); |
308 | |
309 | fileURL.reset(g_strdup_printf("file://%s/simple2.html" , Test::getResourcesDir(Test::WebKit2Resources).data())); |
310 | test->loadURI(fileURL.get()); |
311 | test->waitUntilLoadFinished(); |
312 | |
313 | // Local files are grouped. |
314 | dataList = test->fetch(cacheTypes); |
315 | g_assert_nonnull(dataList); |
316 | g_assert_cmpuint(g_list_length(dataList), ==, 2); |
317 | GList* itemList = g_list_find_custom(dataList, nullptr, [](gconstpointer item, gconstpointer) -> int { |
318 | WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(const_cast<gpointer>(item)); |
319 | return g_strcmp0(webkit_website_data_get_name(data), "Local files" ); |
320 | }); |
321 | g_assert_nonnull(itemList); |
322 | data = static_cast<WebKitWebsiteData*>(itemList->data); |
323 | g_assert_nonnull(data); |
324 | g_assert_true(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_MEMORY_CACHE); |
325 | // Local files are never stored in disk cache. |
326 | g_assert_false(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_DISK_CACHE); |
327 | |
328 | // Clear data modified since the last microsecond should not clear anything. |
329 | // Use disk-cache because memory cache ignores the modified since. |
330 | test->clear(WEBKIT_WEBSITE_DATA_DISK_CACHE, 1); |
331 | dataList = test->fetch(cacheTypes); |
332 | g_assert_nonnull(dataList); |
333 | g_assert_cmpuint(g_list_length(dataList), ==, 2); |
334 | |
335 | // Remove memory cache only for local files. |
336 | itemList = g_list_find_custom(dataList, nullptr, [](gconstpointer item, gconstpointer) -> int { |
337 | WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(const_cast<gpointer>(item)); |
338 | return g_strcmp0(webkit_website_data_get_name(data), "Local files" ); |
339 | }); |
340 | g_assert_nonnull(itemList); |
341 | GList removeList = { itemList->data, nullptr, nullptr }; |
342 | test->remove(WEBKIT_WEBSITE_DATA_MEMORY_CACHE, &removeList); |
343 | dataList = test->fetch(cacheTypes); |
344 | g_assert_nonnull(dataList); |
345 | g_assert_cmpuint(g_list_length(dataList), ==, 1); |
346 | data = static_cast<WebKitWebsiteData*>(dataList->data); |
347 | g_assert_true(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_DISK_CACHE); |
348 | |
349 | // Clear all. |
350 | test->clear(cacheTypes, 0); |
351 | dataList = test->fetch(cacheTypes); |
352 | g_assert_null(dataList); |
353 | } |
354 | |
355 | static void testWebsiteDataStorage(WebsiteDataTest* test, gconstpointer) |
356 | { |
357 | static const WebKitWebsiteDataTypes storageTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_SESSION_STORAGE | WEBKIT_WEBSITE_DATA_LOCAL_STORAGE); |
358 | GList* dataList = test->fetch(storageTypes); |
359 | g_assert_null(dataList); |
360 | |
361 | test->loadURI(kServer->getURIForPath("/sessionstorage" ).data()); |
362 | test->waitUntilLoadFinished(); |
363 | |
364 | test->loadURI(kServer->getURIForPath("/localstorage" ).data()); |
365 | test->waitUntilLoadFinished(); |
366 | |
367 | // Local storage uses a 1 second timer to update the database. |
368 | test->wait(1); |
369 | |
370 | dataList = test->fetch(storageTypes); |
371 | g_assert_nonnull(dataList); |
372 | g_assert_cmpuint(g_list_length(dataList), ==, 1); |
373 | WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data); |
374 | g_assert_nonnull(data); |
375 | WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/" ).data()); |
376 | g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin)); |
377 | webkit_security_origin_unref(origin); |
378 | g_assert_cmpuint(webkit_website_data_get_types(data), ==, storageTypes); |
379 | // Storage sizes are unknown. |
380 | g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_SESSION_STORAGE), ==, 0); |
381 | g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_LOCAL_STORAGE), ==, 0); |
382 | |
383 | // Get also cached data, and clear it. |
384 | static const WebKitWebsiteDataTypes cacheAndStorageTypes = static_cast<WebKitWebsiteDataTypes>(storageTypes | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE); |
385 | dataList = test->fetch(cacheAndStorageTypes); |
386 | g_assert_nonnull(dataList); |
387 | g_assert_cmpuint(g_list_length(dataList), ==, 1); |
388 | data = static_cast<WebKitWebsiteData*>(dataList->data); |
389 | g_assert_nonnull(data); |
390 | g_assert_cmpuint(webkit_website_data_get_types(data), ==, cacheAndStorageTypes); |
391 | test->clear(static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE), 0); |
392 | |
393 | // Get all types again, but only storage is retrieved now. |
394 | dataList = test->fetch(cacheAndStorageTypes); |
395 | g_assert_nonnull(dataList); |
396 | g_assert_cmpuint(g_list_length(dataList), ==, 1); |
397 | data = static_cast<WebKitWebsiteData*>(dataList->data); |
398 | g_assert_nonnull(data); |
399 | g_assert_cmpuint(webkit_website_data_get_types(data), ==, storageTypes); |
400 | |
401 | // Remove the session storage. |
402 | GList removeList = { data, nullptr, nullptr }; |
403 | test->remove(WEBKIT_WEBSITE_DATA_SESSION_STORAGE, &removeList); |
404 | dataList = test->fetch(storageTypes); |
405 | g_assert_nonnull(dataList); |
406 | g_assert_cmpuint(g_list_length(dataList), ==, 1); |
407 | data = static_cast<WebKitWebsiteData*>(dataList->data); |
408 | g_assert_false(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_SESSION_STORAGE); |
409 | g_assert_true(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_LOCAL_STORAGE); |
410 | |
411 | // Clear all. |
412 | test->clear(cacheAndStorageTypes, 0); |
413 | dataList = test->fetch(cacheAndStorageTypes); |
414 | g_assert_null(dataList); |
415 | } |
416 | |
417 | static void testWebsiteDataDatabases(WebsiteDataTest* test, gconstpointer) |
418 | { |
419 | static const WebKitWebsiteDataTypes databaseTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES | WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES); |
420 | GList* dataList = test->fetch(databaseTypes); |
421 | g_assert_null(dataList); |
422 | |
423 | test->loadURI(kServer->getURIForPath("/empty" ).data()); |
424 | test->waitUntilLoadFinished(); |
425 | test->runJavaScriptAndWaitUntilFinished("window.indexedDB.open('TestDatabase');" , nullptr); |
426 | |
427 | dataList = test->fetch(databaseTypes); |
428 | g_assert_nonnull(dataList); |
429 | g_assert_cmpuint(g_list_length(dataList), ==, 1); |
430 | WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data); |
431 | g_assert_nonnull(data); |
432 | WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/" ).data()); |
433 | g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin)); |
434 | webkit_security_origin_unref(origin); |
435 | g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES); |
436 | // Database sizes are unknown. |
437 | g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES), ==, 0); |
438 | |
439 | test->runJavaScriptAndWaitUntilFinished("db = openDatabase(\"TestDatabase\", \"1.0\", \"TestDatabase\", 1);" , nullptr); |
440 | dataList = test->fetch(databaseTypes); |
441 | g_assert_nonnull(dataList); |
442 | g_assert_cmpuint(g_list_length(dataList), ==, 1); |
443 | data = static_cast<WebKitWebsiteData*>(dataList->data); |
444 | g_assert_nonnull(data); |
445 | g_assert_cmpuint(webkit_website_data_get_types(data), ==, databaseTypes); |
446 | // Database sizes are unknown. |
447 | g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES), ==, 0); |
448 | g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES), ==, 0); |
449 | |
450 | // Remove all databases at once. |
451 | GList removeList = { data, nullptr, nullptr }; |
452 | test->remove(databaseTypes, &removeList); |
453 | dataList = test->fetch(databaseTypes); |
454 | g_assert_null(dataList); |
455 | |
456 | // Clear all. |
457 | static const WebKitWebsiteDataTypes cacheAndDatabaseTypes = static_cast<WebKitWebsiteDataTypes>(databaseTypes | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE); |
458 | test->clear(cacheAndDatabaseTypes, 0); |
459 | dataList = test->fetch(cacheAndDatabaseTypes); |
460 | g_assert_null(dataList); |
461 | } |
462 | |
463 | static void testWebsiteDataAppcache(WebsiteDataTest* test, gconstpointer) |
464 | { |
465 | GList* dataList = test->fetch(WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE); |
466 | g_assert_null(dataList); |
467 | |
468 | test->loadURI(kServer->getURIForPath("/appcache" ).data()); |
469 | test->waitUntilLoadFinished(); |
470 | |
471 | test->wait(1); |
472 | dataList = test->fetch(WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE); |
473 | g_assert_nonnull(dataList); |
474 | g_assert_cmpuint(g_list_length(dataList), ==, 1); |
475 | WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data); |
476 | g_assert_nonnull(data); |
477 | WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/" ).data()); |
478 | g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin)); |
479 | webkit_security_origin_unref(origin); |
480 | g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE); |
481 | // Appcache size is unknown. |
482 | g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE), ==, 0); |
483 | |
484 | GList removeList = { data, nullptr, nullptr }; |
485 | test->remove(WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE, &removeList); |
486 | dataList = test->fetch(WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE); |
487 | g_assert_null(dataList); |
488 | |
489 | // Clear all. |
490 | static const WebKitWebsiteDataTypes cacheAndAppcacheTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE); |
491 | test->clear(cacheAndAppcacheTypes, 0); |
492 | dataList = test->fetch(cacheAndAppcacheTypes); |
493 | g_assert_null(dataList); |
494 | } |
495 | |
496 | static void testWebsiteDataCookies(WebsiteDataTest* test, gconstpointer) |
497 | { |
498 | GList* dataList = test->fetch(WEBKIT_WEBSITE_DATA_COOKIES); |
499 | g_assert_null(dataList); |
500 | |
501 | test->loadURI(kServer->getURIForPath("/empty" ).data()); |
502 | test->waitUntilLoadFinished(); |
503 | |
504 | dataList = test->fetch(WEBKIT_WEBSITE_DATA_COOKIES); |
505 | g_assert_nonnull(dataList); |
506 | g_assert_cmpuint(g_list_length(dataList), ==, 1); |
507 | WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data); |
508 | g_assert_nonnull(data); |
509 | g_assert_cmpstr(webkit_website_data_get_name(data), ==, "127.0.0.1" ); |
510 | g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_COOKIES); |
511 | // Cookies size is unknown. |
512 | g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_COOKIES), ==, 0); |
513 | |
514 | GList removeList = { data, nullptr, nullptr }; |
515 | test->remove(WEBKIT_WEBSITE_DATA_COOKIES, &removeList); |
516 | dataList = test->fetch(WEBKIT_WEBSITE_DATA_COOKIES); |
517 | g_assert_null(dataList); |
518 | |
519 | // Clear all. |
520 | static const WebKitWebsiteDataTypes cacheAndCookieTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_COOKIES | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE); |
521 | test->clear(cacheAndCookieTypes, 0); |
522 | dataList = test->fetch(cacheAndCookieTypes); |
523 | g_assert_null(dataList); |
524 | } |
525 | |
526 | static void testWebsiteDataDeviceIdHashSalt(WebsiteDataTest* test, gconstpointer) |
527 | { |
528 | WebKitSettings* settings = webkit_web_view_get_settings(test->m_webView); |
529 | gboolean enabled = webkit_settings_get_enable_media_stream(settings); |
530 | webkit_settings_set_enable_media_stream(settings, TRUE); |
531 | |
532 | test->clear(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT, 0); |
533 | |
534 | GList* dataList = test->fetch(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT); |
535 | g_assert_null(dataList); |
536 | |
537 | test->loadURI(kServer->getURIForPath("/enumeratedevices" ).data()); |
538 | test->waitUntilTitleChangedTo("Finished" ); |
539 | |
540 | dataList = test->fetch(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT); |
541 | g_assert_nonnull(dataList); |
542 | |
543 | g_assert_cmpuint(g_list_length(dataList), ==, 1); |
544 | WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data); |
545 | g_assert_nonnull(data); |
546 | WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/" ).data()); |
547 | g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin)); |
548 | webkit_security_origin_unref(origin); |
549 | g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT); |
550 | |
551 | GList removeList = { data, nullptr, nullptr }; |
552 | test->remove(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT, &removeList); |
553 | dataList = test->fetch(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT); |
554 | g_assert_null(dataList); |
555 | |
556 | // Test removing the cookies. |
557 | test->loadURI(kServer->getURIForPath("/enumeratedevices" ).data()); |
558 | test->waitUntilTitleChangedTo("Finished" ); |
559 | |
560 | dataList = test->fetch(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT); |
561 | g_assert_nonnull(dataList); |
562 | data = static_cast<WebKitWebsiteData*>(dataList->data); |
563 | g_assert_nonnull(data); |
564 | |
565 | GList removeCookieList = { data, nullptr, nullptr }; |
566 | test->remove(WEBKIT_WEBSITE_DATA_COOKIES, &removeCookieList); |
567 | dataList = test->fetch(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT); |
568 | g_assert_null(dataList); |
569 | |
570 | // Clear all. |
571 | static const WebKitWebsiteDataTypes cacheAndAppcacheTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT); |
572 | test->clear(cacheAndAppcacheTypes, 0); |
573 | dataList = test->fetch(cacheAndAppcacheTypes); |
574 | g_assert_null(dataList); |
575 | |
576 | webkit_settings_set_enable_media_stream(settings, enabled); |
577 | } |
578 | |
579 | void beforeAll() |
580 | { |
581 | kServer = new WebKitTestServer(); |
582 | kServer->run(serverCallback); |
583 | |
584 | WebsiteDataTest::add("WebKitWebsiteData" , "configuration" , testWebsiteDataConfiguration); |
585 | WebViewTest::add("WebKitWebsiteData" , "ephemeral" , testWebsiteDataEphemeral); |
586 | WebsiteDataTest::add("WebKitWebsiteData" , "cache" , testWebsiteDataCache); |
587 | WebsiteDataTest::add("WebKitWebsiteData" , "storage" , testWebsiteDataStorage); |
588 | WebsiteDataTest::add("WebKitWebsiteData" , "databases" , testWebsiteDataDatabases); |
589 | WebsiteDataTest::add("WebKitWebsiteData" , "appcache" , testWebsiteDataAppcache); |
590 | WebsiteDataTest::add("WebKitWebsiteData" , "cookies" , testWebsiteDataCookies); |
591 | WebsiteDataTest::add("WebKitWebsiteData" , "deviceidhashsalt" , testWebsiteDataDeviceIdHashSalt); |
592 | } |
593 | |
594 | void afterAll() |
595 | { |
596 | delete kServer; |
597 | } |
598 | |