Hi all,

I've been having problems to use gmail -just like others- and the
google pdf quick view -I haven't seen another report about this one-
with surf. Besides the session management issues, surf is not updating
cookies that are created by javascript running in the current page.
Notice v.g. that uzbl, which supports the two of the aforementioned
webapps, handle both cases of cookie creation:

[...]
g_object_connect(G_OBJECT(uzbl.net.soup_cookie_jar), "signal::changed", 
G_CALLBACK(save_cookies_js), NULL, NULL);
[...]
void
save_cookies_http(SoupMessage *msg, gpointer user_data) {
[...]
void
save_cookies_js(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie
*new_cookie, gpointer user_data) {
[...]

Where soup_cookie_jar is the basic, non persistent, SoupCookieJar.
Anyway, I don't like this approach, I think they do it like this
because they want to allow for external customizable handlers for every
imaginable event. That way they implement cookie persistence a layer
above the C core.

But the customary cookiejar mechanism in webkit takes care of everything
by just registering it as a feature of the session.  Except for file
locking, which is sine qua non for surf :(. So I decided to "subclass"
SoupCookieJarText in order to add some needed decoration: file locking
and sessiontime management. It's about 60 lines of OO-wannabe
GObject-boilerplate and 3 lines of directly useful code, but I think
it's a cleaner approach than trying to intercept all cookie related
events.  Besides, it removes about 60 lines of cookie handling (for a
net amount of 0 lines), it leverages the webkit cookiejar feature and it
solves the aforementioned bugs.

Well, just HIH someone else.

Best regards
--
Carlos



diff -N -up surf-0.4.1/cookie.c surf-0.4.1-cookie//cookie.c
--- surf-0.4.1/cookie.c 1969-12-31 21:00:00.000000000 -0300
+++ surf-0.4.1-cookie//cookie.c 2010-07-09 16:31:13.000000000 -0300
@@ -0,0 +1,57 @@
+#define SURF_TYPE_COOKIE_JAR           (surf_cookie_jar_get_type ())
+#define SURF_COOKIE_JAR(obj)           (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
SURF_TYPE_COOKIE_JAR, SurfCookieJar))
+
+typedef struct {
+  SoupCookieJarText parent_instance;
+  int lock;
+} SurfCookieJar;
+
+typedef struct {
+  SoupCookieJarTextClass parent_class;
+} SurfCookieJarClass;
+
+G_DEFINE_TYPE(SurfCookieJar, surf_cookie_jar, SOUP_TYPE_COOKIE_JAR_TEXT)
+
+static void
+surf_cookie_jar_init(SurfCookieJar *self) {
+  self->lock = open(cookiefile, 0);
+}
+
+static void
+surf_cookie_jar_changed(SoupCookieJar *self, SoupCookie *old_cookie, 
SoupCookie *new_cookie) {
+       flock(SURF_COOKIE_JAR(self)->lock, LOCK_EX);
+       if(new_cookie && !new_cookie->expires && sessiontime)
+               soup_cookie_set_expires(new_cookie, 
soup_date_new_from_now(sessiontime));
+  SOUP_COOKIE_JAR_CLASS(surf_cookie_jar_parent_class)->changed(self, 
old_cookie, new_cookie);
+       flock(SURF_COOKIE_JAR(self)->lock, LOCK_UN);
+}
+
+static void
+surf_cookie_jar_set_property(GObject *self, guint prop_id, const GValue 
*value, GParamSpec *pspec) {
+       flock(SURF_COOKIE_JAR(self)->lock, LOCK_SH);
+  // parent class loads entire file into hash table at once
+  G_OBJECT_CLASS(surf_cookie_jar_parent_class)->set_property(self, prop_id, 
value, pspec);
+       flock(SURF_COOKIE_JAR(self)->lock, LOCK_UN);
+}
+
+static void
+surf_cookie_jar_finalize(GObject *self) {
+  close(SURF_COOKIE_JAR(self)->lock);
+  G_OBJECT_CLASS(surf_cookie_jar_parent_class)->finalize(self);
+}
+
+static void
+surf_cookie_jar_class_init(SurfCookieJarClass *klass) {
+  SOUP_COOKIE_JAR_CLASS(klass)->changed = surf_cookie_jar_changed;
+  G_OBJECT_CLASS(klass)->get_property = 
G_OBJECT_CLASS(surf_cookie_jar_parent_class)->get_property;
+  G_OBJECT_CLASS(klass)->set_property = surf_cookie_jar_set_property;
+  G_OBJECT_CLASS(klass)->finalize = surf_cookie_jar_finalize;
+  g_object_class_override_property(G_OBJECT_CLASS(klass), 1, "filename");
+}
+
+static SoupCookieJar *
+surf_cookie_jar_new(const char *filename, gboolean read_only) {
+  return g_object_new(SURF_TYPE_COOKIE_JAR,
+                      SOUP_COOKIE_JAR_TEXT_FILENAME, filename,
+                      SOUP_COOKIE_JAR_READ_ONLY, read_only, NULL);
+} 
diff -N -up surf-0.4.1/Makefile surf-0.4.1-cookie//Makefile
--- surf-0.4.1/Makefile 2010-06-08 04:06:41.000000000 -0300
+++ surf-0.4.1-cookie//Makefile 2010-07-09 16:31:29.000000000 -0300
@@ -18,7 +18,7 @@ options:
        @echo CC $<
        @${CC} -c ${CFLAGS} $<
 
-${OBJ}: config.h config.mk
+${OBJ}: config.h config.mk cookie.c
 
 config.h:
        @echo creating $@ from config.def.h
diff -N -up surf-0.4.1/surf.c surf-0.4.1-cookie//surf.c
--- surf-0.4.1/surf.c   2010-06-08 04:06:42.000000000 -0300
+++ surf-0.4.1-cookie//surf.c   2010-07-09 16:18:44.000000000 -0300
@@ -78,9 +78,7 @@ static void drawindicator(Client *c);
 static gboolean exposeindicator(GtkWidget *w, GdkEventExpose *e, Client *c);
 static void find(Client *c, const Arg *arg);
 static const char *getatom(Client *c, int a);
-static const char *getcookies(SoupURI *uri);
 static char *geturi(Client *c);
-void gotheaders(SoupMessage *msg, gpointer user_data);
 static gboolean initdownload(WebKitWebView *v, WebKitDownload *o, Client *c);
 static gboolean keypress(GtkWidget *w, GdkEventKey *ev, Client *c);
 static void linkhover(WebKitWebView *v, const char* t, const char* l, Client 
*c);
@@ -89,7 +87,6 @@ static void loaduri(Client *c, const Arg
 static void navigate(Client *c, const Arg *arg);
 static Client *newclient(void);
 static void newwindow(Client *c, const Arg *arg);
-static void newrequest(SoupSession *s, SoupMessage *msg, gpointer v);
 static void pasteuri(GtkClipboard *clipboard, const char *text, gpointer d);
 static void print(Client *c, const Arg *arg);
 static GdkFilterReturn processx(GdkXEvent *xevent, GdkEvent *event, gpointer 
d);
@@ -98,7 +95,6 @@ static void reload(Client *c, const Arg
 static void resize(GtkWidget *w, GtkAllocation *a, Client *c);
 static void scroll(Client *c, const Arg *arg);
 static void setatom(Client *c, int a, const char *v);
-static void setcookie(SoupCookie *c);
 static void setup(void);
 static void sigchld(int unused);
 static void source(Client *c, const Arg *arg);
@@ -113,6 +109,7 @@ static void zoom(Client *c, const Arg *a
 
 /* configuration, allows nested code to access above variables */
 #include "config.h"
+#include "cookie.c"
 
 char *
 buildpath(const char *path) {
@@ -277,15 +274,6 @@ find(Client *c, const Arg *arg) {
 }
 
 const char *
-getcookies(SoupURI *uri) {
-       const char *c;
-       SoupCookieJar *j = soup_cookie_jar_text_new(cookiefile, TRUE);
-       c = soup_cookie_jar_get_cookies(j, uri, TRUE);
-       g_object_unref(j);
-       return c;
-}
-
-const char *
 getatom(Client *c, int a) {
        static char buf[BUFSIZ];
        Atom adummy;
@@ -313,19 +301,6 @@ geturi(Client *c) {
        return uri;
 }
 
-void
-gotheaders(SoupMessage *msg, gpointer v) {
-       SoupURI *uri;
-       GSList *l, *p;
-
-       uri = soup_message_get_uri(msg);
-       for(p = l = soup_cookies_from_response(msg); p;
-               p = g_slist_next(p))  {
-               setcookie((SoupCookie *)p->data);
-       }
-       soup_cookies_free(l);
-}
-
 gboolean
 initdownload(WebKitWebView *view, WebKitDownload *o, Client *c) {
        Arg arg;
@@ -521,19 +496,6 @@ newclient(void) {
 }
 
 void
-newrequest(SoupSession *s, SoupMessage *msg, gpointer v) {
-       SoupMessageHeaders *h = msg->request_headers;
-       SoupURI *uri;
-       const char *c;
-
-       soup_message_headers_remove(h, "Cookie");
-       uri = soup_message_get_uri(msg);
-       if((c = getcookies(uri)))
-               soup_message_headers_append(h, "Cookie", c);
-       g_signal_connect_after(G_OBJECT(msg), "got-headers", 
G_CALLBACK(gotheaders), NULL);
-}
-
-void
 newwindow(Client *c, const Arg *arg) {
        guint i = 0;
        const char *cmd[10], *uri;
@@ -640,25 +602,6 @@ scroll(Client *c, const Arg *arg) {
 }
 
 void
-setcookie(SoupCookie *c) {
-       int lock;
-
-       lock = open(cookiefile, 0);
-       flock(lock, LOCK_EX);
-       SoupDate *e;
-       SoupCookieJar *j = soup_cookie_jar_text_new(cookiefile, FALSE);
-       c = soup_cookie_copy(c);
-       if(c->expires == NULL && sessiontime) {
-               e = soup_date_new_from_time_t(time(NULL) + sessiontime);
-               soup_cookie_set_expires(c, e);
-       }
-       soup_cookie_jar_add_cookie(j, c);
-       g_object_unref(j);
-       flock(lock, LOCK_UN);
-       close(lock);
-}
-
-void
 setatom(Client *c, int a, const char *v) {
        XSync(dpy, False);
        XChangeProperty(dpy, GDK_WINDOW_XID(GTK_WIDGET(c->win)->window), 
atoms[a],
@@ -694,9 +637,7 @@ setup(void) {
 
        /* request handler */
        s = webkit_get_default_session();
-       soup_session_remove_feature_by_type(s, soup_cookie_get_type());
-       soup_session_remove_feature_by_type(s, soup_cookie_jar_get_type());
-       g_signal_connect_after(G_OBJECT(s), "request-started", 
G_CALLBACK(newrequest), NULL);
+  soup_session_add_feature(s, 
SOUP_SESSION_FEATURE(surf_cookie_jar_new(cookiefile, FALSE)));
 
        /* proxy */
        if((proxy = getenv("http_proxy")) && strcmp(proxy, "")) {

Reply via email to