[Xfce4-commits] <midori:master> Merged cookie permissions as of 2013-03-08
Christian Dywan
noreply at xfce.org
Sat Mar 23 12:38:01 CET 2013
Updating branch refs/heads/master
to 3de3a71f4fb26c3c77802d5dd25f241cc216245f (commit)
from 7c49465bf169c21918658438d9456bdeef0fe259 (commit)
commit 3de3a71f4fb26c3c77802d5dd25f241cc216245f
Author: Christian Dywan <christian at twotoasts.de>
Date: Sat Mar 23 12:29:55 2013 +0100
Merged cookie permissions as of 2013-03-08
Fixes: https://bugs.launchpad.net/midori/+bug/1139496
Fixes: https://bugs.launchpad.net/midori/+bug/1145197
.../cookie-permission-manager-preferences-window.c | 69 +++-
.../cookie-permissions/cookie-permission-manager.c | 399 +++++++++++++-------
2 files changed, 321 insertions(+), 147 deletions(-)
diff --git a/extensions/cookie-permissions/cookie-permission-manager-preferences-window.c b/extensions/cookie-permissions/cookie-permission-manager-preferences-window.c
index c7ccc5b..33fb2d6 100644
--- a/extensions/cookie-permissions/cookie-permission-manager-preferences-window.c
+++ b/extensions/cookie-permissions/cookie-permission-manager-preferences-window.c
@@ -189,7 +189,7 @@ static void _cookie_permission_manager_preferences_on_add_domain_entry_changed(C
checkAsciiDomain++;
}
- /* If we have not reached the trimmed end of string something must have gone wrong
+ /* If we have not reached the trimmed end of string something must have gone wrong
* and domain entered is invalid. If domain name entered excluding dots is longer
* than 255 character it is also invalid.
*/
@@ -282,21 +282,19 @@ static void _cookie_permission_manager_preferences_window_manager_database_chang
{
CookiePermissionManagerPreferencesWindowPrivate *priv=self->priv;
CookiePermissionManager *manager=COOKIE_PERMISSION_MANAGER(inUserData);
- sqlite3 *database;
+ const gchar *databaseFilename;
/* Close connection to any open database */
if(priv->database) sqlite3_close(priv->database);
priv->database=NULL;
/* Get pointer to new database and open database */
- g_object_get(manager, "database", &database, NULL);
- if(database)
+ g_object_get(manager, "database-filename", &databaseFilename, NULL);
+ if(databaseFilename)
{
- const gchar *databaseFile;
gint success;
- databaseFile=sqlite3_db_filename(database, NULL);
- success=sqlite3_open(databaseFile, &priv->database);
+ success=sqlite3_open(databaseFilename, &priv->database);
if(success!=SQLITE_OK)
{
g_warning(_("Could not open database of extenstion: %s"), sqlite3_errmsg(priv->database));
@@ -465,6 +463,27 @@ void _cookie_permission_manager_preferences_on_delete_all(CookiePermissionManage
_cookie_permission_manager_preferences_window_fill(self);
}
+/* Sorting callbacks */
+static gint _cookie_permission_manager_preferences_sort_string_callback(GtkTreeModel *inModel,
+ GtkTreeIter *inLeft,
+ GtkTreeIter *inRight,
+ gpointer inUserData)
+{
+ gchar *left, *right;
+ gint column=GPOINTER_TO_INT(inUserData);
+ gint result;
+
+ gtk_tree_model_get(inModel, inLeft, column, &left, -1);
+ gtk_tree_model_get(inModel, inRight, column, &right, -1);
+
+ result=g_strcmp0(left, right);
+
+ g_free(left);
+ g_free(right);
+
+ return(result);
+}
+
/* IMPLEMENTATION: GObject */
/* Finalize this object */
@@ -527,16 +546,18 @@ static void cookie_permission_manager_preferences_window_set_property(GObject *i
{
priv->manager=g_object_ref(manager);
- priv->signalManagerChangedDatabaseID=g_signal_connect_swapped(priv->manager,
- "notify::database",
- G_CALLBACK(_cookie_permission_manager_preferences_window_manager_database_changed),
- self);
- priv->signalManagerAskForUnknownPolicyID=g_signal_connect_swapped(priv->manager,
- "notify::ask-for-unknown-policy",
- G_CALLBACK(_cookie_permission_manager_preferences_window_manager_ask_for_unknown_policy_changed),
- self);
-
+ priv->signalManagerChangedDatabaseID=
+ g_signal_connect_swapped(priv->manager,
+ "notify::database-filename",
+ G_CALLBACK(_cookie_permission_manager_preferences_window_manager_database_changed),
+ self);
_cookie_permission_manager_preferences_window_manager_database_changed(self, NULL, priv->manager);
+
+ priv->signalManagerAskForUnknownPolicyID=
+ g_signal_connect_swapped(priv->manager,
+ "notify::ask-for-unknown-policy",
+ G_CALLBACK(_cookie_permission_manager_preferences_window_manager_ask_for_unknown_policy_changed),
+ self);
_cookie_permission_manager_preferences_window_manager_ask_for_unknown_policy_changed(self, NULL, priv->manager);
}
break;
@@ -598,6 +619,7 @@ static void cookie_permission_manager_preferences_window_class_init(CookiePermis
static void cookie_permission_manager_preferences_window_init(CookiePermissionManagerPreferencesWindow *self)
{
CookiePermissionManagerPreferencesWindowPrivate *priv;
+ GtkTreeSortable *sortableList;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
GtkWidget *widget;
@@ -654,6 +676,19 @@ static void cookie_permission_manager_preferences_window_init(CookiePermissionMa
G_TYPE_STRING, /* DOMAIN_COLUMN */
G_TYPE_STRING /* POLICY_COLUMN */);
+ sortableList=GTK_TREE_SORTABLE(priv->listStore);
+ gtk_tree_sortable_set_sort_func(sortableList,
+ DOMAIN_COLUMN,
+ (GtkTreeIterCompareFunc)_cookie_permission_manager_preferences_sort_string_callback,
+ GINT_TO_POINTER(DOMAIN_COLUMN),
+ NULL);
+ gtk_tree_sortable_set_sort_func(sortableList,
+ POLICY_COLUMN,
+ (GtkTreeIterCompareFunc)_cookie_permission_manager_preferences_sort_string_callback,
+ GINT_TO_POINTER(POLICY_COLUMN),
+ NULL);
+ gtk_tree_sortable_set_sort_column_id(sortableList, DOMAIN_COLUMN, GTK_SORT_ASCENDING);
+
/* Set up domain addition widgets */
#ifdef HAVE_GTK3
hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
@@ -706,6 +741,7 @@ static void cookie_permission_manager_preferences_window_init(CookiePermissionMa
renderer,
"text", DOMAIN_COLUMN,
NULL);
+ gtk_tree_view_column_set_sort_column_id(column, DOMAIN_COLUMN);
gtk_tree_view_append_column(GTK_TREE_VIEW(priv->list), column);
renderer=gtk_cell_renderer_text_new();
@@ -713,6 +749,7 @@ static void cookie_permission_manager_preferences_window_init(CookiePermissionMa
renderer,
"text", POLICY_COLUMN,
NULL);
+ gtk_tree_view_column_set_sort_column_id(column, POLICY_COLUMN);
gtk_tree_view_append_column(GTK_TREE_VIEW(priv->list), column);
scrolled=gtk_scrolled_window_new(NULL, NULL);
diff --git a/extensions/cookie-permissions/cookie-permission-manager.c b/extensions/cookie-permissions/cookie-permission-manager.c
index 84f99af..2fca15c 100644
--- a/extensions/cookie-permissions/cookie-permission-manager.c
+++ b/extensions/cookie-permissions/cookie-permission-manager.c
@@ -13,6 +13,9 @@
#include <errno.h>
+/* Remove next line if we found a way to show details in infobar */
+#define NO_INFOBAR_DETAILS
+
/* Define this class in GObject system */
G_DEFINE_TYPE(CookiePermissionManager,
cookie_permission_manager,
@@ -27,9 +30,9 @@ enum
PROP_APPLICATION,
PROP_DATABASE,
+ PROP_DATABASE_FILENAME,
PROP_ASK_FOR_UNKNOWN_POLICY,
-
PROP_LAST
};
@@ -45,12 +48,9 @@ struct _CookiePermissionManagerPrivate
MidoriExtension *extension;
MidoriApp *application;
sqlite3 *database;
+ gchar *databaseFilename;
gboolean askForUnknownPolicy;
- /* Session related */
- void(*oldRequestQueued)(SoupSessionFeature *inFeature, SoupSession *inSession, SoupMessage *inMessage);
- void(*oldRequestUnqueued)(SoupSessionFeature *inFeature, SoupSession *inSession, SoupMessage *inMessage);
-
/* Cookie jar related */
SoupSession *session;
SoupCookieJar *cookieJar;
@@ -68,6 +68,14 @@ enum
N_COLUMN
};
+struct _CookiePermissionManagerModalInfobar
+{
+ GMainLoop *mainLoop;
+ gint response;
+};
+
+typedef struct _CookiePermissionManagerModalInfobar CookiePermissionManagerModalInfobar;
+
/* IMPLEMENTATION: Private variables and methods */
/* Show common error dialog */
@@ -105,7 +113,6 @@ static void _cookie_permission_manager_open_database(CookiePermissionManager *se
{
CookiePermissionManagerPrivate *priv=self->priv;
const gchar *configDir;
- gchar *databaseFile;
gchar *error=NULL;
gint success;
sqlite3_stmt *statement=NULL;
@@ -113,9 +120,14 @@ static void _cookie_permission_manager_open_database(CookiePermissionManager *se
/* Close any open database */
if(priv->database)
{
+ g_free(priv->databaseFilename);
+ priv->databaseFilename=NULL;
+
sqlite3_close(priv->database);
priv->database=NULL;
+
g_object_notify_by_pspec(G_OBJECT(self), CookiePermissionManagerProperties[PROP_DATABASE]);
+ g_object_notify_by_pspec(G_OBJECT(self), CookiePermissionManagerProperties[PROP_DATABASE_FILENAME]);
}
/* Build path to database file */
@@ -127,7 +139,7 @@ static void _cookie_permission_manager_open_database(CookiePermissionManager *se
_cookie_permission_manager_error(self, _("Could not get path to configuration of extension."));
return;
}
-
+
if(katze_mkdir_with_parents(configDir, 0700))
{
g_warning(_("Could not create configuration folder for extension: %s"), g_strerror(errno));
@@ -137,13 +149,15 @@ static void _cookie_permission_manager_open_database(CookiePermissionManager *se
}
/* Open database */
- databaseFile=g_build_filename(configDir, COOKIE_PERMISSION_DATABASE, NULL);
- success=sqlite3_open(databaseFile, &priv->database);
- g_free(databaseFile);
+ priv->databaseFilename=g_build_filename(configDir, COOKIE_PERMISSION_DATABASE, NULL);
+ success=sqlite3_open(priv->databaseFilename, &priv->database);
if(success!=SQLITE_OK)
{
g_warning(_("Could not open database of extenstion: %s"), sqlite3_errmsg(priv->database));
+ g_free(priv->databaseFilename);
+ priv->databaseFilename=NULL;
+
if(priv->database) sqlite3_close(priv->database);
priv->database=NULL;
@@ -188,6 +202,9 @@ static void _cookie_permission_manager_open_database(CookiePermissionManager *se
sqlite3_free(error);
}
+ g_free(priv->databaseFilename);
+ priv->databaseFilename=NULL;
+
sqlite3_close(priv->database);
priv->database=NULL;
return;
@@ -237,6 +254,7 @@ static void _cookie_permission_manager_open_database(CookiePermissionManager *se
sqlite3_finalize(statement);
g_object_notify_by_pspec(G_OBJECT(self), CookiePermissionManagerProperties[PROP_DATABASE]);
+ g_object_notify_by_pspec(G_OBJECT(self), CookiePermissionManagerProperties[PROP_DATABASE_FILENAME]);
}
/* Get policy for cookies from domain */
@@ -361,6 +379,8 @@ static GSList* _cookie_permission_manager_get_number_domains_and_cookies(CookieP
return(sortedList);
}
+/* FIXME: Find a way to add "details" widget */
+#ifndef NO_INFOBAR_DETAILS
static void _cookie_permission_manager_when_ask_expander_changed(CookiePermissionManager *self,
GParamSpec *inSpec,
gpointer inUserData)
@@ -369,26 +389,84 @@ static void _cookie_permission_manager_when_ask_expander_changed(CookiePermissio
midori_extension_set_boolean(self->priv->extension, "show-details-when-ask", gtk_expander_get_expanded(expander));
}
+#endif
+
+static gboolean _cookie_permission_manager_on_infobar_webview_navigate(WebKitWebView *inView,
+ WebKitWebFrame *inFrame,
+ WebKitNetworkRequest *inRequest,
+ WebKitWebNavigationAction *inAction,
+ WebKitWebPolicyDecision *inDecision,
+ gpointer inUserData)
+{
+ /* Destroy info bar - that calls another callback which quits main loop */
+ GtkWidget *infobar=GTK_WIDGET(inUserData);
+
+ gtk_widget_destroy(infobar);
+
+ /* Let the default handler decide */
+ return(FALSE);
+}
+
+static void _cookie_permission_manager_on_infobar_destroy(GtkWidget* inInfobar,
+ gpointer inUserData)
+{
+ CookiePermissionManagerModalInfobar *modalInfo=(CookiePermissionManagerModalInfobar*)inUserData;
+
+ /* Quit main loop */
+ if(g_main_loop_is_running(modalInfo->mainLoop)) g_main_loop_quit(modalInfo->mainLoop);
+}
+
+static void _cookie_permission_manager_on_infobar_policy_decision(GtkWidget* inInfobar,
+ gint inResponse,
+ gpointer inUserData)
+{
+ CookiePermissionManagerModalInfobar *modalInfo;
+
+ /* Get modal info struct */
+ modalInfo=(CookiePermissionManagerModalInfobar*)g_object_get_data(G_OBJECT(inInfobar), "cookie-permission-manager-infobar-data");
+
+ /* Store response */
+ modalInfo->response=inResponse;
+
+ /* Quit main loop */
+ if(g_main_loop_is_running(modalInfo->mainLoop)) g_main_loop_quit(modalInfo->mainLoop);
+}
static gint _cookie_permission_manager_ask_for_policy(CookiePermissionManager *self,
+ MidoriView *inView,
+ SoupMessage *inMessage,
GSList *inUnknownCookies)
{
- CookiePermissionManagerPrivate *priv=self->priv;
- GtkWidget *dialog;
- GtkWidget *widget;
- GtkWidget *contentArea;
- GtkWidget *vbox, *hbox;
- GtkWidget *expander;
- GtkListStore *listStore;
- GtkTreeIter listIter;
- GtkWidget *scrolled;
- GtkWidget *list;
- GtkCellRenderer *renderer;
- GtkTreeViewColumn *column;
- gchar *text;
- gint numberDomains, numberCookies;
- gint response;
- GSList *sortedCookies, *cookies;
+ /* Ask user for policy of unkndown domains in an undistracting way.
+ * The idea is to put the message not in a modal window but into midori's info bar.
+ * Then we'll set up our own GMainLoop to simulate a modal info bar. We need to
+ * connect to all possible signals of info bar, web view and so on to handle user's
+ * decision and to get out of our own GMainLoop. After that webkit resumes processing
+ * data.
+ */
+ CookiePermissionManagerPrivate *priv=self->priv;
+ GtkWidget *infobar;
+/* FIXME: Find a way to add "details" widget */
+#ifndef NO_INFOBAR_DETAILS
+ GtkWidget *widget;
+ GtkWidget *contentArea;
+ GtkWidget *vbox, *hbox;
+ GtkWidget *expander;
+ GtkListStore *listStore;
+ GtkTreeIter listIter;
+ GtkWidget *scrolled;
+ GtkWidget *list;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+#endif
+ gchar *text;
+ gint numberDomains, numberCookies;
+ GSList *sortedCookies, *cookies;
+ WebKitWebView *webkitView;
+ CookiePermissionManagerModalInfobar modalInfo;
+
+ /* Get webkit view of midori view */
+ webkitView=WEBKIT_WEB_VIEW(midori_view_get_web_view(inView));
/* Create a copy of cookies and sort them */
sortedCookies=_cookie_permission_manager_get_number_domains_and_cookies(self,
@@ -396,6 +474,8 @@ static gint _cookie_permission_manager_ask_for_policy(CookiePermissionManager *s
&numberDomains,
&numberCookies);
+/* FIXME: Find a way to add "details" widget */
+#ifndef NO_INFOBAR_DETAILS
/* Create list model and fill in data */
listStore=gtk_list_store_new(N_COLUMN,
G_TYPE_STRING, /* DOMAIN_COLUMN */
@@ -409,7 +489,8 @@ static gint _cookie_permission_manager_ask_for_policy(CookiePermissionManager *s
SoupCookie *cookie=(SoupCookie*)cookies->data;
SoupDate *cookieDate=soup_cookie_get_expires(cookie);
- text=soup_date_to_string(cookieDate, SOUP_DATE_HTTP);
+ if(cookieDate) text=soup_date_to_string(cookieDate, SOUP_DATE_HTTP);
+ else text=g_strdup(_("Till session end"));
gtk_list_store_append(listStore, &listIter);
gtk_list_store_set(listStore,
@@ -423,40 +504,15 @@ static gint _cookie_permission_manager_ask_for_policy(CookiePermissionManager *s
g_free(text);
}
-
- /* Create dialog with text, icon, title and so on */
- dialog=gtk_dialog_new();
-
- gtk_window_set_title(GTK_WINDOW(dialog), _("Confirm storing cookie"));
- gtk_window_set_icon_name(GTK_WINDOW (dialog), "midori");
-
- /* Get content area and layout widgets */
- contentArea=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
-
-#ifdef HAVE_GTK3
- vbox=gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
- gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
-#else
- vbox=gtk_vbox_new(FALSE, 0);
#endif
/* Create description text */
-#ifdef HAVE_GTK3
- hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_box_set_homogeneous(GTK_BOX(hbox), FALSE);
-#else
- hbox=gtk_hbox_new(FALSE, 0);
-#endif
-
- widget=gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
- gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 4);
-
if(numberDomains==1)
{
const gchar *cookieDomain=soup_cookie_get_domain((SoupCookie*)sortedCookies->data);
if(*cookieDomain=='.') cookieDomain++;
-
+
if(numberCookies>1)
text=g_strdup_printf(_("The website %s wants to store %d cookies."), cookieDomain, numberCookies);
else
@@ -467,17 +523,33 @@ static gint _cookie_permission_manager_ask_for_policy(CookiePermissionManager *s
text=g_strdup_printf(_("Multiple websites want to store %d cookies in total."), numberCookies);
}
- widget=gtk_label_new(NULL);
- gtk_label_set_markup(GTK_LABEL(widget), text);
- gtk_label_set_line_wrap(GTK_LABEL(widget), TRUE);
- gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 4);
+ /* Create info bar message and buttons */
+ infobar=midori_view_add_info_bar(inView,
+ GTK_MESSAGE_QUESTION,
+ text,
+ G_CALLBACK(_cookie_permission_manager_on_infobar_policy_decision),
+ NULL,
+ _("_Accept"), COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT,
+ _("Accept for this _session"), COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT_FOR_SESSION,
+ _("De_ny"), COOKIE_PERMISSION_MANAGER_POLICY_BLOCK,
+ _("Deny _this time"), COOKIE_PERMISSION_MANAGER_POLICY_UNDETERMINED,
+ NULL);
g_free(text);
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 4);
+ /* midori_view_add_info_bar() in version 0.4.8 expects a GObject as user data
+ * but I don't want to create an GObject just for a simple struct. So set object
+ * data by our own
+ */
+ g_object_set_data(G_OBJECT(infobar), "cookie-permission-manager-infobar-data", &modalInfo);
- /* Create expander for details */
- expander=gtk_expander_new_with_mnemonic(_("_Details"));
- gtk_box_pack_start(GTK_BOX(vbox), expander, TRUE, TRUE, 5);
+/* FIXME: Find a way to add "details" widget */
+#ifndef NO_INFOBAR_DETAILS
+ /* Get content area of infobar */
+#if HAVE_GTK_INFO_BAR
+ contentArea=gtk_info_bar_get_content_area(GTK_INFO_BAR(infobar));
+#else
+ contentArea=infobar;
+#endif
/* Create list and set up columns of list */
list=gtk_tree_view_new_with_model(GTK_TREE_MODEL(listStore));
@@ -540,25 +612,36 @@ static gint _cookie_permission_manager_ask_for_policy(CookiePermissionManager *s
gtk_expander_set_expanded(GTK_EXPANDER(expander),
midori_extension_get_boolean(priv->extension, "show-details-when-ask"));
g_signal_connect_swapped(expander, "notify::expanded", G_CALLBACK(_cookie_permission_manager_when_ask_expander_changed), self);
+#endif
- /* Create buttons for dialog */
- widget=gtk_dialog_add_button(GTK_DIALOG(dialog), _("_Accept"), COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT);
- gtk_button_set_image(GTK_BUTTON(widget), gtk_image_new_from_stock(GTK_STOCK_APPLY, GTK_ICON_SIZE_BUTTON));
+ /* Show all widgets of info bar */
+ gtk_widget_show_all(infobar);
- gtk_dialog_add_button(GTK_DIALOG(dialog), _("Accept for this _session"), COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT_FOR_SESSION);
+ /* Connect signals to quit main loop */
+ g_signal_connect(webkitView, "navigation-policy-decision-requested", G_CALLBACK(_cookie_permission_manager_on_infobar_webview_navigate), infobar);
+ g_signal_connect(infobar, "destroy", G_CALLBACK(_cookie_permission_manager_on_infobar_destroy), &modalInfo);
- widget=gtk_dialog_add_button(GTK_DIALOG(dialog), _("De_ny"), COOKIE_PERMISSION_MANAGER_POLICY_BLOCK);
- gtk_button_set_image(GTK_BUTTON(widget), gtk_image_new_from_stock(GTK_STOCK_CANCEL, GTK_ICON_SIZE_BUTTON));
+ /* Let info bar be modal and set response to default */
+ modalInfo.response=COOKIE_PERMISSION_MANAGER_POLICY_UNDETERMINED;
+ modalInfo.mainLoop=g_main_loop_new(NULL, FALSE);
- /* Show confirmation dialog and wait for response of user */
- response=gtk_dialog_run(GTK_DIALOG(dialog));
+ GDK_THREADS_LEAVE();
+ g_main_loop_run(modalInfo.mainLoop);
+ GDK_THREADS_ENTER();
+
+ g_main_loop_unref(modalInfo.mainLoop);
+
+ modalInfo.mainLoop=NULL;
+
+ /* Disconnect signal handler to webkit's web view */
+ g_signal_handlers_disconnect_by_func(webkitView, G_CALLBACK(_cookie_permission_manager_on_infobar_webview_navigate), infobar);
/* Store user's decision in database if it is not a temporary block.
* We use the already sorted list of cookies to prevent multiple
* updates of database for the same domain. This sorted list is a copy
* to avoid a reorder of cookies
*/
- if(response>=0)
+ if(modalInfo.response!=COOKIE_PERMISSION_MANAGER_POLICY_UNDETERMINED)
{
const gchar *lastDomain=NULL;
@@ -579,7 +662,7 @@ static gint _cookie_permission_manager_ask_for_policy(CookiePermissionManager *s
sql=sqlite3_mprintf("INSERT OR REPLACE INTO policies (domain, value) VALUES ('%q', %d);",
cookieDomain,
- response);
+ modalInfo.response);
success=sqlite3_exec(priv->database, sql, NULL, NULL, &error);
if(success!=SQLITE_OK) g_warning(_("SQL fails: %s"), error);
if(error) sqlite3_free(error);
@@ -592,10 +675,10 @@ static gint _cookie_permission_manager_ask_for_policy(CookiePermissionManager *s
/* Free up allocated resources */
g_slist_free(sortedCookies);
- gtk_widget_destroy(dialog);
- /* Return user's selection */
- return(response>=0 ? response : COOKIE_PERMISSION_MANAGER_POLICY_BLOCK);
+ /* Return response */
+ return(modalInfo.response==COOKIE_PERMISSION_MANAGER_POLICY_UNDETERMINED ?
+ COOKIE_PERMISSION_MANAGER_POLICY_BLOCK : modalInfo.response);
}
/* A cookie was changed outside a request (e.g. Javascript) */
@@ -604,9 +687,6 @@ static void _cookie_permission_manager_on_cookie_changed(CookiePermissionManager
SoupCookie *inNewCookie,
SoupCookieJar *inCookieJar)
{
- GSList *newCookies;
- gint newCookiePolicy;
-
/* Do not check changed cookies because they must have been allowed before.
* Also do not check removed cookies because they are removed ;)
*/
@@ -615,33 +695,30 @@ static void _cookie_permission_manager_on_cookie_changed(CookiePermissionManager
/* New cookie is a new cookie so check */
switch(_cookie_permission_manager_get_policy(self, inNewCookie))
{
- case COOKIE_PERMISSION_MANAGER_POLICY_BLOCK:
- soup_cookie_jar_delete_cookie(inCookieJar, inNewCookie);
+ case COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT:
+ case COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT_FOR_SESSION:
break;
case COOKIE_PERMISSION_MANAGER_POLICY_UNDETERMINED:
- newCookies=g_slist_prepend(NULL, inNewCookie);
- newCookiePolicy=_cookie_permission_manager_ask_for_policy(self, newCookies);
- if(newCookiePolicy==COOKIE_PERMISSION_MANAGER_POLICY_BLOCK)
- {
- /* Free cookie because it should be blocked */
- soup_cookie_jar_delete_cookie(inCookieJar, inNewCookie);
- }
- else
- {
- /* Cookie was accept so do nothing (it is already added) */
- }
- g_slist_free(newCookies);
- break;
+ /* Fallthrough!
+ * The problem here is that we don't know the view to ask user
+ * for policy to follow for this cookie domain. Therefore we
+ * delete the cookie from jar and assume that we will be asked
+ * again in _cookie_permission_manager_on_response_received().
+ */
- case COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT:
- case COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT_FOR_SESSION:
+ default:
+ soup_cookie_jar_delete_cookie(inCookieJar, inNewCookie);
break;
}
}
/* We received the HTTP headers of the request and it contains cookie-managing headers */
-static void _cookie_permission_manager_process_set_cookie_header(SoupMessage *inMessage, gpointer inUserData)
+static void _cookie_permission_manager_on_response_received(WebKitWebView *inView,
+ WebKitWebFrame *inFrame,
+ WebKitWebResource *inResource,
+ WebKitNetworkResponse *inResponse,
+ gpointer inUserData)
{
g_return_if_fail(IS_COOKIE_PERMISSION_MANAGER(inUserData));
@@ -652,18 +729,23 @@ static void _cookie_permission_manager_process_set_cookie_header(SoupMessage *in
SoupURI *firstParty;
SoupCookieJarAcceptPolicy cookiePolicy;
gint unknownCookiesPolicy;
+ SoupMessage *message;
/* If policy is to deny all cookies return immediately */
cookiePolicy=soup_cookie_jar_get_accept_policy(priv->cookieJar);
if(cookiePolicy==SOUP_COOKIE_JAR_ACCEPT_NEVER) return;
+ /* Get SoupMessage */
+ message=webkit_network_response_get_message(inResponse);
+ if(!message || !SOUP_IS_MESSAGE(message)) return;
+
/* Iterate through cookies in response and check if they should be
* blocked (remove from cookies list) or accepted (added to cookie jar).
* If we could not determine what to do collect these cookies and
* ask user
*/
- newCookies=soup_cookies_from_response(inMessage);
- firstParty=soup_message_get_first_party(inMessage);
+ newCookies=soup_cookies_from_response(message);
+ firstParty=soup_message_get_first_party(message);
for(cookie=newCookies; cookie; cookie=cookie->next)
{
switch(_cookie_permission_manager_get_policy(self, cookie->data))
@@ -712,7 +794,13 @@ static void _cookie_permission_manager_process_set_cookie_header(SoupMessage *in
*/
if(g_slist_length(unknownCookies)>0)
{
- unknownCookiesPolicy=_cookie_permission_manager_ask_for_policy(self, unknownCookies);
+ /* Get view */
+ MidoriView *view;
+
+ view=MIDORI_VIEW(g_object_get_data(G_OBJECT(inView), "midori-view"));
+
+ /* Ask for user's decision */
+ unknownCookiesPolicy=_cookie_permission_manager_ask_for_policy(self, view, message, unknownCookies);
if(unknownCookiesPolicy==COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT ||
unknownCookiesPolicy==COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT_FOR_SESSION)
{
@@ -744,33 +832,51 @@ static void _cookie_permission_manager_process_set_cookie_header(SoupMessage *in
g_slist_free(newCookies);
}
-/* A request was started and is in queue now */
-static void _cookie_permission_manager_request_queued(SoupSessionFeature *inFeature, SoupSession *inSession, SoupMessage *inMessage)
+/* A tab to a browser was added */
+static void _cookie_permission_manager_on_add_tab(CookiePermissionManager *self, MidoriView *inView, gpointer inUserData)
{
- /* Get class instance */
- CookiePermissionManager *manager=g_object_get_data(G_OBJECT(inFeature), "cookie-permission-manager");
+ /* Listen to starting network requests */
+ WebKitWebView *webkitView=WEBKIT_WEB_VIEW(midori_view_get_web_view(inView));
- /* Listen to "got-headers" signals and register handlers for
- * checking cookie-managing headers in HTTP stream
- */
- soup_message_add_header_handler(inMessage,
- "got-headers",
- "Set-Cookie",
- G_CALLBACK(_cookie_permission_manager_process_set_cookie_header),
- manager);
-
- soup_message_add_header_handler(inMessage,
- "got-headers",
- "Set-Cookie2",
- G_CALLBACK(_cookie_permission_manager_process_set_cookie_header),
- manager);
+ g_object_set_data(G_OBJECT(webkitView), "midori-view", inView);
+ g_signal_connect(webkitView, "resource-response-received", G_CALLBACK(_cookie_permission_manager_on_response_received), self);
}
-/* Request has loaded and was unqueued */
-static void _cookie_permission_manager_request_unqueued(SoupSessionFeature *inFeature, SoupSession *inSession, SoupMessage *inMessage)
+/* A browser window was added */
+static void _cookie_permission_manager_on_add_browser(CookiePermissionManager *self,
+ MidoriBrowser *inBrowser,
+ gpointer inUserData)
{
- /* Stop listening to HTTP stream */
- g_signal_handlers_disconnect_by_func(inMessage, _cookie_permission_manager_process_set_cookie_header, inFeature);
+ GList *tabs, *iter;
+
+ /* Set up all current available tabs in browser */
+ tabs=midori_browser_get_tabs(inBrowser);
+ for(iter=tabs; iter; iter=g_list_next(iter))
+ {
+ _cookie_permission_manager_on_add_tab(self, iter->data, inBrowser);
+ }
+ g_list_free(tabs);
+
+ /* Listen to new tabs opened in browser and existing ones closed */
+ g_signal_connect_swapped(inBrowser, "add-tab", G_CALLBACK(_cookie_permission_manager_on_add_tab), self);
+}
+
+/* Application property has changed */
+static void _cookie_permission_manager_on_application_changed(CookiePermissionManager *self)
+{
+ CookiePermissionManagerPrivate *priv=COOKIE_PERMISSION_MANAGER(self)->priv;
+ GList *browsers, *iter;
+
+ /* Set up all current open browser windows */
+ browsers=midori_app_get_browsers(priv->application);
+ for(iter=browsers; iter; iter=g_list_next(iter))
+ {
+ _cookie_permission_manager_on_add_browser(self, MIDORI_BROWSER(iter->data), priv->application);
+ }
+ g_list_free(browsers);
+
+ /* Listen to new browser windows opened and existing ones closed */
+ g_signal_connect_swapped(priv->application, "add-browser", G_CALLBACK(_cookie_permission_manager_on_add_browser), self);
}
/* IMPLEMENTATION: GObject */
@@ -778,9 +884,20 @@ static void _cookie_permission_manager_request_unqueued(SoupSessionFeature *inFe
/* Finalize this object */
static void cookie_permission_manager_finalize(GObject *inObject)
{
- CookiePermissionManagerPrivate *priv=COOKIE_PERMISSION_MANAGER(inObject)->priv;
+ CookiePermissionManager *self=COOKIE_PERMISSION_MANAGER(inObject);
+ CookiePermissionManagerPrivate *priv=self->priv;
+ GList *browsers, *browser;
+ GList *tabs, *tab;
+ WebKitWebView *webkitView;
/* Dispose allocated resources */
+ if(priv->databaseFilename)
+ {
+ g_free(priv->databaseFilename);
+ priv->databaseFilename=NULL;
+ g_object_notify_by_pspec(inObject, CookiePermissionManagerProperties[PROP_DATABASE_FILENAME]);
+ }
+
if(priv->database)
{
sqlite3_close(priv->database);
@@ -789,11 +906,24 @@ static void cookie_permission_manager_finalize(GObject *inObject)
}
g_signal_handler_disconnect(priv->cookieJar, priv->cookieJarChangedID);
+ g_object_steal_data(G_OBJECT(priv->cookieJar), "cookie-permission-manager");
- priv->featureIface->request_queued=priv->oldRequestQueued;
- priv->featureIface->request_unqueued=priv->oldRequestUnqueued;
+ g_signal_handlers_disconnect_by_data(priv->application, self);
- g_object_steal_data(G_OBJECT(priv->cookieJar), "cookie-permission-manager");
+ browsers=midori_app_get_browsers(priv->application);
+ for(browser=browsers; browser; browser=g_list_next(browser))
+ {
+ g_signal_handlers_disconnect_by_data(browser->data, self);
+
+ tabs=midori_browser_get_tabs(MIDORI_BROWSER(browser->data));
+ for(tab=tabs; tab; tab=g_list_next(tab))
+ {
+ webkitView=WEBKIT_WEB_VIEW(midori_view_get_web_view(MIDORI_VIEW(tab->data)));
+ g_signal_handlers_disconnect_by_data(webkitView, self);
+ }
+ g_list_free(tabs);
+ }
+ g_list_free(browsers);
/* Call parent's class finalize method */
G_OBJECT_CLASS(cookie_permission_manager_parent_class)->finalize(inObject);
@@ -806,7 +936,7 @@ static void cookie_permission_manager_set_property(GObject *inObject,
GParamSpec *inSpec)
{
CookiePermissionManager *self=COOKIE_PERMISSION_MANAGER(inObject);
-
+
switch(inPropID)
{
/* Construct-only properties */
@@ -817,6 +947,7 @@ static void cookie_permission_manager_set_property(GObject *inObject,
case PROP_APPLICATION:
self->priv->application=g_value_get_object(inValue);
+ _cookie_permission_manager_on_application_changed(self);
break;
case PROP_ASK_FOR_UNKNOWN_POLICY:
@@ -850,6 +981,10 @@ static void cookie_permission_manager_get_property(GObject *inObject,
g_value_set_pointer(outValue, self->priv->database);
break;
+ case PROP_DATABASE_FILENAME:
+ g_value_set_string(outValue, self->priv->databaseFilename);
+ break;
+
case PROP_ASK_FOR_UNKNOWN_POLICY:
g_value_set_boolean(outValue, self->priv->askForUnknownPolicy);
break;
@@ -896,6 +1031,13 @@ static void cookie_permission_manager_class_init(CookiePermissionManagerClass *k
_("Pointer to sqlite database instance used by this extension"),
G_PARAM_READABLE);
+ CookiePermissionManagerProperties[PROP_DATABASE_FILENAME]=
+ g_param_spec_string("database-filename",
+ _("Database path"),
+ _("Path to sqlite database instance used by this extension"),
+ NULL,
+ G_PARAM_READABLE);
+
CookiePermissionManagerProperties[PROP_ASK_FOR_UNKNOWN_POLICY]=
g_param_spec_boolean("ask-for-unknown-policy",
_("Ask for unknown policy"),
@@ -918,6 +1060,7 @@ static void cookie_permission_manager_init(CookiePermissionManager *self)
/* Set up default values */
priv->database=NULL;
+ priv->databaseFilename=NULL;
priv->askForUnknownPolicy=TRUE;
/* Hijack session's cookie jar to handle cookies requests on our own in HTTP streams
@@ -928,12 +1071,6 @@ static void cookie_permission_manager_init(CookiePermissionManager *self)
priv->featureIface=SOUP_SESSION_FEATURE_GET_CLASS(priv->cookieJar);
g_object_set_data(G_OBJECT(priv->cookieJar), "cookie-permission-manager", self);
- priv->oldRequestQueued=priv->featureIface->request_queued;
- priv->oldRequestUnqueued=priv->featureIface->request_unqueued;
-
- priv->featureIface->request_queued=_cookie_permission_manager_request_queued;
- priv->featureIface->request_unqueued=_cookie_permission_manager_request_unqueued;
-
/* Listen to changed cookies set or changed by other sources like javascript */
priv->cookieJarChangedID=g_signal_connect_swapped(priv->cookieJar, "changed", G_CALLBACK(_cookie_permission_manager_on_cookie_changed), self);
}
More information about the Xfce4-commits
mailing list