diff --git a/katze/katze-http-cookies.c b/katze/katze-http-cookies.c index 9a38d741..951a1c96 100644 --- a/katze/katze-http-cookies.c +++ b/katze/katze-http-cookies.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2008-2009 Christian Dywan + Copyright (C) 2008-2010 Christian Dywan This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -27,6 +27,10 @@ struct _KatzeHttpCookies { GObject parent_instance; + gchar* filename; + SoupCookieJar* jar; + guint timeout; + guint counter; }; struct _KatzeHttpCookiesClass @@ -124,11 +128,12 @@ cookie_jar_load (SoupCookieJar* jar, gchar* line; gchar* p; gsize length = 0; - time_t now = time (NULL); + time_t now; if (!g_file_get_contents (filename, &contents, &length, NULL)) return; + now = time (NULL); line = contents; for (p = contents; *p; p++) { @@ -152,8 +157,6 @@ cookie_jar_load (SoupCookieJar* jar, static gboolean write_cookie (FILE *out, SoupCookie *cookie) { - fseek (out, 0, SEEK_END); - if (fprintf (out, "%s%s\t%s\t%s\t%s\t%lu\t%s\t%s\n", cookie->http_only ? "#HttpOnly_" : "", cookie->domain, @@ -167,83 +170,72 @@ write_cookie (FILE *out, SoupCookie *cookie) return TRUE; } -/* Cookie jar saving to Mozilla format - Copyright (C) 2008 Xan Lopez - Copyright (C) 2008 Dan Winship - Copied from libSoup 2.24, coding style preserved */ -static void -delete_cookie (const char *filename, SoupCookie *cookie) +static gboolean +katze_http_cookies_update_jar (KatzeHttpCookies* http_cookies) { - char *contents = NULL, *line, *p; - gsize length = 0; - gint fn = 0; - FILE *f; - gchar* temporary_filename = NULL; - SoupCookie *c; - time_t now = time (NULL); + gint fn = 0; + FILE* f = NULL; + gchar* temporary_filename = NULL; + GSList* cookies; - if (!g_file_get_contents (filename, &contents, &length, NULL)) - return; + http_cookies->timeout = 0; - fn = g_file_open_tmp (NULL, &temporary_filename, NULL); - if (fn == -1) - goto failed; - f = fopen (temporary_filename, "w"); - if (!f) - goto failed; + temporary_filename = g_strconcat (http_cookies->filename, ".XXXXXX", NULL); + if ((fn = g_mkstemp (temporary_filename)) == -1) + goto failed; + if (!((f = fdopen (fn, "wb")))) + goto failed; - line = contents; - for (p = contents; *p; p++) { - /* \r\n comes out as an extra empty line and gets ignored */ - if (*p == '\r' || *p == '\n') { - *p = '\0'; - c = parse_cookie (line, now); - if (!c) - continue; - if (!soup_cookie_equal (cookie, c)) - write_cookie (f, c); - line = p + 1; - soup_cookie_free (c); - } - } - c = parse_cookie (line, now); - if (c) { - if (!soup_cookie_equal (cookie, c)) - if (!write_cookie (f, c)) - goto failed; - soup_cookie_free (c); - } + cookies = soup_cookie_jar_all_cookies (http_cookies->jar); + for (; cookies != NULL; cookies = g_slist_next (cookies)) + { + SoupCookie* cookie = cookies->data; + if (cookie->expires && !soup_date_is_past (cookie->expires)) + write_cookie (f, cookie); + soup_cookie_free (cookie); + } + g_slist_free (cookies); - if (!fclose (f)) - goto failed; + if (fclose (f) != 0) + { + f = NULL; + goto failed; + } + f = NULL; + + if (g_rename (temporary_filename, http_cookies->filename) == -1) + goto failed; + g_free (temporary_filename); + + if (g_getenv ("MIDORI_COOKIES_DEBUG") != NULL) + { + g_print ("KatzeHttpCookies: %d cookies changed\n", http_cookies->counter); + http_cookies->counter = 0; + } + return FALSE; - g_free (contents); - close (fn); - g_rename (temporary_filename, filename); - g_free (temporary_filename); - return; failed: - g_free (contents); - close (fn); - g_unlink (temporary_filename); - g_free (temporary_filename); + if (f) + fclose (f); + g_unlink (temporary_filename); + g_free (temporary_filename); + if (g_getenv ("MIDORI_COOKIES_DEBUG") != NULL) + g_print ("KatzeHttpCookies: Failed to write '%s'\n", + http_cookies->filename); + return FALSE; } -/* Cookie jar saving to Mozilla format - Copyright (C) 2008 Xan Lopez - Copyright (C) 2008 Dan Winship - Mostly copied from libSoup 2.24, coding style adjusted */ static void -cookie_jar_changed_cb (SoupCookieJar* jar, - SoupCookie* old_cookie, - SoupCookie* new_cookie, - gchar* filename) +katze_http_cookies_jar_changed_cb (SoupCookieJar* jar, + SoupCookie* old_cookie, + SoupCookie* new_cookie, + KatzeHttpCookies* http_cookies) { GObject* settings; guint accept_cookies; if (old_cookie) - delete_cookie (filename, old_cookie); + soup_cookie_set_max_age (old_cookie, 0); if (new_cookie) { @@ -251,7 +243,7 @@ cookie_jar_changed_cb (SoupCookieJar* jar, accept_cookies = katze_object_get_enum (settings, "accept-cookies"); if (accept_cookies == 2 /* MIDORI_ACCEPT_COOKIES_NONE */) { - soup_cookie_jar_delete_cookie (jar, new_cookie); + soup_cookie_set_max_age (new_cookie, 0); } else if (accept_cookies == 1 /* MIDORI_ACCEPT_COOKIES_SESSION */ && new_cookie->expires) @@ -263,18 +255,11 @@ cookie_jar_changed_cb (SoupCookieJar* jar, gint age = katze_object_get_int (settings, "maximum-cookie-age"); if (age > 0) { - FILE *out; SoupDate* max_date = soup_date_new_from_now ( age * SOUP_COOKIE_MAX_AGE_ONE_DAY); if (soup_date_to_time_t (new_cookie->expires) > soup_date_to_time_t (max_date)) soup_cookie_set_expires (new_cookie, max_date); - - if (!(out = fopen (filename, "a"))) - return; - write_cookie (out, new_cookie); - if (fclose (out) != 0) - return; } else { @@ -284,23 +269,28 @@ cookie_jar_changed_cb (SoupCookieJar* jar, } } } + + if (g_getenv ("MIDORI_COOKIES_DEBUG") != NULL) + http_cookies->counter++; + + if (!http_cookies->timeout && (old_cookie || new_cookie->expires)) + http_cookies->timeout = g_timeout_add_seconds (5, + (GSourceFunc)katze_http_cookies_update_jar, http_cookies); } static void katze_http_cookies_attach (SoupSessionFeature* feature, SoupSession* session) { - SoupSessionFeature* cookie_jar; - gchar* filename; - - cookie_jar = soup_session_get_feature (session, SOUP_TYPE_COOKIE_JAR); - g_return_if_fail (cookie_jar != NULL); - filename = g_object_get_data (G_OBJECT (feature), "filename"); - g_return_if_fail (filename != NULL); - cookie_jar_load (SOUP_COOKIE_JAR (cookie_jar), filename); - g_signal_connect_data (cookie_jar, "changed", - G_CALLBACK (cookie_jar_changed_cb), g_strdup (filename), - (GClosureNotify)g_free, 0); + KatzeHttpCookies* http_cookies = (KatzeHttpCookies*)feature; + SoupSessionFeature* jar = soup_session_get_feature (session, SOUP_TYPE_COOKIE_JAR); + g_return_if_fail (jar != NULL); + http_cookies->filename = g_object_get_data (G_OBJECT (feature), "filename"); + g_return_if_fail (http_cookies->filename != NULL); + http_cookies->jar = g_object_ref (jar); + cookie_jar_load (http_cookies->jar, http_cookies->filename); + g_signal_connect (jar, "changed", + G_CALLBACK (katze_http_cookies_jar_changed_cb), feature); } @@ -308,7 +298,11 @@ static void katze_http_cookies_detach (SoupSessionFeature* feature, SoupSession* session) { - /* Nothing to do. */ + KatzeHttpCookies* http_cookies = (KatzeHttpCookies*)feature; + if (http_cookies->timeout) + katze_http_cookies_update_jar (http_cookies); + katze_assign (http_cookies->filename, NULL); + katze_object_assign (http_cookies->jar, NULL); } static void @@ -319,14 +313,24 @@ katze_http_cookies_session_feature_iface_init (SoupSessionFeatureInterface *ifac iface->detach = katze_http_cookies_detach; } +static void +katze_http_cookies_finalize (GObject* object) +{ + katze_http_cookies_detach ((SoupSessionFeature*)object, NULL); +} + static void katze_http_cookies_class_init (KatzeHttpCookiesClass* class) { - /* Nothing to do. */ + GObjectClass* gobject_class = (GObjectClass*)class; + gobject_class->finalize = katze_http_cookies_finalize; } static void katze_http_cookies_init (KatzeHttpCookies* http_cookies) { - /* Nothing to do. */ + http_cookies->filename = NULL; + http_cookies->jar = NULL; + http_cookies->timeout = 0; + http_cookies->counter = 0; } diff --git a/midori/main.c b/midori/main.c index 62c1b002..7638e078 100644 --- a/midori/main.c +++ b/midori/main.c @@ -1004,14 +1004,10 @@ midori_create_diagnostic_dialog (MidoriWebSettings* settings, static gboolean midori_load_cookie_jar (gpointer data) { - MidoriWebSettings* settings = MIDORI_WEB_SETTINGS (data); - SoupSession* webkit_session; - SoupCookieJar* jar; - - webkit_session = webkit_get_default_session (); - jar = soup_cookie_jar_new (); - g_object_set_data (G_OBJECT (jar), "midori-settings", settings); - midori_soup_session_prepare (webkit_session, jar, settings); + SoupSession* session = webkit_get_default_session (); + SoupCookieJar* jar = soup_cookie_jar_new (); + g_object_set_data (G_OBJECT (jar), "midori-settings", data); + midori_soup_session_prepare (session, jar, MIDORI_WEB_SETTINGS (data)); g_object_unref (jar); return FALSE; @@ -2114,6 +2110,9 @@ main (int argc, settings = katze_object_get_object (app, "settings"); g_object_get (settings, "maximum-history-age", &max_history_age, NULL); midori_history_terminate (db, max_history_age); + /* Removing KatzeHttpCookies makes it save outstanding changes */ + soup_session_remove_feature_by_type (webkit_get_default_session (), + KATZE_TYPE_HTTP_COOKIES); /* Clear data on quit, according to the Clear private data dialog */ g_object_get (settings, "clear-private-data", &clear_prefs, NULL);