Revise cookie saving based on a timeout
The variable MIDORI_COOKIES_DEBUG can be used to print the number of updated cookies when they're written. The temporary cookie file is written in the same location now as moving across filesystems may not work. Saving when Midori is quit is enforced.
This commit is contained in:
parent
cf18d418de
commit
392fa7fc85
2 changed files with 99 additions and 96 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2008-2009 Christian Dywan <christian@twotoasts.de>
|
Copyright (C) 2008-2010 Christian Dywan <christian@twotoasts.de>
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -27,6 +27,10 @@
|
||||||
struct _KatzeHttpCookies
|
struct _KatzeHttpCookies
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
|
gchar* filename;
|
||||||
|
SoupCookieJar* jar;
|
||||||
|
guint timeout;
|
||||||
|
guint counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _KatzeHttpCookiesClass
|
struct _KatzeHttpCookiesClass
|
||||||
|
@ -124,11 +128,12 @@ cookie_jar_load (SoupCookieJar* jar,
|
||||||
gchar* line;
|
gchar* line;
|
||||||
gchar* p;
|
gchar* p;
|
||||||
gsize length = 0;
|
gsize length = 0;
|
||||||
time_t now = time (NULL);
|
time_t now;
|
||||||
|
|
||||||
if (!g_file_get_contents (filename, &contents, &length, NULL))
|
if (!g_file_get_contents (filename, &contents, &length, NULL))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
now = time (NULL);
|
||||||
line = contents;
|
line = contents;
|
||||||
for (p = contents; *p; p++)
|
for (p = contents; *p; p++)
|
||||||
{
|
{
|
||||||
|
@ -152,8 +157,6 @@ cookie_jar_load (SoupCookieJar* jar,
|
||||||
static gboolean
|
static gboolean
|
||||||
write_cookie (FILE *out, SoupCookie *cookie)
|
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",
|
if (fprintf (out, "%s%s\t%s\t%s\t%s\t%lu\t%s\t%s\n",
|
||||||
cookie->http_only ? "#HttpOnly_" : "",
|
cookie->http_only ? "#HttpOnly_" : "",
|
||||||
cookie->domain,
|
cookie->domain,
|
||||||
|
@ -167,83 +170,72 @@ write_cookie (FILE *out, SoupCookie *cookie)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cookie jar saving to Mozilla format
|
static gboolean
|
||||||
Copyright (C) 2008 Xan Lopez <xan@gnome.org>
|
katze_http_cookies_update_jar (KatzeHttpCookies* http_cookies)
|
||||||
Copyright (C) 2008 Dan Winship <danw@gnome.org>
|
|
||||||
Copied from libSoup 2.24, coding style preserved */
|
|
||||||
static void
|
|
||||||
delete_cookie (const char *filename, SoupCookie *cookie)
|
|
||||||
{
|
{
|
||||||
char *contents = NULL, *line, *p;
|
|
||||||
gsize length = 0;
|
|
||||||
gint fn = 0;
|
gint fn = 0;
|
||||||
FILE *f;
|
FILE* f = NULL;
|
||||||
gchar* temporary_filename = NULL;
|
gchar* temporary_filename = NULL;
|
||||||
SoupCookie *c;
|
GSList* cookies;
|
||||||
time_t now = time (NULL);
|
|
||||||
|
|
||||||
if (!g_file_get_contents (filename, &contents, &length, NULL))
|
http_cookies->timeout = 0;
|
||||||
return;
|
|
||||||
|
|
||||||
fn = g_file_open_tmp (NULL, &temporary_filename, NULL);
|
temporary_filename = g_strconcat (http_cookies->filename, ".XXXXXX", NULL);
|
||||||
if (fn == -1)
|
if ((fn = g_mkstemp (temporary_filename)) == -1)
|
||||||
goto failed;
|
goto failed;
|
||||||
f = fopen (temporary_filename, "w");
|
if (!((f = fdopen (fn, "wb"))))
|
||||||
if (!f)
|
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
line = contents;
|
cookies = soup_cookie_jar_all_cookies (http_cookies->jar);
|
||||||
for (p = contents; *p; p++) {
|
for (; cookies != NULL; cookies = g_slist_next (cookies))
|
||||||
/* \r\n comes out as an extra empty line and gets ignored */
|
{
|
||||||
if (*p == '\r' || *p == '\n') {
|
SoupCookie* cookie = cookies->data;
|
||||||
*p = '\0';
|
if (cookie->expires && !soup_date_is_past (cookie->expires))
|
||||||
c = parse_cookie (line, now);
|
write_cookie (f, cookie);
|
||||||
if (!c)
|
soup_cookie_free (cookie);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
g_slist_free (cookies);
|
||||||
|
|
||||||
if (!fclose (f))
|
if (fclose (f) != 0)
|
||||||
|
{
|
||||||
|
f = NULL;
|
||||||
goto failed;
|
goto failed;
|
||||||
|
}
|
||||||
|
f = NULL;
|
||||||
|
|
||||||
g_free (contents);
|
if (g_rename (temporary_filename, http_cookies->filename) == -1)
|
||||||
close (fn);
|
goto failed;
|
||||||
g_rename (temporary_filename, filename);
|
|
||||||
g_free (temporary_filename);
|
g_free (temporary_filename);
|
||||||
return;
|
|
||||||
|
if (g_getenv ("MIDORI_COOKIES_DEBUG") != NULL)
|
||||||
|
{
|
||||||
|
g_print ("KatzeHttpCookies: %d cookies changed\n", http_cookies->counter);
|
||||||
|
http_cookies->counter = 0;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
g_free (contents);
|
if (f)
|
||||||
close (fn);
|
fclose (f);
|
||||||
g_unlink (temporary_filename);
|
g_unlink (temporary_filename);
|
||||||
g_free (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 <xan@gnome.org>
|
|
||||||
Copyright (C) 2008 Dan Winship <danw@gnome.org>
|
|
||||||
Mostly copied from libSoup 2.24, coding style adjusted */
|
|
||||||
static void
|
static void
|
||||||
cookie_jar_changed_cb (SoupCookieJar* jar,
|
katze_http_cookies_jar_changed_cb (SoupCookieJar* jar,
|
||||||
SoupCookie* old_cookie,
|
SoupCookie* old_cookie,
|
||||||
SoupCookie* new_cookie,
|
SoupCookie* new_cookie,
|
||||||
gchar* filename)
|
KatzeHttpCookies* http_cookies)
|
||||||
{
|
{
|
||||||
GObject* settings;
|
GObject* settings;
|
||||||
guint accept_cookies;
|
guint accept_cookies;
|
||||||
|
|
||||||
if (old_cookie)
|
if (old_cookie)
|
||||||
delete_cookie (filename, old_cookie);
|
soup_cookie_set_max_age (old_cookie, 0);
|
||||||
|
|
||||||
if (new_cookie)
|
if (new_cookie)
|
||||||
{
|
{
|
||||||
|
@ -251,7 +243,7 @@ cookie_jar_changed_cb (SoupCookieJar* jar,
|
||||||
accept_cookies = katze_object_get_enum (settings, "accept-cookies");
|
accept_cookies = katze_object_get_enum (settings, "accept-cookies");
|
||||||
if (accept_cookies == 2 /* MIDORI_ACCEPT_COOKIES_NONE */)
|
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 */
|
else if (accept_cookies == 1 /* MIDORI_ACCEPT_COOKIES_SESSION */
|
||||||
&& new_cookie->expires)
|
&& new_cookie->expires)
|
||||||
|
@ -263,18 +255,11 @@ cookie_jar_changed_cb (SoupCookieJar* jar,
|
||||||
gint age = katze_object_get_int (settings, "maximum-cookie-age");
|
gint age = katze_object_get_int (settings, "maximum-cookie-age");
|
||||||
if (age > 0)
|
if (age > 0)
|
||||||
{
|
{
|
||||||
FILE *out;
|
|
||||||
SoupDate* max_date = soup_date_new_from_now (
|
SoupDate* max_date = soup_date_new_from_now (
|
||||||
age * SOUP_COOKIE_MAX_AGE_ONE_DAY);
|
age * SOUP_COOKIE_MAX_AGE_ONE_DAY);
|
||||||
if (soup_date_to_time_t (new_cookie->expires)
|
if (soup_date_to_time_t (new_cookie->expires)
|
||||||
> soup_date_to_time_t (max_date))
|
> soup_date_to_time_t (max_date))
|
||||||
soup_cookie_set_expires (new_cookie, 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
|
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
|
static void
|
||||||
katze_http_cookies_attach (SoupSessionFeature* feature,
|
katze_http_cookies_attach (SoupSessionFeature* feature,
|
||||||
SoupSession* session)
|
SoupSession* session)
|
||||||
{
|
{
|
||||||
SoupSessionFeature* cookie_jar;
|
KatzeHttpCookies* http_cookies = (KatzeHttpCookies*)feature;
|
||||||
gchar* filename;
|
SoupSessionFeature* jar = soup_session_get_feature (session, SOUP_TYPE_COOKIE_JAR);
|
||||||
|
g_return_if_fail (jar != NULL);
|
||||||
cookie_jar = soup_session_get_feature (session, SOUP_TYPE_COOKIE_JAR);
|
http_cookies->filename = g_object_get_data (G_OBJECT (feature), "filename");
|
||||||
g_return_if_fail (cookie_jar != NULL);
|
g_return_if_fail (http_cookies->filename != NULL);
|
||||||
filename = g_object_get_data (G_OBJECT (feature), "filename");
|
http_cookies->jar = g_object_ref (jar);
|
||||||
g_return_if_fail (filename != NULL);
|
cookie_jar_load (http_cookies->jar, http_cookies->filename);
|
||||||
cookie_jar_load (SOUP_COOKIE_JAR (cookie_jar), filename);
|
g_signal_connect (jar, "changed",
|
||||||
g_signal_connect_data (cookie_jar, "changed",
|
G_CALLBACK (katze_http_cookies_jar_changed_cb), feature);
|
||||||
G_CALLBACK (cookie_jar_changed_cb), g_strdup (filename),
|
|
||||||
(GClosureNotify)g_free, 0);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,7 +298,11 @@ static void
|
||||||
katze_http_cookies_detach (SoupSessionFeature* feature,
|
katze_http_cookies_detach (SoupSessionFeature* feature,
|
||||||
SoupSession* session)
|
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
|
static void
|
||||||
|
@ -319,14 +313,24 @@ katze_http_cookies_session_feature_iface_init (SoupSessionFeatureInterface *ifac
|
||||||
iface->detach = katze_http_cookies_detach;
|
iface->detach = katze_http_cookies_detach;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
katze_http_cookies_finalize (GObject* object)
|
||||||
|
{
|
||||||
|
katze_http_cookies_detach ((SoupSessionFeature*)object, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
katze_http_cookies_class_init (KatzeHttpCookiesClass* class)
|
katze_http_cookies_class_init (KatzeHttpCookiesClass* class)
|
||||||
{
|
{
|
||||||
/* Nothing to do. */
|
GObjectClass* gobject_class = (GObjectClass*)class;
|
||||||
|
gobject_class->finalize = katze_http_cookies_finalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
katze_http_cookies_init (KatzeHttpCookies* http_cookies)
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1004,14 +1004,10 @@ midori_create_diagnostic_dialog (MidoriWebSettings* settings,
|
||||||
static gboolean
|
static gboolean
|
||||||
midori_load_cookie_jar (gpointer data)
|
midori_load_cookie_jar (gpointer data)
|
||||||
{
|
{
|
||||||
MidoriWebSettings* settings = MIDORI_WEB_SETTINGS (data);
|
SoupSession* session = webkit_get_default_session ();
|
||||||
SoupSession* webkit_session;
|
SoupCookieJar* jar = soup_cookie_jar_new ();
|
||||||
SoupCookieJar* jar;
|
g_object_set_data (G_OBJECT (jar), "midori-settings", data);
|
||||||
|
midori_soup_session_prepare (session, jar, MIDORI_WEB_SETTINGS (data));
|
||||||
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);
|
|
||||||
g_object_unref (jar);
|
g_object_unref (jar);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -2114,6 +2110,9 @@ main (int argc,
|
||||||
settings = katze_object_get_object (app, "settings");
|
settings = katze_object_get_object (app, "settings");
|
||||||
g_object_get (settings, "maximum-history-age", &max_history_age, NULL);
|
g_object_get (settings, "maximum-history-age", &max_history_age, NULL);
|
||||||
midori_history_terminate (db, max_history_age);
|
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 */
|
/* Clear data on quit, according to the Clear private data dialog */
|
||||||
g_object_get (settings, "clear-private-data", &clear_prefs, NULL);
|
g_object_get (settings, "clear-private-data", &clear_prefs, NULL);
|
||||||
|
|
Loading…
Reference in a new issue