From ade7a484f33f223defad9acb50396058767781e1 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Tue, 11 Dec 2012 18:43:42 +0100 Subject: [PATCH] Add SoupCookieJarDB to replace SoupCookieJarSqlite Move SoupCookieJarSqlite (and its sqlite3 dependency) into libsoup from libsoup-gnome, but rename it to SoupCookieJarDB so libsoup-gnome can keep using the old name. SoupCookieJarSqlite is now just a wrapper around SoupCookieJarDB. --- configure.ac | 14 +- docs/reference/libsoup-2.4-docs.sgml | 2 +- docs/reference/libsoup-2.4-sections.txt | 27 ++- libsoup/Makefile.am | 6 +- libsoup/libsoup-2.4.sym | 2 + libsoup/soup-cookie-jar-db.c | 337 ++++++++++++++++++++++++++++++++ libsoup/soup-cookie-jar-db.h | 46 +++++ libsoup/soup-cookie-jar-sqlite.c | 298 +--------------------------- libsoup/soup-cookie-jar-sqlite.h | 13 +- libsoup/soup.h | 1 + 10 files changed, 419 insertions(+), 327 deletions(-) create mode 100644 libsoup/soup-cookie-jar-db.c create mode 100644 libsoup/soup-cookie-jar-db.h diff --git a/configure.ac b/configure.ac index 3f5097c..fe5403b 100644 --- a/configure.ac +++ b/configure.ac @@ -97,6 +97,10 @@ PKG_CHECK_MODULES(XML, libxml-2.0) AC_SUBST(XML_CFLAGS) AC_SUBST(XML_LIBS) +PKG_CHECK_MODULES(SQLITE, sqlite3) +AC_SUBST(SQLITE_CFLAGS) +AC_SUBST(SQLITE_LIBS) + dnl *********************** dnl *** Check for Win32 *** dnl *********************** @@ -142,18 +146,8 @@ AM_CONDITIONAL(BUILD_LIBSOUP_GNOME, test $with_gnome != no) if test $with_gnome != no; then AC_DEFINE(HAVE_GNOME, 1, [Defined if GNOME support is enabled]) - - PKG_CHECK_MODULES(SQLITE, sqlite3, :, [AC_MSG_ERROR(dnl -[Could not find sqlite3 devel files: - -$SQLITE_PKG_ERRORS - -Pass "--without-gnome" to configure if you want to build libsoup -without GNOME support.])]) fi AC_SUBST(HAVE_GNOME) -AC_SUBST(SQLITE_CFLAGS) -AC_SUBST(SQLITE_LIBS) dnl *************** diff --git a/docs/reference/libsoup-2.4-docs.sgml b/docs/reference/libsoup-2.4-docs.sgml index 3f24676..1273eca 100644 --- a/docs/reference/libsoup-2.4-docs.sgml +++ b/docs/reference/libsoup-2.4-docs.sgml @@ -49,6 +49,7 @@ + @@ -64,7 +65,6 @@ GNOME integration - diff --git a/docs/reference/libsoup-2.4-sections.txt b/docs/reference/libsoup-2.4-sections.txt index 43388ef..f8e6dbf 100644 --- a/docs/reference/libsoup-2.4-sections.txt +++ b/docs/reference/libsoup-2.4-sections.txt @@ -973,22 +973,21 @@ soup_cookie_jar_text_get_type
-libsoup/soup-gnome.h -soup-cookie-jar-sqlite -SoupCookieJarSqlite -SoupCookieJarSqlite -soup_cookie_jar_sqlite_new +soup-cookie-jar-db +SoupCookieJarDB +SoupCookieJarDB +soup_cookie_jar_db_new -SOUP_COOKIE_JAR_SQLITE_FILENAME +SOUP_COOKIE_JAR_DB_FILENAME -SoupCookieJarSqliteClass -SOUP_COOKIE_JAR_SQLITE -SOUP_COOKIE_JAR_SQLITE_CLASS -SOUP_COOKIE_JAR_SQLITE_GET_CLASS -SOUP_TYPE_COOKIE_JAR_SQLITE -SOUP_IS_COOKIE_JAR_SQLITE -SOUP_IS_COOKIE_JAR_SQLITE_CLASS -soup_cookie_jar_sqlite_get_type +SoupCookieJarDBClass +SOUP_COOKIE_JAR_DB +SOUP_COOKIE_JAR_DB_CLASS +SOUP_COOKIE_JAR_DB_GET_CLASS +SOUP_TYPE_COOKIE_JAR_DB +SOUP_IS_COOKIE_JAR_DB +SOUP_IS_COOKIE_JAR_DB_CLASS +soup_cookie_jar_db_get_type
diff --git a/libsoup/Makefile.am b/libsoup/Makefile.am index 3a256e0..87629ed 100644 --- a/libsoup/Makefile.am +++ b/libsoup/Makefile.am @@ -34,6 +34,7 @@ soup_headers = \ soup-content-sniffer.h \ soup-cookie.h \ soup-cookie-jar.h \ + soup-cookie-jar-db.h \ soup-cookie-jar-text.h \ soup-date.h \ soup-form.h \ @@ -88,6 +89,7 @@ EXTRA_DIST += libsoup-2.4.sym libsoup_2_4_la_LIBADD = \ $(GLIB_LIBS) \ $(XML_LIBS) \ + $(SQLITE_LIBS) \ -lz \ $(LIBWS2_32) @@ -127,6 +129,7 @@ libsoup_2_4_la_SOURCES = \ soup-converter-wrapper.c \ soup-cookie.c \ soup-cookie-jar.c \ + soup-cookie-jar-db.c \ soup-cookie-jar-text.c \ soup-date.c \ soup-directory-input-stream.h \ @@ -212,8 +215,7 @@ EXTRA_DIST += libsoup-gnome-2.4.sym libsoup_gnome_2_4_la_LIBADD = \ libsoup-2.4.la \ - $(GLIB_LIBS) \ - $(SQLITE_LIBS) + $(GLIB_LIBS) libsoup_gnome_2_4_la_SOURCES = \ soup-cookie-jar-sqlite.c \ diff --git a/libsoup/libsoup-2.4.sym b/libsoup/libsoup-2.4.sym index aa302c6..66e5bf7 100644 --- a/libsoup/libsoup-2.4.sym +++ b/libsoup/libsoup-2.4.sym @@ -110,6 +110,8 @@ soup_cookie_jar_accept_policy_get_type soup_cookie_jar_add_cookie soup_cookie_jar_add_cookie_with_first_party soup_cookie_jar_all_cookies +soup_cookie_jar_db_get_type +soup_cookie_jar_db_new soup_cookie_jar_delete_cookie soup_cookie_jar_get_accept_policy soup_cookie_jar_get_cookie_list diff --git a/libsoup/soup-cookie-jar-db.c b/libsoup/soup-cookie-jar-db.c new file mode 100644 index 0000000..8f21baa --- /dev/null +++ b/libsoup/soup-cookie-jar-db.c @@ -0,0 +1,337 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * soup-cookie-jar-db.c: database-based cookie storage + * + * Using danw's soup-cookie-jar-text as template + * Copyright (C) 2008 Diego Escalante Urrelo + * Copyright (C) 2009 Collabora Ltd. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include + +#include "soup-cookie-jar-db.h" +#include "soup.h" + +/** + * SECTION:soup-cookie-jar-db + * @short_description: Database-based Cookie Jar + * + * #SoupCookieJarDB is a #SoupCookieJar that reads cookies from and + * writes them to a sqlite database in the new Mozilla format. + * + * (This is identical to SoupCookieJarSqlite in + * libsoup-gnome; it has just been moved into libsoup proper, and + * renamed to avoid conflicting.) + **/ + +enum { + PROP_0, + + PROP_FILENAME, + + LAST_PROP +}; + +typedef struct { + char *filename; + sqlite3 *db; +} SoupCookieJarDBPrivate; + +#define SOUP_COOKIE_JAR_DB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_COOKIE_JAR_DB, SoupCookieJarDBPrivate)) + +G_DEFINE_TYPE (SoupCookieJarDB, soup_cookie_jar_db, SOUP_TYPE_COOKIE_JAR) + +static void load (SoupCookieJar *jar); + +static void +soup_cookie_jar_db_init (SoupCookieJarDB *db) +{ +} + +static void +soup_cookie_jar_db_finalize (GObject *object) +{ + SoupCookieJarDBPrivate *priv = + SOUP_COOKIE_JAR_DB_GET_PRIVATE (object); + + g_free (priv->filename); + g_clear_pointer (&priv->db, sqlite3_close); + + G_OBJECT_CLASS (soup_cookie_jar_db_parent_class)->finalize (object); +} + +static void +soup_cookie_jar_db_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + SoupCookieJarDBPrivate *priv = + SOUP_COOKIE_JAR_DB_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_FILENAME: + priv->filename = g_value_dup_string (value); + load (SOUP_COOKIE_JAR (object)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +soup_cookie_jar_db_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + SoupCookieJarDBPrivate *priv = + SOUP_COOKIE_JAR_DB_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_FILENAME: + g_value_set_string (value, priv->filename); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/** + * soup_cookie_jar_db_new: + * @filename: the filename to read to/write from, or %NULL + * @read_only: %TRUE if @filename is read-only + * + * Creates a #SoupCookieJarDB. + * + * @filename will be read in at startup to create an initial set of + * cookies. If @read_only is %FALSE, then the non-session cookies will + * be written to @filename when the 'changed' signal is emitted from + * the jar. (If @read_only is %TRUE, then the cookie jar will only be + * used for this session, and changes made to it will be lost when the + * jar is destroyed.) + * + * Return value: the new #SoupCookieJar + * + * Since: 2.42 + **/ +SoupCookieJar * +soup_cookie_jar_db_new (const char *filename, gboolean read_only) +{ + g_return_val_if_fail (filename != NULL, NULL); + + return g_object_new (SOUP_TYPE_COOKIE_JAR_DB, + SOUP_COOKIE_JAR_DB_FILENAME, filename, + SOUP_COOKIE_JAR_READ_ONLY, read_only, + NULL); +} + +#define QUERY_ALL "SELECT id, name, value, host, path, expiry, lastAccessed, isSecure, isHttpOnly FROM moz_cookies;" +#define CREATE_TABLE "CREATE TABLE moz_cookies (id INTEGER PRIMARY KEY, name TEXT, value TEXT, host TEXT, path TEXT,expiry INTEGER, lastAccessed INTEGER, isSecure INTEGER, isHttpOnly INTEGER)" +#define QUERY_INSERT "INSERT INTO moz_cookies VALUES(NULL, %Q, %Q, %Q, %Q, %d, NULL, %d, %d);" +#define QUERY_DELETE "DELETE FROM moz_cookies WHERE name=%Q AND host=%Q;" + +enum { + COL_ID, + COL_NAME, + COL_VALUE, + COL_HOST, + COL_PATH, + COL_EXPIRY, + COL_LAST_ACCESS, + COL_SECURE, + COL_HTTP_ONLY, + N_COL, +}; + +static int +callback (void *data, int argc, char **argv, char **colname) +{ + SoupCookie *cookie = NULL; + SoupCookieJar *jar = SOUP_COOKIE_JAR (data); + + char *name, *value, *host, *path; + gulong expire_time; + time_t now; + int max_age; + gboolean http_only = FALSE, secure = FALSE; + + now = time (NULL); + + name = argv[COL_NAME]; + value = argv[COL_VALUE]; + host = argv[COL_HOST]; + path = argv[COL_PATH]; + expire_time = strtoul (argv[COL_EXPIRY], NULL, 10); + + if (now >= expire_time) + return 0; + max_age = (expire_time - now <= G_MAXINT ? expire_time - now : G_MAXINT); + + http_only = (g_strcmp0 (argv[COL_HTTP_ONLY], "1") == 0); + secure = (g_strcmp0 (argv[COL_SECURE], "1") == 0); + + cookie = soup_cookie_new (name, value, host, path, max_age); + + if (secure) + soup_cookie_set_secure (cookie, TRUE); + if (http_only) + soup_cookie_set_http_only (cookie, TRUE); + + soup_cookie_jar_add_cookie (jar, cookie); + + return 0; +} + +static void +try_create_table (sqlite3 *db) +{ + char *error = NULL; + + if (sqlite3_exec (db, CREATE_TABLE, NULL, NULL, &error)) { + g_warning ("Failed to execute query: %s", error); + sqlite3_free (error); + } +} + +static void +exec_query_with_try_create_table (sqlite3 *db, + const char *sql, + int (*callback)(void*,int,char**,char**), + void *argument) +{ + char *error = NULL; + gboolean try_create = TRUE; + +try_exec: + if (sqlite3_exec (db, sql, callback, argument, &error)) { + if (try_create) { + try_create = FALSE; + try_create_table (db); + sqlite3_free (error); + error = NULL; + goto try_exec; + } else { + g_warning ("Failed to execute query: %s", error); + sqlite3_free (error); + } + } +} + +/* Follows sqlite3 convention; returns TRUE on error */ +static gboolean +open_db (SoupCookieJar *jar) +{ + SoupCookieJarDBPrivate *priv = + SOUP_COOKIE_JAR_DB_GET_PRIVATE (jar); + + char *error = NULL; + + if (sqlite3_open (priv->filename, &priv->db)) { + sqlite3_close (priv->db); + priv->db = NULL; + g_warning ("Can't open %s", priv->filename); + return TRUE; + } + + if (sqlite3_exec (priv->db, "PRAGMA synchronous = OFF; PRAGMA secure_delete = 1;", NULL, NULL, &error)) { + g_warning ("Failed to execute query: %s", error); + sqlite3_free (error); + } + + return FALSE; +} + +static void +load (SoupCookieJar *jar) +{ + SoupCookieJarDBPrivate *priv = + SOUP_COOKIE_JAR_DB_GET_PRIVATE (jar); + + if (priv->db == NULL) { + if (open_db (jar)) + return; + } + + exec_query_with_try_create_table (priv->db, QUERY_ALL, callback, jar); +} + +static void +soup_cookie_jar_db_changed (SoupCookieJar *jar, + SoupCookie *old_cookie, + SoupCookie *new_cookie) +{ + SoupCookieJarDBPrivate *priv = + SOUP_COOKIE_JAR_DB_GET_PRIVATE (jar); + char *query; + + if (priv->db == NULL) { + if (open_db (jar)) + return; + } + + if (old_cookie) { + query = sqlite3_mprintf (QUERY_DELETE, + old_cookie->name, + old_cookie->domain); + exec_query_with_try_create_table (priv->db, query, NULL, NULL); + sqlite3_free (query); + } + + if (new_cookie && new_cookie->expires) { + gulong expires; + + expires = (gulong)soup_date_to_time_t (new_cookie->expires); + query = sqlite3_mprintf (QUERY_INSERT, + new_cookie->name, + new_cookie->value, + new_cookie->domain, + new_cookie->path, + expires, + new_cookie->secure, + new_cookie->http_only); + exec_query_with_try_create_table (priv->db, query, NULL, NULL); + sqlite3_free (query); + } +} + +static gboolean +soup_cookie_jar_db_is_persistent (SoupCookieJar *jar) +{ + return TRUE; +} + +static void +soup_cookie_jar_db_class_init (SoupCookieJarDBClass *db_class) +{ + SoupCookieJarClass *cookie_jar_class = + SOUP_COOKIE_JAR_CLASS (db_class); + GObjectClass *object_class = G_OBJECT_CLASS (db_class); + + g_type_class_add_private (db_class, sizeof (SoupCookieJarDBPrivate)); + + cookie_jar_class->is_persistent = soup_cookie_jar_db_is_persistent; + cookie_jar_class->changed = soup_cookie_jar_db_changed; + + object_class->finalize = soup_cookie_jar_db_finalize; + object_class->set_property = soup_cookie_jar_db_set_property; + object_class->get_property = soup_cookie_jar_db_get_property; + + /** + * SOUP_COOKIE_JAR_DB_FILENAME: + * + * Alias for the #SoupCookieJarDB:filename property. (The + * cookie-storage filename.) + **/ + g_object_class_install_property ( + object_class, PROP_FILENAME, + g_param_spec_string (SOUP_COOKIE_JAR_DB_FILENAME, + "Filename", + "Cookie-storage filename", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +} diff --git a/libsoup/soup-cookie-jar-db.h b/libsoup/soup-cookie-jar-db.h new file mode 100644 index 0000000..1a98901 --- /dev/null +++ b/libsoup/soup-cookie-jar-db.h @@ -0,0 +1,46 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2008 Diego Escalante Urrelo + */ + +#ifndef SOUP_COOKIE_JAR_DB_H +#define SOUP_COOKIE_JAR_DB_H 1 + +#include + +G_BEGIN_DECLS + +#define SOUP_TYPE_COOKIE_JAR_DB (soup_cookie_jar_db_get_type ()) +#define SOUP_COOKIE_JAR_DB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SOUP_TYPE_COOKIE_JAR_DB, SoupCookieJarDB)) +#define SOUP_COOKIE_JAR_DB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_COOKIE_JAR_DB, SoupCookieJarDBClass)) +#define SOUP_IS_COOKIE_JAR_DB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SOUP_TYPE_COOKIE_JAR_DB)) +#define SOUP_IS_COOKIE_JAR_DB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SOUP_TYPE_COOKIE_JAR_DB)) +#define SOUP_COOKIE_JAR_DB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_COOKIE_JAR_DB, SoupCookieJarDBClass)) + +typedef struct { + SoupCookieJar parent; + +} SoupCookieJarDB; + +typedef struct { + SoupCookieJarClass parent_class; + + /* Padding for future expansion */ + void (*_libsoup_reserved1) (void); + void (*_libsoup_reserved2) (void); + void (*_libsoup_reserved3) (void); + void (*_libsoup_reserved4) (void); +} SoupCookieJarDBClass; + +#define SOUP_COOKIE_JAR_DB_FILENAME "filename" + +SOUP_AVAILABLE_IN_2_42 +GType soup_cookie_jar_db_get_type (void); + +SOUP_AVAILABLE_IN_2_42 +SoupCookieJar *soup_cookie_jar_db_new (const char *filename, + gboolean read_only); + +G_END_DECLS + +#endif /* SOUP_COOKIE_JAR_DB_H */ diff --git a/libsoup/soup-cookie-jar-sqlite.c b/libsoup/soup-cookie-jar-sqlite.c index 97e6a0e..705e047 100644 --- a/libsoup/soup-cookie-jar-sqlite.c +++ b/libsoup/soup-cookie-jar-sqlite.c @@ -1,10 +1,8 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * soup-cookie-jar-sqlite.c: ff sqlite-based cookie storage + * soup-cookie-jar-sqlite.c: deprecated version of sqlite-based cookie storage * - * Using danw's soup-cookie-jar-text as template - * Copyright (C) 2008 Diego Escalante Urrelo - * Copyright (C) 2009 Collabora Ltd. + * Copyright 2012 Red Hat, Inc. */ #ifdef HAVE_CONFIG_H @@ -13,18 +11,11 @@ #include -#include +/* Avoid deprecation warnings */ +#define SOUP_VERSION_MIN_REQUIRED SOUP_VERSION_2_40 -#include "soup-cookie-jar-sqlite.h" #include "soup.h" - -/** - * SECTION:soup-cookie-jar-sqlite - * @short_description: SQLite-based Cookie Jar - * - * #SoupCookieJarSqlite is a #SoupCookieJar that reads cookies from and - * writes them to an SQLite file in the new Mozilla format. - **/ +#include "soup-cookie-jar-sqlite.h" enum { PROP_0, @@ -34,89 +25,13 @@ enum { LAST_PROP }; -typedef struct { - char *filename; - sqlite3 *db; -} SoupCookieJarSqlitePrivate; - -#define SOUP_COOKIE_JAR_SQLITE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_COOKIE_JAR_SQLITE, SoupCookieJarSqlitePrivate)) - -G_DEFINE_TYPE (SoupCookieJarSqlite, soup_cookie_jar_sqlite, SOUP_TYPE_COOKIE_JAR) - -static void load (SoupCookieJar *jar); +G_DEFINE_TYPE (SoupCookieJarSqlite, soup_cookie_jar_sqlite, SOUP_TYPE_COOKIE_JAR_DB) static void soup_cookie_jar_sqlite_init (SoupCookieJarSqlite *sqlite) { } -static void -soup_cookie_jar_sqlite_finalize (GObject *object) -{ - SoupCookieJarSqlitePrivate *priv = - SOUP_COOKIE_JAR_SQLITE_GET_PRIVATE (object); - - g_free (priv->filename); - - if (priv->db) - sqlite3_close (priv->db); - - G_OBJECT_CLASS (soup_cookie_jar_sqlite_parent_class)->finalize (object); -} - -static void -soup_cookie_jar_sqlite_set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - SoupCookieJarSqlitePrivate *priv = - SOUP_COOKIE_JAR_SQLITE_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_FILENAME: - priv->filename = g_value_dup_string (value); - load (SOUP_COOKIE_JAR (object)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -soup_cookie_jar_sqlite_get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - SoupCookieJarSqlitePrivate *priv = - SOUP_COOKIE_JAR_SQLITE_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_FILENAME: - g_value_set_string (value, priv->filename); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/** - * soup_cookie_jar_sqlite_new: - * @filename: the filename to read to/write from, or %NULL - * @read_only: %TRUE if @filename is read-only - * - * Creates a #SoupCookieJarSqlite. - * - * @filename will be read in at startup to create an initial set of - * cookies. If @read_only is %FALSE, then the non-session cookies will - * be written to @filename when the 'changed' signal is emitted from - * the jar. (If @read_only is %TRUE, then the cookie jar will only be - * used for this session, and changes made to it will be lost when the - * jar is destroyed.) - * - * Return value: the new #SoupCookieJar - * - * Since: 2.26 - **/ SoupCookieJar * soup_cookie_jar_sqlite_new (const char *filename, gboolean read_only) { @@ -128,208 +43,7 @@ soup_cookie_jar_sqlite_new (const char *filename, gboolean read_only) NULL); } -#define QUERY_ALL "SELECT id, name, value, host, path, expiry, lastAccessed, isSecure, isHttpOnly FROM moz_cookies;" -#define CREATE_TABLE "CREATE TABLE moz_cookies (id INTEGER PRIMARY KEY, name TEXT, value TEXT, host TEXT, path TEXT,expiry INTEGER, lastAccessed INTEGER, isSecure INTEGER, isHttpOnly INTEGER)" -#define QUERY_INSERT "INSERT INTO moz_cookies VALUES(NULL, %Q, %Q, %Q, %Q, %d, NULL, %d, %d);" -#define QUERY_DELETE "DELETE FROM moz_cookies WHERE name=%Q AND host=%Q;" - -enum { - COL_ID, - COL_NAME, - COL_VALUE, - COL_HOST, - COL_PATH, - COL_EXPIRY, - COL_LAST_ACCESS, - COL_SECURE, - COL_HTTP_ONLY, - N_COL, -}; - -static int -callback (void *data, int argc, char **argv, char **colname) -{ - SoupCookie *cookie = NULL; - SoupCookieJar *jar = SOUP_COOKIE_JAR (data); - - char *name, *value, *host, *path; - gulong expire_time; - time_t now; - int max_age; - gboolean http_only = FALSE, secure = FALSE; - - now = time (NULL); - - name = argv[COL_NAME]; - value = argv[COL_VALUE]; - host = argv[COL_HOST]; - path = argv[COL_PATH]; - expire_time = strtoul (argv[COL_EXPIRY], NULL, 10); - - if (now >= expire_time) - return 0; - max_age = (expire_time - now <= G_MAXINT ? expire_time - now : G_MAXINT); - - http_only = (g_strcmp0 (argv[COL_HTTP_ONLY], "1") == 0); - secure = (g_strcmp0 (argv[COL_SECURE], "1") == 0); - - cookie = soup_cookie_new (name, value, host, path, max_age); - - if (secure) - soup_cookie_set_secure (cookie, TRUE); - if (http_only) - soup_cookie_set_http_only (cookie, TRUE); - - soup_cookie_jar_add_cookie (jar, cookie); - - return 0; -} - -static void -try_create_table (sqlite3 *db) -{ - char *error = NULL; - - if (sqlite3_exec (db, CREATE_TABLE, NULL, NULL, &error)) { - g_warning ("Failed to execute query: %s", error); - sqlite3_free (error); - } -} - -static void -exec_query_with_try_create_table (sqlite3 *db, - const char *sql, - int (*callback)(void*,int,char**,char**), - void *argument) -{ - char *error = NULL; - gboolean try_create = TRUE; - -try_exec: - if (sqlite3_exec (db, sql, callback, argument, &error)) { - if (try_create) { - try_create = FALSE; - try_create_table (db); - sqlite3_free (error); - error = NULL; - goto try_exec; - } else { - g_warning ("Failed to execute query: %s", error); - sqlite3_free (error); - } - } -} - -/* Follows sqlite3 convention; returns TRUE on error */ -static gboolean -open_db (SoupCookieJar *jar) -{ - SoupCookieJarSqlitePrivate *priv = - SOUP_COOKIE_JAR_SQLITE_GET_PRIVATE (jar); - - char *error = NULL; - - if (sqlite3_open (priv->filename, &priv->db)) { - sqlite3_close (priv->db); - priv->db = NULL; - g_warning ("Can't open %s", priv->filename); - return TRUE; - } - - if (sqlite3_exec (priv->db, "PRAGMA synchronous = OFF; PRAGMA secure_delete = 1;", NULL, NULL, &error)) { - g_warning ("Failed to execute query: %s", error); - sqlite3_free (error); - } - - return FALSE; -} - -static void -load (SoupCookieJar *jar) -{ - SoupCookieJarSqlitePrivate *priv = - SOUP_COOKIE_JAR_SQLITE_GET_PRIVATE (jar); - - if (priv->db == NULL) { - if (open_db (jar)) - return; - } - - exec_query_with_try_create_table (priv->db, QUERY_ALL, callback, jar); -} - -static void -soup_cookie_jar_sqlite_changed (SoupCookieJar *jar, - SoupCookie *old_cookie, - SoupCookie *new_cookie) -{ - SoupCookieJarSqlitePrivate *priv = - SOUP_COOKIE_JAR_SQLITE_GET_PRIVATE (jar); - char *query; - - if (priv->db == NULL) { - if (open_db (jar)) - return; - } - - if (old_cookie) { - query = sqlite3_mprintf (QUERY_DELETE, - old_cookie->name, - old_cookie->domain); - exec_query_with_try_create_table (priv->db, query, NULL, NULL); - sqlite3_free (query); - } - - if (new_cookie && new_cookie->expires) { - gulong expires; - - expires = (gulong)soup_date_to_time_t (new_cookie->expires); - query = sqlite3_mprintf (QUERY_INSERT, - new_cookie->name, - new_cookie->value, - new_cookie->domain, - new_cookie->path, - expires, - new_cookie->secure, - new_cookie->http_only); - exec_query_with_try_create_table (priv->db, query, NULL, NULL); - sqlite3_free (query); - } -} - -static gboolean -soup_cookie_jar_sqlite_is_persistent (SoupCookieJar *jar) -{ - return TRUE; -} - static void soup_cookie_jar_sqlite_class_init (SoupCookieJarSqliteClass *sqlite_class) { - SoupCookieJarClass *cookie_jar_class = - SOUP_COOKIE_JAR_CLASS (sqlite_class); - GObjectClass *object_class = G_OBJECT_CLASS (sqlite_class); - - g_type_class_add_private (sqlite_class, sizeof (SoupCookieJarSqlitePrivate)); - - cookie_jar_class->is_persistent = soup_cookie_jar_sqlite_is_persistent; - cookie_jar_class->changed = soup_cookie_jar_sqlite_changed; - - object_class->finalize = soup_cookie_jar_sqlite_finalize; - object_class->set_property = soup_cookie_jar_sqlite_set_property; - object_class->get_property = soup_cookie_jar_sqlite_get_property; - - /** - * SOUP_COOKIE_JAR_SQLITE_FILENAME: - * - * Alias for the #SoupCookieJarSqlite:filename property. (The - * cookie-storage filename.) - **/ - g_object_class_install_property ( - object_class, PROP_FILENAME, - g_param_spec_string (SOUP_COOKIE_JAR_SQLITE_FILENAME, - "Filename", - "Cookie-storage filename", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } diff --git a/libsoup/soup-cookie-jar-sqlite.h b/libsoup/soup-cookie-jar-sqlite.h index 97cdf33..adc2786 100644 --- a/libsoup/soup-cookie-jar-sqlite.h +++ b/libsoup/soup-cookie-jar-sqlite.h @@ -6,7 +6,7 @@ #ifndef SOUP_COOKIE_JAR_SQLITE_H #define SOUP_COOKIE_JAR_SQLITE_H 1 -#include +#include G_BEGIN_DECLS @@ -18,26 +18,23 @@ G_BEGIN_DECLS #define SOUP_COOKIE_JAR_SQLITE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_COOKIE_JAR_SQLITE, SoupCookieJarSqliteClass)) typedef struct { - SoupCookieJar parent; + SoupCookieJarDB parent; } SoupCookieJarSqlite; typedef struct { - SoupCookieJarClass parent_class; + SoupCookieJarDBClass parent_class; - /* Padding for future expansion */ - void (*_libsoup_reserved1) (void); - void (*_libsoup_reserved2) (void); - void (*_libsoup_reserved3) (void); - void (*_libsoup_reserved4) (void); } SoupCookieJarSqliteClass; #define SOUP_COOKIE_JAR_SQLITE_FILENAME "filename" SOUP_AVAILABLE_IN_2_26 +SOUP_DEPRECATED_IN_2_42_FOR(soup_cookie_jar_db_get_type) GType soup_cookie_jar_sqlite_get_type (void); SOUP_AVAILABLE_IN_2_26 +SOUP_DEPRECATED_IN_2_42_FOR(soup_cookie_jar_db_new) SoupCookieJar *soup_cookie_jar_sqlite_new (const char *filename, gboolean read_only); diff --git a/libsoup/soup.h b/libsoup/soup.h index b1b7472..fd836fe 100644 --- a/libsoup/soup.h +++ b/libsoup/soup.h @@ -20,6 +20,7 @@ extern "C" { #include #include #include +#include #include #include #include -- 2.7.4