Refactored the soup session (#14).
authorDaniel Carl <danielcarl@gmx.de>
Fri, 5 Apr 2013 15:36:40 +0000 (17:36 +0200)
committerDaniel Carl <danielcarl@gmx.de>
Fri, 5 Apr 2013 15:36:40 +0000 (17:36 +0200)
Move session related logic into own c file. Added file locking to cookie jar
file.

src/config.h
src/main.c
src/session.c [new file with mode: 0644]
src/session.h [new file with mode: 0644]

index f762a92..1d22019 100644 (file)
@@ -25,8 +25,8 @@
 /* time in seconds after that message will be removed from inputbox if the
  * message where only temporary */
 #define MESSAGE_TIMEOUT             5
-#define SETTING_MAX_CONNS           25
-#define SETTING_MAX_CONNS_PER_HOST  5
+const unsigned int SETTING_MAX_CONNS          = 25;
+const unsigned int SETTING_MAX_CONNS_PER_HOST = 5;
 
 /* number of chars in inputbox - if completion or stepping through history
  * print values longer this value, the cursor will be placed to the beginning
index 60f047a..00d8fc6 100644 (file)
@@ -29,6 +29,7 @@
 #include "hints.h"
 #include "searchengine.h"
 #include "history.h"
+#include "session.h"
 
 /* variables */
 static char **args;
@@ -42,8 +43,6 @@ static void vb_destroy_window_cb(GtkWidget *widget);
 static void vb_inputbox_activate_cb(GtkEntry *entry);
 static gboolean vb_inputbox_keyrelease_cb(GtkEntry *entry, GdkEventKey *event);
 static void vb_scroll_cb(GtkAdjustment *adjustment);
-static void vb_new_request_cb(SoupSession *session, SoupMessage *message);
-static void vb_gotheaders_cb(SoupMessage *message);
 static WebKitWebView *vb_inspector_new(WebKitWebInspector *inspector, WebKitWebView *webview);
 static gboolean vb_inspector_show(WebKitWebInspector *inspector);
 static gboolean vb_inspector_close(WebKitWebInspector *inspector);
@@ -70,8 +69,6 @@ static void vb_init_core(void);
 static void vb_read_config(void);
 static void vb_setup_signals();
 static void vb_init_files(void);
-static void vb_set_cookie(SoupCookie *cookie);
-static const char *vb_get_cookies(SoupURI *uri);
 static gboolean vb_hide_message();
 static void vb_set_status(const StatusType status);
 void vb_inputbox_print(gboolean force, const MessageType type, gboolean hide, const char *message);
@@ -484,30 +481,6 @@ static void vb_scroll_cb(GtkAdjustment *adjustment)
     vb_update_statusbar();
 }
 
-static void vb_new_request_cb(SoupSession *session, SoupMessage *message)
-{
-    SoupMessageHeaders *header = message->request_headers;
-    SoupURI *uri;
-    const char *cookie;
-
-    soup_message_headers_remove(header, "Cookie");
-    uri = soup_message_get_uri(message);
-    if ((cookie = vb_get_cookies(uri))) {
-        soup_message_headers_append(header, "Cookie", cookie);
-    }
-    g_signal_connect_after(G_OBJECT(message), "got-headers", G_CALLBACK(vb_gotheaders_cb), NULL);
-}
-
-static void vb_gotheaders_cb(SoupMessage *message)
-{
-    GSList *list = NULL, *p = NULL;
-
-    for(p = list = soup_cookies_from_response(message); p; p = g_slist_next(p)) {
-        vb_set_cookie((SoupCookie*)p->data);
-    }
-    soup_cookies_free(list);
-}
-
 static WebKitWebView *vb_inspector_new(WebKitWebInspector *inspector, WebKitWebView *webview)
 {
     return WEBKIT_WEB_VIEW(webkit_web_view_new());
@@ -557,30 +530,6 @@ static void vb_inspector_finished(WebKitWebInspector *inspector)
     g_free(vb.gui.inspector);
 }
 
