commit 0bf2efbd2b12bd7ac7e2cf90867f59ebdaee8e6b
parent 266e6562976a6aaaa1fadd3ecc6d72612cc7ce3e
Author: Christoph Lohmann <20h@r-36.net>
Date:   Fri,  5 May 2017 21:44:27 +0200
Allow user-agent switching.
Diffstat:
4 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/README b/README
@@ -8,6 +8,14 @@ In order to build surf you need GTK+ and Webkit/GTK+ header files.
 
 In order to use the functionality of the url-bar, also install dmenu[0].
 
+Surf is running a "download" script when a file needs to be downloaded and a
+"plumb" script when some URI needs to be opened, which is not beginning with
+"about:", "http://" or "https://". Please create them in your $PATH prior to
+using surf.
+
+An example file for the User-Agent switching file is supplied in
+"useragents.txt". You may need to adapt them to the current world situation.
+
 Installation
 ------------
 Edit config.mk to match your local setup (surf is installed into
diff --git a/config.def.h b/config.def.h
@@ -29,6 +29,7 @@ static Bool strictssl       = TRUE; /* strict means if untrusted SSL/TLS
 static time_t sessiontime   = 3600;
 static Bool enablediskcache = TRUE;
 static int diskcachebytes   = 5 * 1024 * 1024;
+#define uafile                "~/.surf/useragents.txt"
 
 /* Webkit default features */
 static Bool enablescrollbars      = TRUE;
@@ -71,7 +72,7 @@ static Bool insecureresources     = FALSE; /* Whether to allow to load
  * Now on TV: »What is the best User-Agent for me?«
  * Result: None.
  */
-char *useragent = NULL;
+char *useragent = " ";
 /*
  * These are for the case some incompetent »web programmer« decided for you
  * what is best for you.
@@ -92,8 +93,6 @@ static HttpHeader customheaders[] = {
 	/* key, value */
 	/* Do-Not-Track. Haha! */
 	{ "DNT", "1" },
-	/* Best User-Agent ever. */
-	{ "User-Agent", " "},
 	/* We are a damn US imperialist. Change to cn, once Chinese communism
 	 * has won.*/
 	{ "Accept-Language", "en-US,en;q=0.5" },
@@ -106,7 +105,9 @@ static HttpHeader customheaders[] = {
 #define PROMPT_GOTO  "Go To"
 #define PROMPT_FIND  "Find"
 #define PROMPT_SLASH "/"
+#define PROMPT_UA    "Set User-Agent"
 
+/* Set the property of surf using the old value. */
 #define SETPROP(p, q, prompt) { \
 	.v = (char *[]){ "/bin/sh", "-c", \
 		"prop=\"`xprop -id $2 $0 " \
@@ -117,6 +118,22 @@ static HttpHeader customheaders[] = {
 	} \
 }
 
+/*
+ * Set the property of surf using the old value and values supplied from a
+ * file.
+ */
+#define SETPROPFROMFILE(p, q, prompt, file) { \
+	.v = (char *[]){ "/bin/bash", "-c", \
+		"prop=\"`{ xprop -id $2 $0 " \
+		"| sed \"s/^$0(STRING) = \\(\\\\\"\\?\\)\\(.*\\)\\1$/\\2/\" " \
+		"| xargs -0 printf %b; " \
+		"  [ -e $(eval echo $4) ] && cat $(eval echo $4); } " \
+		"| dmenu -p \"$3\"`\" &&" \
+		"xprop -id $2 -f $1 8u -set $1 \"$prop\"", \
+		p, q, winid, prompt, file, NULL \
+	} \
+}
+
 /* DOWNLOAD(URI, referer) */
 #define DOWNLOAD(d, r) { \
 	.v = (char *[]){ "/bin/sh", "-c", \
@@ -186,6 +203,7 @@ static Key keys[] = {
 	{ MODKEY,               GDK_g,      spawn,      SETPROP("_SURF_URI", "_SURF_GO", PROMPT_GOTO) },
 	{ MODKEY,               GDK_f,      spawn,      SETPROP("_SURF_FIND", "_SURF_FIND", PROMPT_FIND) },
 	{ MODKEY,               GDK_slash,  spawn,      SETPROP("_SURF_FIND", "_SURF_FIND", PROMPT_SLASH) },
+	{ MODKEY,               GDK_a,      spawn,      SETPROPFROMFILE("_SURF_UA", "_SURF_UA", PROMPT_UA, uafile) },
 
 	{ MODKEY,               GDK_n,      find,       { .b = TRUE } },
 	{ MODKEY|GDK_SHIFT_MASK,GDK_n,      find,       { .b = FALSE } },
diff --git a/surf.c b/surf.c
@@ -36,7 +36,7 @@ char *argv0;
 #define COOKIEJAR_TYPE          (cookiejar_get_type ())
 #define COOKIEJAR(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), COOKIEJAR_TYPE, CookieJar))
 
-enum { AtomFind, AtomGo, AtomUri, AtomLast };
+enum { AtomFind, AtomGo, AtomUri, AtomUA, AtomLast };
 enum {
 	ClkDoc   = WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT,
 	ClkLink  = WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK,
@@ -1078,9 +1078,12 @@ newclient(void)
 			"enable-private-browsing", privatebrowsing, NULL);
 	g_object_set(G_OBJECT(settings), "enable-dns-prefetching",
 			dnsprefetching, NULL);
+
 	if (!(ua = getenv("SURF_USERAGENT")))
 		ua = useragent;
 	g_object_set(G_OBJECT(settings), "user-agent", ua, NULL);
+	setatom(c, AtomUA, ua);
+
 	g_object_set(G_OBJECT(settings),
 	             "auto-load-images", loadimages, NULL);
 	g_object_set(G_OBJECT(settings),
@@ -1372,6 +1375,7 @@ GdkFilterReturn
 processx(GdkXEvent *e, GdkEvent *event, gpointer d)
 {
 	Client *c = (Client *)d;
+	WebKitWebSettings *settings;
 	XPropertyEvent *ev;
 	Arg arg;
 
@@ -1386,6 +1390,11 @@ processx(GdkXEvent *e, GdkEvent *event, gpointer d)
 				arg.v = getatom(c, AtomGo);
 				loaduri(c, &arg);
 				return GDK_FILTER_REMOVE;
+			} else if (ev->atom == atoms[AtomUA]) {
+				settings = webkit_web_view_get_settings(c->view);
+				g_object_set(G_OBJECT(settings), "user-agent",
+						getatom(c, AtomUA), NULL);
+				return GDK_FILTER_REMOVE;
 			}
 		}
 	}
@@ -1488,6 +1497,7 @@ setup(void)
 	atoms[AtomFind] = XInternAtom(dpy, "_SURF_FIND", False);
 	atoms[AtomGo] = XInternAtom(dpy, "_SURF_GO", False);
 	atoms[AtomUri] = XInternAtom(dpy, "_SURF_URI", False);
+	atoms[AtomUA] = XInternAtom(dpy, "_SURF_UA", False);
 
 	/* dirs and files */
 	cookiefile = buildfile(cookiefile);
diff --git a/useragents.txt b/useragents.txt
@@ -0,0 +1,3 @@
+Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0
+Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.19 Safari/537.36
+Mozilla/5.0 (X11; U; Unix; en-US) AppleWebKit/537.15 (KHTML, like Gecko) Chrome/24.0.1295.0 Safari/537.15 Surf/0.8