1 /*
2 * Copyright (C) 2009 Martin Robinson, Jan Michael C. Alonzo
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 "webkitwebdatabase.h"
22
23 #include "webkitprivate.h"
24
25 #include "CString.h"
26 #include "PlatformString.h"
27 #include "DatabaseTracker.h"
28
29 #include <glib/gi18n-lib.h>
30
31 /**
32 * SECTION:webkitsecurityorigin
33 * @short_description: A security boundary for web sites
34 *
35 * #WebKitSecurityOrigin is a representation of a security domain defined
36 * by web sites. An origin consists of a host name, a protocol, and a port
37 * number. Web sites with the same security origin can access each other's
38 * resources for client-side scripting or database access.
39 *
40 * Use #webkit_web_frame_get_security_origin to get the security origin of a
41 * #WebKitWebFrame.
42 *
43 * Database quotas and usages are also defined per security origin. The
44 * cumulative disk usage of an origin's databases may be retrieved with
45 * #webkit_security_origin_get_web_database_usage. An origin's quota can be
46 * adjusted with #webkit_security_origin_set_web_database_quota.
47 */
48
49 using namespace WebKit;
50
51 enum {
52 PROP_0,
53
54 PROP_PROTOCOL,
55 PROP_HOST,
56 PROP_PORT,
57 PROP_DATABASE_USAGE,
58 PROP_DATABASE_QUOTA
59 };
60
G_DEFINE_TYPE(WebKitSecurityOrigin,webkit_security_origin,G_TYPE_OBJECT)61 G_DEFINE_TYPE(WebKitSecurityOrigin, webkit_security_origin, G_TYPE_OBJECT)
62
63 static void webkit_security_origin_finalize(GObject* object)
64 {
65 WebKitSecurityOrigin* securityOrigin = WEBKIT_SECURITY_ORIGIN(object);
66 WebKitSecurityOriginPrivate* priv = securityOrigin->priv;
67
68 g_free(priv->protocol);
69 g_free(priv->host);
70
71 G_OBJECT_CLASS(webkit_security_origin_parent_class)->finalize(object);
72 }
73
webkit_security_origin_dispose(GObject * object)74 static void webkit_security_origin_dispose(GObject* object)
75 {
76 WebKitSecurityOrigin* securityOrigin = WEBKIT_SECURITY_ORIGIN(object);
77 WebKitSecurityOriginPrivate* priv = securityOrigin->priv;
78
79 if (!priv->disposed) {
80 priv->coreOrigin->deref();
81 g_hash_table_destroy(priv->webDatabases);
82 priv->disposed = true;
83 }
84
85 G_OBJECT_CLASS(webkit_security_origin_parent_class)->dispose(object);
86 }
87
webkit_security_origin_set_property(GObject * object,guint propId,const GValue * value,GParamSpec * pspec)88 static void webkit_security_origin_set_property(GObject* object, guint propId, const GValue* value, GParamSpec* pspec)
89 {
90 WebKitSecurityOrigin* securityOrigin = WEBKIT_SECURITY_ORIGIN(object);
91
92 switch (propId) {
93 case PROP_DATABASE_QUOTA:
94 webkit_security_origin_set_web_database_quota(securityOrigin, g_value_get_uint64(value));
95 break;
96 default:
97 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
98 break;
99 }
100 }
101
webkit_security_origin_get_property(GObject * object,guint propId,GValue * value,GParamSpec * pspec)102 static void webkit_security_origin_get_property(GObject* object, guint propId, GValue* value, GParamSpec* pspec)
103 {
104 WebKitSecurityOrigin* securityOrigin = WEBKIT_SECURITY_ORIGIN(object);
105
106 switch (propId) {
107 case PROP_PROTOCOL:
108 g_value_set_string(value, webkit_security_origin_get_protocol(securityOrigin));
109 break;
110 case PROP_HOST:
111 g_value_set_string(value, webkit_security_origin_get_host(securityOrigin));
112 break;
113 case PROP_PORT:
114 g_value_set_uint(value, webkit_security_origin_get_port(securityOrigin));
115 break;
116 case PROP_DATABASE_USAGE:
117 g_value_set_uint64(value, webkit_security_origin_get_web_database_usage(securityOrigin));
118 break;
119 case PROP_DATABASE_QUOTA:
120 g_value_set_uint64(value, webkit_security_origin_get_web_database_quota(securityOrigin));
121 break;
122 default:
123 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
124 break;
125 }
126 }
127
webkit_security_origins()128 static GHashTable* webkit_security_origins()
129 {
130 static GHashTable* securityOrigins = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref);
131 return securityOrigins;
132 }
133
webkit_security_origin_class_init(WebKitSecurityOriginClass * klass)134 static void webkit_security_origin_class_init(WebKitSecurityOriginClass* klass)
135 {
136 GObjectClass* gobjectClass = G_OBJECT_CLASS(klass);
137 gobjectClass->dispose = webkit_security_origin_dispose;
138 gobjectClass->finalize = webkit_security_origin_finalize;
139 gobjectClass->set_property = webkit_security_origin_set_property;
140 gobjectClass->get_property = webkit_security_origin_get_property;
141
142 /**
143 * WebKitSecurityOrigin:protocol:
144 *
145 * The protocol of the security origin.
146 *
147 * Since: 1.1.14
148 */
149 g_object_class_install_property(gobjectClass, PROP_PROTOCOL,
150 g_param_spec_string("protocol",
151 _("Protocol"),
152 _("The protocol of the security origin"),
153 NULL,
154 WEBKIT_PARAM_READABLE));
155
156 /**
157 * WebKitSecurityOrigin:host:
158 *
159 * The host of the security origin.
160 *
161 * Since: 1.1.14
162 */
163 g_object_class_install_property(gobjectClass, PROP_HOST,
164 g_param_spec_string("host",
165 _("Host"),
166 _("The host of the security origin"),
167 NULL,
168 WEBKIT_PARAM_READABLE));
169
170 /**
171 * WebKitSecurityOrigin:port:
172 *
173 * The port of the security origin.
174 *
175 * Since: 1.1.14
176 */
177 g_object_class_install_property(gobjectClass, PROP_PORT,
178 g_param_spec_uint("port",
179 _("Port"),
180 _("The port of the security origin"),
181 0, G_MAXUSHORT, 0,
182 WEBKIT_PARAM_READABLE));
183
184 /**
185 * WebKitSecurityOrigin:web-database-usage:
186 *
187 * The cumulative size of all web databases in the security origin in bytes.
188 *
189 * Since: 1.1.14
190 */
191 g_object_class_install_property(gobjectClass, PROP_DATABASE_USAGE,
192 g_param_spec_uint64("web-database-usage",
193 _("Web Database Usage"),
194 _("The cumulative size of all web databases in the security origin"),
195 0, G_MAXUINT64, 0,
196 WEBKIT_PARAM_READABLE));
197 /**
198 * WebKitSecurityOrigin:web-database-quota:
199 *
200 * The web database qouta of the security origin in bytes.
201 *
202 * Since: 1.1.14
203 */
204 g_object_class_install_property(gobjectClass, PROP_DATABASE_QUOTA,
205 g_param_spec_uint64("web-database-quota",
206 _("Web Database Quota"),
207 _("The web database quota of the security origin in bytes"),
208 0, G_MAXUINT64, 0,
209 WEBKIT_PARAM_READWRITE));
210
211 g_type_class_add_private(klass, sizeof(WebKitSecurityOriginPrivate));
212 }
213
webkit_security_origin_init(WebKitSecurityOrigin * securityOrigin)214 static void webkit_security_origin_init(WebKitSecurityOrigin* securityOrigin)
215 {
216 WebKitSecurityOriginPrivate* priv = WEBKIT_SECURITY_ORIGIN_GET_PRIVATE(securityOrigin);
217 priv->webDatabases = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref);
218 securityOrigin->priv = priv;
219 }
220
221 /**
222 * webkit_security_origin_get_protocol:
223 * @security_origin: a #WebKitSecurityOrigin
224 *
225 * Returns the protocol for the security origin.
226 *
227 * Returns: the protocol for the security origin
228 *
229 * Since: 1.1.14
230 **/
webkit_security_origin_get_protocol(WebKitSecurityOrigin * securityOrigin)231 G_CONST_RETURN gchar* webkit_security_origin_get_protocol(WebKitSecurityOrigin* securityOrigin)
232 {
233 g_return_val_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin), NULL);
234
235 WebKitSecurityOriginPrivate* priv = securityOrigin->priv;
236 WebCore::String protocol = priv->coreOrigin->protocol();
237
238 if (!priv->protocol)
239 priv->protocol = g_strdup(protocol.utf8().data());
240
241 return priv->protocol;
242 }
243
244 /**
245 * webkit_security_origin_get_host:
246 * @security_origin: a #WebKitSecurityOrigin
247 *
248 * Returns the hostname for the security origin.
249 *
250 * Returns: the hostname for the security origin
251 *
252 * Since: 1.1.14
253 **/
webkit_security_origin_get_host(WebKitSecurityOrigin * securityOrigin)254 G_CONST_RETURN gchar* webkit_security_origin_get_host(WebKitSecurityOrigin* securityOrigin)
255 {
256 g_return_val_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin), NULL);
257
258 WebKitSecurityOriginPrivate* priv = securityOrigin->priv;
259 WebCore::String host = priv->coreOrigin->host();
260
261 if (!priv->host)
262 priv->host = g_strdup(host.utf8().data());
263
264 return priv->host;
265 }
266
267 /**
268 * webkit_security_origin_get_port:
269 * @security_origin: a #WebKitSecurityOrigin
270 *
271 * Returns the port for the security origin.
272 *
273 * Returns: the port for the security origin
274 *
275 * Since: 1.1.14
276 **/
webkit_security_origin_get_port(WebKitSecurityOrigin * securityOrigin)277 guint webkit_security_origin_get_port(WebKitSecurityOrigin* securityOrigin)
278 {
279 g_return_val_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin), 0);
280
281 WebCore::SecurityOrigin* coreOrigin = core(securityOrigin);
282 return coreOrigin->port();
283 }
284
285 /**
286 * webkit_security_origin_get_web_database_usage:
287 * @security_origin: a #WebKitSecurityOrigin
288 *
289 * Returns the cumulative size of all Web Database database's in the origin
290 * in bytes.
291 *
292 * Returns: the cumulative size of all databases
293 *
294 * Since: 1.1.14
295 **/
webkit_security_origin_get_web_database_usage(WebKitSecurityOrigin * securityOrigin)296 guint64 webkit_security_origin_get_web_database_usage(WebKitSecurityOrigin* securityOrigin)
297 {
298 g_return_val_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin), 0);
299
300 #if ENABLE(DATABASE)
301 WebCore::SecurityOrigin* coreOrigin = core(securityOrigin);
302 return WebCore::DatabaseTracker::tracker().usageForOrigin(coreOrigin);
303 #else
304 return 0;
305 #endif
306 }
307
308 /**
309 * webkit_security_origin_get_web_database_quota:
310 * @security_origin: a #WebKitSecurityOrigin
311 *
312 * Returns the quota for Web Database storage of the security origin
313 * in bytes.
314 *
315 * Returns: the Web Database quota
316 *
317 * Since: 1.1.14
318 **/
webkit_security_origin_get_web_database_quota(WebKitSecurityOrigin * securityOrigin)319 guint64 webkit_security_origin_get_web_database_quota(WebKitSecurityOrigin* securityOrigin)
320 {
321 g_return_val_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin), 0);
322
323 #if ENABLE(DATABASE)
324 WebCore::SecurityOrigin* coreOrigin = core(securityOrigin);
325 return WebCore::DatabaseTracker::tracker().quotaForOrigin(coreOrigin);
326 #else
327 return 0;
328 #endif
329 }
330
331 /**
332 * webkit_security_origin_set_web_database_quota:
333 * @security_origin: a #WebKitSecurityOrigin
334 * @quota: a new Web Database quota in bytes
335 *
336 * Adjust the quota for Web Database storage of the security origin
337 *
338 * Since: 1.1.14
339 **/
webkit_security_origin_set_web_database_quota(WebKitSecurityOrigin * securityOrigin,guint64 quota)340 void webkit_security_origin_set_web_database_quota(WebKitSecurityOrigin* securityOrigin, guint64 quota)
341 {
342 g_return_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin));
343
344 #if ENABLE(DATABASE)
345 WebCore::SecurityOrigin* coreOrigin = core(securityOrigin);
346 WebCore::DatabaseTracker::tracker().setQuota(coreOrigin, quota);
347 #endif
348 }
349
350 /**
351 * webkit_security_origin_get_all_web_databases:
352 * @security_origin: a #WebKitSecurityOrigin
353 *
354 * Returns a list of all Web Databases in the security origin.
355 *
356 * Returns: a #Glist of databases in the security origin.
357 *
358 * Since: 1.1.14
359 **/
webkit_security_origin_get_all_web_databases(WebKitSecurityOrigin * securityOrigin)360 GList* webkit_security_origin_get_all_web_databases(WebKitSecurityOrigin* securityOrigin)
361 {
362 g_return_val_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin), NULL);
363 GList* databases = NULL;
364
365 #if ENABLE(DATABASE)
366 WebCore::SecurityOrigin* coreOrigin = core(securityOrigin);
367 Vector<WebCore::String> databaseNames;
368
369 if (!WebCore::DatabaseTracker::tracker().databaseNamesForOrigin(coreOrigin, databaseNames))
370 return NULL;
371
372 for (unsigned i = 0; i < databaseNames.size(); ++i) {
373 WebKitWebDatabase* database = webkit_security_origin_get_web_database(securityOrigin, databaseNames[i].utf8().data());
374 databases = g_list_append(databases, database);
375 }
376 #endif
377
378 return databases;
379 }
380
kit(WebCore::SecurityOrigin * coreOrigin)381 WebKitSecurityOrigin* WebKit::kit(WebCore::SecurityOrigin* coreOrigin)
382 {
383 ASSERT(coreOrigin);
384
385 GHashTable* table = webkit_security_origins();
386 WebKitSecurityOrigin* origin = (WebKitSecurityOrigin*) g_hash_table_lookup(table, coreOrigin);
387
388 if (!origin) {
389 origin = WEBKIT_SECURITY_ORIGIN(g_object_new(WEBKIT_TYPE_SECURITY_ORIGIN, NULL));
390 origin->priv->coreOrigin = coreOrigin;
391 g_hash_table_insert(table, coreOrigin, origin);
392 }
393
394 return origin;
395 }
396
397
core(WebKitSecurityOrigin * securityOrigin)398 WebCore::SecurityOrigin* WebKit::core(WebKitSecurityOrigin* securityOrigin)
399 {
400 ASSERT(securityOrigin);
401
402 return securityOrigin->priv->coreOrigin.get();
403 }
404
webkit_security_origin_get_web_database(WebKitSecurityOrigin * securityOrigin,const gchar * databaseName)405 WebKitWebDatabase* webkit_security_origin_get_web_database(WebKitSecurityOrigin* securityOrigin, const gchar* databaseName)
406 {
407 g_return_val_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin), NULL);
408
409 WebKitSecurityOriginPrivate* priv = securityOrigin->priv;
410 GHashTable* databaseHash = priv->webDatabases;
411 WebKitWebDatabase* database = (WebKitWebDatabase*) g_hash_table_lookup(databaseHash, databaseName);
412
413 if (!database) {
414 database = WEBKIT_WEB_DATABASE(g_object_new(WEBKIT_TYPE_WEB_DATABASE,
415 "security-origin", securityOrigin,
416 "name", databaseName,
417 NULL));
418 g_hash_table_insert(databaseHash, g_strdup(databaseName), database);
419 }
420
421 return database;
422 }
423
424