-#ifdef FEATURE_COOKIE
-static void vb_set_cookie(SoupCookie *cookie)
-{
-    SoupCookieJar *jar = soup_cookie_jar_text_new(vb.files[FILES_COOKIE], false);
-    cookie = soup_cookie_copy(cookie);
-    if (!cookie->expires && vb.config.cookie_timeout) {
-        soup_cookie_set_expires(cookie, soup_date_new_from_now(vb.config.cookie_timeout));
-    }
-    soup_cookie_jar_add_cookie(jar, cookie);
-    g_object_unref(jar);
-}
-
-static const char *vb_get_cookies(SoupURI *uri)
-{
-    const char *cookie;
-
-    SoupCookieJar *jar = soup_cookie_jar_text_new(vb.files[FILES_COOKIE], TRUE);
-    cookie = soup_cookie_jar_get_cookies(jar, uri, TRUE);
-    g_object_unref(jar);
-
-    return cookie;
-}
-#endif
-
 static void vb_set_status(const StatusType status)
 {
     if (vb.state.status_type != status) {
@@ -690,12 +639,6 @@ static void vb_init_core(void)
 
     gtk_paned_pack1(GTK_PANED(gui->pane), GTK_WIDGET(gui->box), TRUE, TRUE);
 
-    /* init soup session */
-    vb.soup_session = webkit_get_default_session();
-    soup_session_remove_feature_by_type(vb.soup_session, soup_cookie_jar_get_type());
-    g_object_set(vb.soup_session, "max-conns", SETTING_MAX_CONNS , NULL);
-    g_object_set(vb.soup_session, "max-conns-per-host", SETTING_MAX_CONNS_PER_HOST, NULL);
-
     vb_setup_signals();
 
     /* Put all part together */
@@ -717,6 +660,7 @@ static void vb_init_core(void)
     gtk_widget_grab_focus(GTK_WIDGET(gui->webview));
 
     vb_init_files();
+    session_init();
     setting_init();
     command_init();
     keybind_init();
@@ -796,8 +740,6 @@ static void vb_setup_signals()
         NULL
     );
 
-    g_signal_connect_after(G_OBJECT(vb.soup_session), "request-started", G_CALLBACK(vb_new_request_cb), NULL);
-
     /* inspector */
     g_object_connect(
         G_OBJECT(vb.gui.inspector),
diff --git a/src/session.c b/src/session.c
new file mode 100644 (file)
index 0000000..dad0b28
--- /dev/null
@@ -0,0 +1,95 @@
+/**
+ * vimb - a webkit based vim like browser.
+ *
+ * Copyright (C) 2012-2013 Daniel Carl
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+#include <sys/file.h>
+#include "main.h"
+#include "session.h"
+
+G_DEFINE_TYPE(SessionCookieJar, session_cookiejar, SOUP_TYPE_COOKIE_JAR_TEXT)
+
+static SoupCookieJar *session_cookiejar_new(const char *file, gboolean ro);
+static void session_cookiejar_changed(SoupCookieJar *self, SoupCookie *old, SoupCookie *new);
+static void session_cookiejar_class_init(SessionCookieJarClass *class);
+static void session_cookiejar_finalize(GObject *self);
+static void session_cookiejar_init(SessionCookieJar *self);
+static void session_cookiejar_set_property(GObject *self, guint prop_id,
+    const GValue *value, GParamSpec *pspec);
+
+extern VbCore vb;
+extern const unsigned int SETTING_MAX_CONNS;
+extern const unsigned int SETTING_MAX_CONNS_PER_HOST;
+
+
+void session_init(void)
+{
+    /* init soup session */
+    vb.soup_session = webkit_get_default_session();
+    soup_session_add_feature(
+        vb.soup_session,
+        SOUP_SESSION_FEATURE(session_cookiejar_new(vb.files[FILES_COOKIE], false))
+    );
+    g_object_set(vb.soup_session, "max-conns", SETTING_MAX_CONNS , NULL);
+    g_object_set(vb.soup_session, "max-conns-per-host", SETTING_MAX_CONNS_PER_HOST, NULL);
+
+}
+
+static SoupCookieJar *session_cookiejar_new(const char *file, gboolean ro)
+{
+    return g_object_new(
+        SESSION_COOKIEJAR_TYPE, SOUP_COOKIE_JAR_TEXT_FILENAME, file, SOUP_COOKIE_JAR_READ_ONLY, ro, NULL
+    );
+}
+
+static void session_cookiejar_changed(SoupCookieJar *self, SoupCookie *old_cookie, SoupCookie *new_cookie)
+{
+    flock(SESSION_COOKIEJAR(self)->lock, LOCK_EX);
+    if (new_cookie && !new_cookie->expires) {
+        soup_cookie_set_expires(new_cookie, soup_date_new_from_now(vb.config.cookie_timeout));
+    }
+    SOUP_COOKIE_JAR_CLASS(session_cookiejar_parent_class)->changed(self, old_cookie, new_cookie);
+    flock(SESSION_COOKIEJAR(self)->lock, LOCK_UN);
+}
+
+static void session_cookiejar_class_init(SessionCookieJarClass *class)
+{
+    SOUP_COOKIE_JAR_CLASS(class)->changed = session_cookiejar_changed;
+    G_OBJECT_CLASS(class)->get_property   = G_OBJECT_CLASS(session_cookiejar_parent_class)->get_property;
+    G_OBJECT_CLASS(class)->set_property   = session_cookiejar_set_property;
+    G_OBJECT_CLASS(class)->finalize       = session_cookiejar_finalize;
+    g_object_class_override_property(G_OBJECT_CLASS(class), 1, "filename");
+}
+
+static void session_cookiejar_finalize(GObject *self)
+{
+    close(SESSION_COOKIEJAR(self)->lock);
+    G_OBJECT_CLASS(session_cookiejar_parent_class)->finalize(self);
+}
+
+static void session_cookiejar_init(SessionCookieJar *self)
+{
+    self->lock = open(vb.files[FILES_COOKIE], 0);
+}
+
+static void session_cookiejar_set_property(GObject *self, guint prop_id, const
+    GValue *value, GParamSpec *pspec)
+{
+    flock(SESSION_COOKIEJAR(self)->lock, LOCK_SH);
+    G_OBJECT_CLASS(session_cookiejar_parent_class)->set_property(self, prop_id, value, pspec);
+    flock(SESSION_COOKIEJAR(self)->lock, LOCK_UN);
+}
diff --git a/src/session.h b/src/session.h
new file mode 100644 (file)
index 0000000..fceb9e4
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * vimb - a webkit based vim like browser.
+ *
+ * Copyright (C) 2012-2013 Daniel Carl
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+#ifndef _SESSION_H
+#define _SESSION_H
+
+#include <glib.h>
+#include <libsoup/soup.h>
+
+#define SESSION_COOKIEJAR_TYPE (session_cookiejar_get_type())
+#define SESSION_COOKIEJAR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SESSION_COOKIEJAR_TYPE, SessionCookieJar))
+
+typedef struct {
+    SoupCookieJarText parent_instance;
+    int lock;
+} SessionCookieJar;
+
+typedef struct {
+    SoupCookieJarTextClass parent_class;
+} SessionCookieJarClass;
+
+GType session_cookiejar_get_type(void);
+
+void session_init(void);
+
+#endif /* end of include guard: _SESSION_H */