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 Library General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2 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 "WebKitWebsiteData.h" |
22 | |
23 | #include "WebKitSecurityOriginPrivate.h" |
24 | #include "WebKitWebsiteDataPrivate.h" |
25 | #include <glib/gi18n-lib.h> |
26 | #include <wtf/HashTable.h> |
27 | #include <wtf/Vector.h> |
28 | |
29 | using namespace WebKit; |
30 | |
31 | /** |
32 | * SECTION: WebKitWebsiteData |
33 | * @Short_description: Website data |
34 | * @Title: WebKitWebsiteData |
35 | * @See_also: #WebKitWebsiteDataManager |
36 | * |
37 | * WebKitWebsiteData represents data stored in the client by a particular website. |
38 | * A website is normally a set of URLs grouped by domain name. You can get the website name, |
39 | * which is usually the domain, with webkit_website_data_get_name(). |
40 | * Documents loaded from the file system, like file:// URIs, are all grouped in the same WebKitWebsiteData |
41 | * with the name "Local files". |
42 | * |
43 | * A website can store different types of data in the client side. #WebKitWebsiteDataTypes is an enum containing |
44 | * all the possible data types; use webkit_website_data_get_types() to get the bitmask of data types. |
45 | * It's also possible to know the size of the data stored for some of the #WebKitWebsiteDataTypes by using |
46 | * webkit_website_data_get_size(). |
47 | * |
48 | * A list of WebKitWebsiteData can be retrieved with webkit_website_data_manager_fetch(). See #WebKitWebsiteDataManager |
49 | * for more information. |
50 | * |
51 | * Since: 2.16 |
52 | */ |
53 | struct _WebKitWebsiteData { |
54 | explicit _WebKitWebsiteData(WebsiteDataRecord&& websiteDataDecord) |
55 | : record(WTFMove(websiteDataDecord)) |
56 | { |
57 | } |
58 | |
59 | WebsiteDataRecord record; |
60 | CString displayName; |
61 | int referenceCount { 1 }; |
62 | }; |
63 | |
64 | G_DEFINE_BOXED_TYPE(WebKitWebsiteData, webkit_website_data, webkit_website_data_ref, webkit_website_data_unref) |
65 | |
66 | static bool recordContainsSupportedDataTypes(const WebsiteDataRecord& record) |
67 | { |
68 | return record.types.containsAny({ |
69 | WebsiteDataType::MemoryCache, |
70 | WebsiteDataType::DiskCache, |
71 | WebsiteDataType::OfflineWebApplicationCache, |
72 | WebsiteDataType::SessionStorage, |
73 | WebsiteDataType::LocalStorage, |
74 | WebsiteDataType::WebSQLDatabases, |
75 | WebsiteDataType::IndexedDBDatabases, |
76 | #if ENABLE(NETSCAPE_PLUGIN_API) |
77 | WebsiteDataType::PlugInData, |
78 | #endif |
79 | WebsiteDataType::Cookies, |
80 | WebsiteDataType::DeviceIdHashSalt |
81 | }); |
82 | } |
83 | |
84 | static WebKitWebsiteDataTypes toWebKitWebsiteDataTypes(OptionSet<WebsiteDataType> types) |
85 | { |
86 | uint32_t returnValue = 0; |
87 | if (types.contains(WebsiteDataType::MemoryCache)) |
88 | returnValue |= WEBKIT_WEBSITE_DATA_MEMORY_CACHE; |
89 | if (types.contains(WebsiteDataType::DiskCache)) |
90 | returnValue |= WEBKIT_WEBSITE_DATA_DISK_CACHE; |
91 | if (types.contains(WebsiteDataType::OfflineWebApplicationCache)) |
92 | returnValue |= WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE; |
93 | if (types.contains(WebsiteDataType::SessionStorage)) |
94 | returnValue |= WEBKIT_WEBSITE_DATA_SESSION_STORAGE; |
95 | if (types.contains(WebsiteDataType::LocalStorage)) |
96 | returnValue |= WEBKIT_WEBSITE_DATA_LOCAL_STORAGE; |
97 | if (types.contains(WebsiteDataType::WebSQLDatabases)) |
98 | returnValue |= WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES; |
99 | if (types.contains(WebsiteDataType::IndexedDBDatabases)) |
100 | returnValue |= WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES; |
101 | #if ENABLE(NETSCAPE_PLUGIN_API) |
102 | if (types.contains(WebsiteDataType::PlugInData)) |
103 | returnValue |= WEBKIT_WEBSITE_DATA_PLUGIN_DATA; |
104 | #endif |
105 | if (types.contains(WebsiteDataType::Cookies)) |
106 | returnValue |= WEBKIT_WEBSITE_DATA_COOKIES; |
107 | if (types.contains(WebsiteDataType::DeviceIdHashSalt)) |
108 | returnValue |= WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT; |
109 | return static_cast<WebKitWebsiteDataTypes>(returnValue); |
110 | } |
111 | |
112 | WebKitWebsiteData* webkitWebsiteDataCreate(WebsiteDataRecord&& record) |
113 | { |
114 | if (!recordContainsSupportedDataTypes(record)) |
115 | return nullptr; |
116 | |
117 | WebKitWebsiteData* websiteData = static_cast<WebKitWebsiteData*>(fastMalloc(sizeof(WebKitWebsiteData))); |
118 | new (websiteData) WebKitWebsiteData(WTFMove(record)); |
119 | return websiteData; |
120 | } |
121 | |
122 | const WebKit::WebsiteDataRecord& webkitWebsiteDataGetRecord(WebKitWebsiteData* websiteData) |
123 | { |
124 | ASSERT(websiteData); |
125 | return websiteData->record; |
126 | } |
127 | |
128 | /** |
129 | * webkit_website_data_ref: |
130 | * @website_data: a #WebKitWebsiteData |
131 | * |
132 | * Atomically increments the reference count of @website_data by one. |
133 | * This function is MT-safe and may be called from any thread. |
134 | * |
135 | * Returns: The passed #WebKitWebsiteData |
136 | * |
137 | * Since: 2.16 |
138 | */ |
139 | WebKitWebsiteData* webkit_website_data_ref(WebKitWebsiteData* websiteData) |
140 | { |
141 | g_return_val_if_fail(websiteData, nullptr); |
142 | |
143 | g_atomic_int_inc(&websiteData->referenceCount); |
144 | return websiteData; |
145 | } |
146 | |
147 | /** |
148 | * webkit_website_data_unref: |
149 | * @website_data: A #WebKitWebsiteData |
150 | * |
151 | * Atomically decrements the reference count of @website_data by one. |
152 | * If the reference count drops to 0, all memory allocated by |
153 | * #WebKitWebsiteData is released. This function is MT-safe and may be |
154 | * called from any thread. |
155 | * |
156 | * Since: 2.16 |
157 | */ |
158 | void webkit_website_data_unref(WebKitWebsiteData* websiteData) |
159 | { |
160 | g_return_if_fail(websiteData); |
161 | |
162 | if (g_atomic_int_dec_and_test(&websiteData->referenceCount)) { |
163 | websiteData->~WebKitWebsiteData(); |
164 | fastFree(websiteData); |
165 | } |
166 | } |
167 | |
168 | /** |
169 | * webkit_website_data_get_name: |
170 | * @website_data: a #WebKitWebsiteData |
171 | * |
172 | * Gets the name of #WebKitWebsiteData. This is the website name, normally represented by |
173 | * a domain or host name. All local documents are grouped in the same #WebKitWebsiteData using |
174 | * the name "Local files". |
175 | * |
176 | * Returns: the website name of @website_data. |
177 | * |
178 | * Since: 2.16 |
179 | */ |
180 | const char* webkit_website_data_get_name(WebKitWebsiteData* websiteData) |
181 | { |
182 | g_return_val_if_fail(websiteData, nullptr); |
183 | |
184 | if (websiteData->displayName.isNull()) { |
185 | if (websiteData->record.displayName == "Local documents on your computer" ) |
186 | websiteData->displayName = _("Local files" ); |
187 | else |
188 | websiteData->displayName = websiteData->record.displayName.utf8(); |
189 | } |
190 | return websiteData->displayName.data(); |
191 | } |
192 | |
193 | /** |
194 | * webkit_website_data_get_types: |
195 | * @website_data: a #WebKitWebsiteData |
196 | * |
197 | * Gets the types of data stored in the client for a #WebKitWebsiteData. These are the |
198 | * types actually present, not the types queried with webkit_website_data_manager_fetch(). |
199 | * |
200 | * Returns: a bitmask of #WebKitWebsiteDataTypes in @website_data |
201 | * |
202 | * Since: 2.16 |
203 | */ |
204 | WebKitWebsiteDataTypes webkit_website_data_get_types(WebKitWebsiteData* websiteData) |
205 | { |
206 | g_return_val_if_fail(websiteData, static_cast<WebKitWebsiteDataTypes>(0)); |
207 | |
208 | return toWebKitWebsiteDataTypes(websiteData->record.types); |
209 | } |
210 | |
211 | /** |
212 | * webkit_website_data_get_size: |
213 | * @website_data: a #WebKitWebsiteData |
214 | * @types: a bitmask of #WebKitWebsiteDataTypes |
215 | * |
216 | * Gets the size of the data of types @types in a #WebKitWebsiteData. |
217 | * Note that currently the data size is only known for %WEBKIT_WEBSITE_DATA_DISK_CACHE data type |
218 | * so for all other types 0 will be returned. |
219 | * |
220 | * Returns: the size of @website_data for the given @types. |
221 | * |
222 | * Since: 2.16 |
223 | */ |
224 | guint64 webkit_website_data_get_size(WebKitWebsiteData* websiteData, WebKitWebsiteDataTypes types) |
225 | { |
226 | g_return_val_if_fail(websiteData, 0); |
227 | |
228 | if (!types || !websiteData->record.size) |
229 | return 0; |
230 | |
231 | guint64 totalSize = 0; |
232 | for (auto type : websiteData->record.size->typeSizes.keys()) { |
233 | if (type & types) |
234 | totalSize += websiteData->record.size->typeSizes.get(type); |
235 | } |
236 | |
237 | return totalSize; |
238 | } |
239 | |