aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Brendan Taylor <whateley@gmail.com>2011-02-14 21:54:00 -0700
committerGravatar Brendan Taylor <whateley@gmail.com>2011-02-14 21:54:00 -0700
commit940591850179640811bac6cf206fabae61964f55 (patch)
tree23325ce4f6899ef0dc35edc5747c5f2dd76495b6
parent7e5a921c93a580725b64fee3bdbf0af406d369a3 (diff)
parent6a737a7137c8cfbbe21bb5f0c0182ca2255a5b4c (diff)
Merge commit '6a737a7137' (keis/intcookies) into experimental
Conflicts: docs/README.uzbl-event-manager
-rw-r--r--Makefile23
-rw-r--r--README9
-rw-r--r--docs/README.cookies63
-rw-r--r--docs/README.uzbl-event-manager20
-rw-r--r--examples/config/config6
-rw-r--r--examples/data/plugins/cookies.py56
-rwxr-xr-xexamples/data/scripts/uzbl-cookie-daemon677
-rw-r--r--examples/uzbl-cookie-manager.c381
-rw-r--r--extras/vim/syntax/uzbl.vim2
-rw-r--r--src/callbacks.c10
-rw-r--r--src/callbacks.h3
-rw-r--r--src/cookie-jar.c286
-rw-r--r--src/cookie-jar.h12
-rwxr-xr-xsrc/uzbl-browser7
-rw-r--r--src/uzbl-core.c5
-rw-r--r--src/uzbl-core.h1
16 files changed, 77 insertions, 1484 deletions
diff --git a/Makefile b/Makefile
index f33a626..62bc9b5 100644
--- a/Makefile
+++ b/Makefile
@@ -41,7 +41,7 @@ HEAD = $(wildcard src/*.h)
OBJ = $(foreach obj, $(SRC:.c=.o), $(notdir $(obj)))
LOBJ = $(foreach obj, $(SRC:.c=.lo), $(notdir $(obj)))
-all: uzbl-browser uzbl-cookie-manager
+all: uzbl-browser
VPATH:=src
@@ -49,11 +49,7 @@ ${OBJ}: ${HEAD}
uzbl-core: ${OBJ}
-uzbl-cookie-manager: examples/uzbl-cookie-manager.o util.o
- @echo -e "\n${CC} -o $@ examples/uzbl-cookie-manager.o util.o ${shell pkg-config --libs glib-2.0 libsoup-2.4}"
- @${CC} -o $@ examples/uzbl-cookie-manager.o util.o $(shell pkg-config --libs glib-2.0 libsoup-2.4)
-
-uzbl-browser: uzbl-core uzbl-cookie-manager
+uzbl-browser: uzbl-core
# the 'tests' target can never be up to date
.PHONY: tests
@@ -87,10 +83,8 @@ test-uzbl-browser-sandbox: uzbl-browser
make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-uzbl-browser
make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-example-data
cp -np ./misc/env.sh ./sandbox/env.sh
- -source ./sandbox/env.sh && uzbl-cookie-manager -v
-source ./sandbox/env.sh && uzbl-event-manager restart -avv
source ./sandbox/env.sh && uzbl-browser --uri http://www.uzbl.org --verbose
- kill `cat ./sandbox/home/.cache/uzbl/cookie_daemon_socket.pid`
source ./sandbox/env.sh && uzbl-event-manager stop -ivv
make DESTDIR=./sandbox uninstall
rm -rf ./sandbox/usr
@@ -100,18 +94,20 @@ test-uzbl-tabbed-sandbox: uzbl-browser
make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-uzbl-browser
make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-example-data
cp -np ./misc/env.sh ./sandbox/env.sh
- -source ./sandbox/env.sh && uzbl-cookie-manager -v
-source ./sandbox/env.sh && uzbl-event-manager restart -avv
source ./sandbox/env.sh && ./sandbox/home/.local/share/uzbl/scripts/uzbl-tabbed
- kill `cat ./sandbox/home/.cache/uzbl/cookie_daemon_socket.pid`
source ./sandbox/env.sh && uzbl-event-manager stop -ivv
make DESTDIR=./sandbox uninstall
rm -rf ./sandbox/usr
clean:
rm -f uzbl-core
- rm -f uzbl-cookie-manager
- rm -f *.o *.lo
+ rm -f uzbl-core.o
+ rm -f events.o
+ rm -f callbacks.o
+ rm -f inspector.o
+ rm -f cookie-jar.o
+ rm -f util.o
find ./examples/ -name "*.pyc" -delete
cd ./tests/; $(MAKE) clean
rm -rf ./sandbox/
@@ -137,9 +133,8 @@ install-uzbl-core: all install-dirs
chmod 755 $(INSTALLDIR)/share/uzbl/examples/data/scripts/*
install -m755 uzbl-core $(INSTALLDIR)/bin/uzbl-core
-install-uzbl-browser: uzbl-cookie-manager install-dirs
+install-uzbl-browser: install-dirs
install -m755 src/uzbl-browser $(INSTALLDIR)/bin/uzbl-browser
- install -m755 uzbl-cookie-manager $(INSTALLDIR)/bin/uzbl-cookie-manager
install -m755 examples/data/scripts/uzbl-event-manager $(INSTALLDIR)/bin/uzbl-event-manager
mv $(INSTALLDIR)/bin/uzbl-browser $(INSTALLDIR)/bin/uzbl-browser.bak
sed 's#^PREFIX=.*#PREFIX=$(RUN_PREFIX)#' < $(INSTALLDIR)/bin/uzbl-browser.bak > $(INSTALLDIR)/bin/uzbl-browser
diff --git a/README b/README
index d1f2357..d20cbd2 100644
--- a/README
+++ b/README
@@ -183,11 +183,6 @@ The following commands are recognized:
the end, so the argument numbers will be higher.
* `sync_sh <command>`
- Synchronous version of `sh`, See `sync_spawn`.
-* `talk_to_socket <socketfile> <tokens>`
- - Send a message to `<socketfile>` and wait for a response. `<tokens>` are
- concatenated and separated by ASCII NUL bytes.
- - Expects the socket type to be `SOCK_SEQPACKET` (see `connect(2)`).
- - Waits for 500ms for a response.
* `exit`
- Closes `uzbl`.
* `search <string>`
@@ -775,12 +770,12 @@ Events/requests which the EM and its plugins listens for
move the cursor back by one character.
* `START_COMPLETION`: TODO explain completion
* `BLACKLIST_COOKIE`: add a rule for blacklisting cookies
- - `request BLACKLIST_COOKIE <component> <regexp>`: Blacklist cookies where
+ - `request BLACKLIST_COOKIE [<component> <regexp>]*`: Blacklist cookies where
`<component>` matches `<regexp>`. `<component>` is one of `domain`,
`path`, `name`, `value`, `scheme` or `expires`.
* `WHITELIST_COOKIE`: add a rule for whitelisting cookies (if any whitelist is
set then only cookies that are whitelisted cookies will be used)
- - `request WHITELIST_COOKIE <component> <regexp>`: Whitelist cookies where
+ - `request WHITELIST_COOKIE [<component> <regexp>]*`: Whitelist cookies where
`<component>` matches `<regexp>`. `<component>` is one of `domain`,
`path`, `name`, `value`, `scheme` or `expires`.
diff --git a/docs/README.cookies b/docs/README.cookies
deleted file mode 100644
index 148603f..0000000
--- a/docs/README.cookies
+++ /dev/null
@@ -1,63 +0,0 @@
-# Cookies and Uzbl #
-
-The speed of cookie lookups is important, since a single page load can involve
-dozens of HTTP requests, each of which needs a separate cookie lookup (since
-another instance of uzbl may have obtained new cookies for a site).
-
-It is possible handle cookie lookup (and storage) using a `spawn_async` cookie
-handler, but spawning new processes is inherently slow so a `talk_to_socket`
-cookie daemon (like the default uzbl-cookie-manager) is recommended.
-
-## uzbl-cookie-manager ##
-
-uzbl-cookie-manager is a cookie daemon based on libsoup's SoupCookieJar. Cookies
-are stored in a file in the Mozilla cookies.txt format (default location
-$XDG_DATA_HOME/.local/share/cookies.txt).
-
-### uzbl-cookie-manager Whitelist ###
-
-If a whitelist file is present (default location
-$XDG_CONFIG_HOME/uzbl/cookie_whitelist), then website attempts to set cookies
-will be ignored unless the site's domain is present in the whitelist.
-
-The whitelist can contain comment lines beginning with `#`, and domain lines. A
-domain line beginning with . will whitelist the given domain name and any
-subdomain of it. Otherwise only exact matches of the domain are whitelisted.
-
-For instance, given this whitelist file:
-
- example.com
- .uzbl.org
-
-uzbl-cookie-manager would accept cookies for example.com, uzbl.org and
-www.uzbl.org, but ignore cookies set for www.example.com (and any other
-domain that is not a subdomain of uzbl.org).
-
-## uzbl-cookie-daemon ##
-
-uzbl-cookie-daemon is a Python cookie daemon based on Python's cookielib.
-Cookielib's lookup algorithm isn't very efficient for our needs, so
-uzbl-cookie-daemon is noticeably slow.
-
-## Cookie Daemon Protocol ##
-
-When uzbl's `cookie_handler` variable is set to `talk_to_socket path`, uzbl
-connects to the Unix domain socket located at `path`. uzbl will send a cookie
-lookup request on this socket every time it makes an HTTP request. The format of
-this lookup request is:
-
- GET\0scheme\0host\0path\0
-
-where `\0` is the null character, `scheme` is the URL scheme (http or https),
-`host` is the hostname from the URL and `path` is the requested path. The cookie
-daemon should respond with the names and values of cookies that match the
-request, in the format used by the `Cookie` header, terminated with a `\0`.
-
-When a website adds, deletes or changes a cookie, uzbl notifies the cookie
-daemon with a request in the format:
-
- PUT\0scheme\0host\0path\0name=value\0
-
-where `scheme`, `host` and `path` are (approximately) as above, and `name=value`
-is the cookie name-value pair to store. The cookie daemon should respond by
-writing `\0` to the socket.
diff --git a/docs/README.uzbl-event-manager b/docs/README.uzbl-event-manager
index 92f0228..23e185c 100644
--- a/docs/README.uzbl-event-manager
+++ b/docs/README.uzbl-event-manager
@@ -83,20 +83,20 @@ events. If any whitelist is set, then any cookie that is not whitelisted will
be rejected. Otherwise, only cookies that have been blacklisted will be
rejected.
-BLACKLIST_COOKIE <part> <re>
- Adds a new blacklist filter. cookies where the component specified by
- `part` matches the regular expression `re` will be filtered. part can be
- either 0-5 or any of the symbolic names domain, path, name, value, scheme,
- expires
+BLACKLIST_COOKIE [<component> <re>]*
+ Adds a new blacklist filter. cookies where the components specified by
+ `component` matches the regular expression `re` will be filtered. component
+ may be either 0-5 or any of the symbolic names domain, path, name, value,
+ scheme, expires
- for example to block all cookies which name is "__utm" followed by a single
+ for example to block all cookies which name is "__utm" followed by a single
character (google analytics cookies) do.
request BLACKLIST_COOKIE name '^__utm.$'
-WHITELIST_COOKIE <part> <re>
- Adds a new whitelist filter. cookies where the component specified by
- `part` matches the regular expression `re` will be allowed. part can be any
- of the parts allowed for the BLACKLIST_COOKIE event
+WHITELIST_COOKIE [<component> <re>]*
+ Adds a new whitelist filter. cookies where the components specified by
+ `component` matches the regular expression `re` will be allowed. component
+ may be any of the components allowed for the BLACKLIST_COOKIE event
### history.py ###
- Status bar command history
diff --git a/examples/config/config b/examples/config/config
index 864d37e..bc07b0c 100644
--- a/examples/config/config
+++ b/examples/config/config
@@ -129,7 +129,11 @@ set progress.pending =
set useragent = Uzbl (Webkit @{WEBKIT_MAJOR}.@{WEBKIT_MINOR}) (@(+uname -sm)@ [@ARCH_UZBL])
# === Configure cookie blacklist ========================================================
-# Drop google analytics tracking cookies
+
+# Accept 'session cookies' from uzbl.org (when you have a whitelist all other cookies are dropped)
+#request WHITELIST_COOKIE domain 'uzbl.org$' expires '^$'
+
+# Drop google analytics tracking cookies (applied after whitelists if any)
#request BLACKLIST_COOKIE name '^__utm.$'
# === Key binding configuration ==============================================
diff --git a/examples/data/plugins/cookies.py b/examples/data/plugins/cookies.py
index c9fe2c3..6ee8798 100644
--- a/examples/data/plugins/cookies.py
+++ b/examples/data/plugins/cookies.py
@@ -38,24 +38,38 @@ class TextStore(object):
self.filename = filename
def as_event(self, cookie):
+ """Convert cookie.txt row to uzbls cookie event format"""
+ scheme = {
+ 'TRUE' : 'https',
+ 'FALSE' : 'http'
+ }
if cookie[0].startswith("#HttpOnly_"):
domain = cookie[0][len("#HttpOnly_"):]
elif cookie[0].startswith('#'):
return None
else:
domain = cookie[0]
- return (domain,
- cookie[2],
- cookie[5],
- cookie[6],
- 'https' if cookie[3] == 'TRUE' else 'http',
- cookie[4])
+ try:
+ return (domain,
+ cookie[2],
+ cookie[5],
+ cookie[6],
+ scheme[cookie[3]],
+ cookie[4])
+ except (KeyError,IndexError):
+ # Let malformed rows pass through like comments
+ return None
def as_file(self, cookie):
+ """Convert cookie event to cookie.txt row"""
+ secure = {
+ 'https' : 'TRUE',
+ 'http' : 'FALSE'
+ }
return (cookie[0],
'TRUE' if cookie[0].startswith('.') else 'FALSE',
cookie[1],
- 'TRUE' if cookie[4] == 'https' else 'FALSE',
+ secure[cookie[4]],
cookie[5],
cookie[2],
cookie[3])
@@ -92,8 +106,11 @@ DefaultStore = TextStore(os.path.join(xdg_data_home, 'uzbl/cookies.txt'))
SessionStore = TextStore(os.path.join(xdg_data_home, 'uzbl/session-cookies.txt'))
def match_list(_list, cookie):
- for component, match in _list:
- if match(cookie[component]) is not None:
+ for matcher in _list:
+ for component, match in matcher:
+ if match(cookie[component]) is None:
+ break
+ else:
return True
return False
@@ -144,18 +161,21 @@ def delete_cookie(uzbl, cookie):
store.delete_cookie(cookie, splitted)
# add a cookie matcher to a whitelist or a blacklist.
-# a matcher is a (component, re) tuple that matches a cookie when the
+# a matcher is a list of (component, re) tuples that matches a cookie when the
# "component" part of the cookie matches the regular expression "re".
# "component" is one of the keys defined in the variable "symbolic" above,
# or the index of a component of a cookie tuple.
def add_cookie_matcher(_list, arg):
- component, regexp = splitquoted(arg)
- try:
- component = symbolic[component]
- except KeyError:
- component = int(component)
- assert component <= 5
- _list.append((component, re.compile(regexp).search))
+ args = splitquoted(arg)
+ mlist = []
+ for (component, regexp) in zip(args[0::2], args[1::2]):
+ try:
+ component = symbolic[component]
+ except KeyError:
+ component = int(component)
+ assert component <= 5
+ mlist.append((component, re.compile(regexp).search))
+ _list.append(mlist)
def blacklist(uzbl, arg):
add_cookie_matcher(uzbl.cookie_blacklist, arg)
@@ -174,3 +194,5 @@ def init(uzbl):
'cookie_blacklist' : [],
'cookie_whitelist' : []
})
+
+# vi: set et ts=4:
diff --git a/examples/data/scripts/uzbl-cookie-daemon b/examples/data/scripts/uzbl-cookie-daemon
deleted file mode 100755
index 0b9bef9..0000000
--- a/examples/data/scripts/uzbl-cookie-daemon
+++ /dev/null
@@ -1,677 +0,0 @@
-#!/usr/bin/env python
-
-# The Python Cookie Daemon for Uzbl.
-# Copyright (c) 2009, Tom Adams <tom@holizz.com>
-# Copyright (c) 2009, Dieter Plaetinck <dieter@plaetinck.be>
-# Copyright (c) 2009, Mason Larobina <mason.larobina@gmail.com>
-# Copyright (c) 2009, Michael Fiano <axionix@gmail.com>
-#
-# 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/>.
-
-'''
-The Python Cookie Daemon
-========================
-
-This daemon is a re-write of the original cookies.py script found in uzbl's
-master branch. This script provides more functionality than the original
-cookies.py by adding numerous command line options to specify different cookie
-jar locations, socket locations, verbose output, etc. This functionality is
-very useful as it allows you to run multiple daemons at once serving cookies
-to different groups of uzbl instances as required.
-
-Keeping up to date
-==================
-
-Check the cookie daemon uzbl-wiki page for more information on where to
-find the latest version of the cookie_daemon.py
-
- http://www.uzbl.org/wiki/cookie_daemon.py
-
-Command line options
-====================
-
-Use the following command to get a full list of the cookie_daemon.py command
-line options:
-
- ./cookie_daemon.py --help
-
-Talking with uzbl
-=================
-
-In order to get uzbl to talk to a running cookie daemon you add the following
-to your uzbl config:
-
- set cookie_handler = talk_to_socket $XDG_CACHE_HOME/uzbl/cookie_daemon_socket
-
-Or if you prefer using the $HOME variable:
-
- set cookie_handler = talk_to_socket $HOME/.cache/uzbl/cookie_daemon_socket
-
-Todo list
-=========
-
- - Use a pid file to make force killing a running daemon possible.
-
-Reporting bugs / getting help
-=============================
-
-The best way to report bugs and or get help with the cookie daemon is to
-contact the maintainers it the #uzbl irc channel found on the Freenode IRC
-network (irc.freenode.org).
-'''
-
-import cookielib
-import os
-import sys
-import urllib2
-import select
-import socket
-import time
-import atexit
-from traceback import print_exc
-from signal import signal, SIGTERM
-from optparse import OptionParser
-from os.path import join
-
-try:
- import cStringIO as StringIO
-
-except ImportError:
- import StringIO
-
-
-# ============================================================================
-# ::: Default configuration section ::::::::::::::::::::::::::::::::::::::::::
-# ============================================================================
-
-def xdghome(key, default):
- '''Attempts to use the environ XDG_*_HOME paths if they exist otherwise
- use $HOME and the default path.'''
-
- xdgkey = "XDG_%s_HOME" % key
- if xdgkey in os.environ.keys() and os.environ[xdgkey]:
- return os.environ[xdgkey]
-
- return join(os.environ['HOME'], default)
-
-# Setup xdg paths.
-CACHE_DIR = join(xdghome('CACHE', '.cache/'), 'uzbl/')
-DATA_DIR = join(xdghome('DATA', '.local/share/'), 'uzbl/')
-CONFIG_DIR = join(xdghome('CONFIG', '.config/'), 'uzbl/')
-
-# Ensure data paths exist.
-for path in [CACHE_DIR, DATA_DIR, CONFIG_DIR]:
- if not os.path.exists(path):
- os.makedirs(path)
-
-# Default config
-config = {
-
- # Default cookie jar, whitelist, and daemon socket locations.
- 'cookie_jar': join(DATA_DIR, 'cookies.txt'),
- 'cookie_whitelist': join(CONFIG_DIR, 'cookie_whitelist'),
- 'cookie_socket': join(CACHE_DIR, 'cookie_daemon_socket'),
-
- # Don't use a cookie whitelist policy by default.
- 'use_whitelist': False,
-
- # Time out after x seconds of inactivity (set to 0 for never time out).
- # WARNING: Do not use this option if you are manually launching the daemon.
- 'daemon_timeout': 0,
-
- # Daemonise by default.
- 'daemon_mode': True,
-
- # Optionally print helpful debugging messages to the terminal.
- 'verbose': False,
-
-} # End of config dictionary.
-
-
-# ============================================================================
-# ::: End of configuration section :::::::::::::::::::::::::::::::::::::::::::
-# ============================================================================
-
-
-_SCRIPTNAME = os.path.basename(sys.argv[0])
-def echo(msg):
- '''Prints only if the verbose flag has been set.'''
-
- if config['verbose']:
- sys.stderr.write("%s: %s\n" % (_SCRIPTNAME, msg))
-
-
-def error(msg):
- '''Prints error message and exits.'''
-
- sys.stderr.write("%s: error: %s\n" % (_SCRIPTNAME, msg))
- sys.exit(1)
-
-
-def mkbasedir(filepath):
- '''Create the base directories of the file in the file-path if the dirs
- don't exist.'''
-
- dirname = os.path.dirname(filepath)
- if not os.path.exists(dirname):
- echo("creating dirs: %r" % dirname)
- os.makedirs(dirname)
-
-
-def daemon_running(cookie_socket):
- '''Check if another process (hopefully a cookie_daemon.py) is listening
- on the cookie daemon socket. If another process is found to be
- listening on the socket exit the daemon immediately and leave the
- socket alone. If the connect fails assume the socket has been abandoned
- and delete it (to be re-created in the create socket function).'''
-
- if not os.path.exists(cookie_socket):
- return False
-
- if os.path.isfile(cookie_socket):
- raise Exception("regular file at %r is not a socket" % cookie_socket)
-
-
- if os.path.isdir(cookie_socket):
- raise Exception("directory at %r is not a socket" % cookie_socket)
-
- try:
- sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
- sock.connect(cookie_socket)
- sock.close()
- echo("detected daemon listening on %r" % cookie_socket)
- return True
-
- except socket.error:
- # Failed to connect to cookie_socket so assume it has been
- # abandoned by another cookie daemon process.
- if os.path.exists(cookie_socket):
- echo("deleting abandoned socket at %r" % cookie_socket)
- os.remove(cookie_socket)
-
- return False
-
-
-def send_command(cookie_socket, cmd):
- '''Send a command to a running cookie daemon.'''
-
- if not daemon_running(cookie_socket):
- return False
-
- try:
- sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
- sock.connect(cookie_socket)
- sock.send(cmd)
- sock.close()
- echo("sent command %r to %r" % (cmd, cookie_socket))
- return True
-
- except socket.error:
- print_exc()
- error("failed to send message %r to %r" % (cmd, cookie_socket))
- return False
-
-
-def kill_daemon(cookie_socket):
- '''Send the "EXIT" command to running cookie_daemon.'''
-
- if send_command(cookie_socket, "EXIT"):
- # Now ensure the cookie_socket is cleaned up.
- start = time.time()
- while os.path.exists(cookie_socket):
- time.sleep(0.1)
- if (time.time() - start) > 5:
- error("force deleting socket %r" % cookie_socket)
- os.remove(cookie_socket)
- return
-
- echo("stopped daemon listening on %r"% cookie_socket)
-
- else:
- if os.path.exists(cookie_socket):
- os.remove(cookie_socket)
- echo("removed abandoned/broken socket %r" % cookie_socket)
-
-
-def daemonize():
- '''Daemonize the process using the Stevens' double-fork magic.'''
-
- try:
- if os.fork():
- os._exit(0)
-
- except OSError:
- print_exc()
- sys.stderr.write("fork #1 failed")
- sys.exit(1)
-
- os.chdir('/')
- os.setsid()
- os.umask(0)
-
- try:
- if os.fork():
- os._exit(0)
-
- except OSError:
- print_exc()
- sys.stderr.write("fork #2 failed")
- sys.exit(1)
-
- if sys.stdout.isatty():
- sys.stdout.flush()
- sys.stderr.flush()
-
- devnull = '/dev/null'
- stdin = file(devnull, 'r')
- stdout = file(devnull, 'a+')
- stderr = file(devnull, 'a+', 0)
-
- os.dup2(stdin.fileno(), sys.stdin.fileno())
- os.dup2(stdout.fileno(), sys.stdout.fileno())
- os.dup2(stderr.fileno(), sys.stderr.fileno())
-
-
-class CookieMonster:
- '''The uzbl cookie daemon class.'''
-
- def __init__(self):
- '''Initialise class variables.'''
-
- self.server_socket = None
- self.jar = None
- self.last_request = time.time()
- self._running = False
-
-
- def run(self):
- '''Start the daemon.'''
-
- # The check healthy function will exit if another daemon is detected
- # listening on the cookie socket and remove the abandoned socket if
- # there isnt.
- if os.path.exists(config['cookie_socket']):
- if daemon_running(config['cookie_socket']):
- sys.exit(1)
-
- # Create cookie daemon socket.
- self.create_socket()
-
- # Daemonize process.
- if config['daemon_mode']:
- echo("entering daemon mode")
- daemonize()
-
- # Register a function to cleanup on exit.
- atexit.register(self.quit)
-
- # Make SIGTERM act orderly.
- signal(SIGTERM, lambda signum, stack_frame: sys.exit(1))
-
- # Create cookie jar object from file.
- self.open_cookie_jar()
-
- # Create a way to exit nested loops by setting a running flag.
- self._running = True
-
- while self._running:
- try:
- # Enter main listen loop.
- self.listen()
-
- except KeyboardInterrupt:
- self._running = False
- print
-
- except socket.error:
- print_exc()
-
- except:
- # Clean up
- self.del_socket()
-
- # Raise exception
- raise
-
- # Always delete the socket before calling create again.
- self.del_socket()
- # Create cookie daemon socket.
- self.create_socket()
-
-
- def load_whitelist(self):
- '''Load the cookie jar whitelist policy.'''
-
- cookie_whitelist = config['cookie_whitelist']
-
- if cookie_whitelist:
- mkbasedir(cookie_whitelist)
-
- # Create cookie whitelist file if it does not exist.
- if not os.path.exists(cookie_whitelist):
- open(cookie_whitelist, 'w').close()
-
- # Read cookie whitelist file into list.
- file = open(cookie_whitelist,'r')
- domain_list = [line.rstrip('\n') for line in file]
- file.close()
-
- # Define policy of allowed domains
- policy = cookielib.DefaultCookiePolicy(allowed_domains=domain_list)
- self.jar.set_policy(policy)
-
- # Save the last modified time of the whitelist.
- self._whitelistmtime = os.stat(cookie_whitelist).st_mtime
-
-
- def open_cookie_jar(self):
- '''Open the cookie jar.'''
-
- cookie_jar = config['cookie_jar']
- cookie_whitelist = config['cookie_whitelist']
-
- if cookie_jar:
- mkbasedir(cookie_jar)
-
- # Create cookie jar object from file.
- self.jar = cookielib.MozillaCookieJar(cookie_jar)
-
- # Load cookie whitelist policy.
- if config['use_whitelist']:
- self.load_whitelist()
-
- if cookie_jar:
- try:
- # Attempt to load cookies from the cookie jar.
- self.jar.load(ignore_discard=True)
-
- # Ensure restrictive permissions are set on the cookie jar
- # to prevent other users on the system from hi-jacking your
- # authenticated sessions simply by copying your cookie jar.
- os.chmod(cookie_jar, 0600)
-
- except:
- pass
-
-
- def reload_whitelist(self):
- '''Reload the cookie whitelist.'''
-
- cookie_whitelist = config['cookie_whitelist']
- if os.path.exists(cookie_whitelist):
- echo("reloading whitelist %r" % cookie_whitelist)
- self.open_cookie_jar()
-
-
- def create_socket(self):
- '''Create AF_UNIX socket for communication with uzbl instances.'''
-
- cookie_socket = config['cookie_socket']
- mkbasedir(cookie_socket)
-
- self.server_socket = socket.socket(socket.AF_UNIX,
- socket.SOCK_SEQPACKET)
-
- self.server_socket.bind(cookie_socket)
-
- # Set restrictive permissions on the cookie socket to prevent other
- # users on the system from data-mining your cookies.
- os.chmod(cookie_socket, 0600)
-
-
- def listen(self):
- '''Listen for incoming cookie PUT and GET requests.'''
-
- daemon_timeout = config['daemon_timeout']
- echo("listening on %r" % config['cookie_socket'])
-
- connections = []
-
- while self._running:
- # This line tells the socket how many pending incoming connections
- # to enqueue at once. Raising this number may or may not increase
- # performance.
- self.server_socket.listen(1)
-
- r, w, x = select.select([self.server_socket]+connections, [], [], 1)
-
- for socket in r:
- if self.server_socket == socket:
- client_socket, _ = socket.accept()
- connections.append(client_socket)
- else:
- if not self.handle_request(socket):
- # connection was closed, forget about the client socket
- connections.remove(socket)
-
- self.last_request = time.time()
-
- if daemon_timeout:
- # Checks if the daemon has been idling for too long.
- idle = time.time() - self.last_request
- if idle > daemon_timeout:
- self._running = False
-
-
- def handle_request(self, client_socket):
- '''Connection made, now to serve a cookie PUT or GET request.'''
-
- # Receive cookie request from client.
- data = client_socket.recv(8192)
- if not data:
- return False
-
- # Cookie argument list in packet is null separated.
- argv = data.split("\0")
- action = argv[0].upper().strip()
-
- # Catch the EXIT command sent to kill running daemons.
- if action == "EXIT":
- self._running = False
- return False
-
- # Catch whitelist RELOAD command.
- elif action == "RELOAD":
- self.reload_whitelist()
- return True
-
- # Return if command unknown.
- elif action not in ['GET', 'PUT']:
- error("unknown command %r." % argv)
- return True
-
- # Determine whether or not to print cookie data to terminal.
- print_cookie = (config['verbose'] and not config['daemon_mode'])
- if print_cookie:
- print ' '.join(argv[:4])
-
- uri = urllib2.urlparse.ParseResult(
- scheme=argv[1],
- netloc=argv[2],
- path=argv[3],
- params='',
- query='',
- fragment='').geturl()
-
- req = urllib2.Request(uri)
-
- if action == "GET":
- self.jar._policy._now = self._now = int(time.time())
- cookies = self.jar._cookies_for_request(req)
- attrs = self.jar._cookie_attrs(cookies)
- if attrs:
- cookie = "; ".join(attrs)
- client_socket.send(cookie)
- if print_cookie:
- print cookie
- else:
- client_socket.send("\0")
-
- elif action == "PUT":
- cookie = argv[4] if len(argv) > 3 else None
- if print_cookie:
- print cookie
-
- self.put_cookie(req, cookie)
- client_socket.send("\0")
-
- if print_cookie:
- print
-
- return True
-
-
- def put_cookie(self, req, cookie=None):
- '''Put a cookie in the cookie jar.'''
-
- hdr = urllib2.httplib.HTTPMessage(\
- StringIO.StringIO('Set-Cookie: %s' % cookie))
- res = urllib2.addinfourl(StringIO.StringIO(), hdr,
- req.get_full_url())
- self.jar.extract_cookies(res, req)
- if config['cookie_jar']:
- self.jar.save(ignore_discard=True)
-
-
- def del_socket(self):
- '''Remove the cookie_socket file on exit. In a way the cookie_socket
- is the daemons pid file equivalent.'''
-
- if self.server_socket:
- try:
- self.server_socket.close()
-
- except:
- pass
-
- self.server_socket = None
-
- cookie_socket = config['cookie_socket']
- if os.path.exists(cookie_socket):
- echo("deleting socket %r" % cookie_socket)
- os.remove(cookie_socket)
-
-
- def quit(self):
- '''Called on exit to make sure all loose ends are tied up.'''
-
- self.del_socket()
- sys.exit(0)
-
-
-def main():
- '''Main function.'''
-
- # Define command line parameters.
- usage = "usage: %prog [options] {start|stop|restart|reload}"
- parser = OptionParser(usage=usage)
- parser.add_option('-n', '--no-daemon', dest='no_daemon',
- action='store_true', help="don't daemonise the process.")
-
- parser.add_option('-v', '--verbose', dest="verbose",
- action='store_true', help="print verbose output.")
-
- parser.add_option('-t', '--daemon-timeout', dest='daemon_timeout',
- action="store", metavar="SECONDS", help="shutdown the daemon after x "\
- "seconds inactivity. WARNING: Do not use this when launching the "\
- "cookie daemon manually.")
-
- parser.add_option('-s', '--cookie-socket', dest="cookie_socket",
- metavar="SOCKET", help="manually specify the socket location.")
-
- parser.add_option('-j', '--cookie-jar', dest='cookie_jar',
- metavar="FILE", help="manually specify the cookie jar location.")
-
- parser.add_option('-m', '--memory', dest='memory', action='store_true',
- help="store cookies in memory only - do not write to disk")
-
- parser.add_option('-u', '--use-whitelist', dest='usewhitelist',
- action='store_true', help="use cookie whitelist policy")
-
- parser.add_option('-w', '--cookie-whitelist', dest='whitelist',
- action='store', help="manually specify whitelist location",
- metavar='FILE')
-
- # Parse the command line arguments.
- (options, args) = parser.parse_args()
-
- expand = lambda p: os.path.realpath(os.path.expandvars(p))
-
- initcommands = ['start', 'stop', 'restart', 'reload']
- for arg in args:
- if arg not in initcommands:
- error("unknown argument %r" % args[0])
- sys.exit(1)
-
- if len(args) > 1:
- error("the daemon only accepts one {%s} action at a time."
- % '|'.join(initcommands))
- sys.exit(1)
-
- if len(args):
- action = args[0]
-
- else:
- action = "start"
-
- if options.no_daemon:
- config['daemon_mode'] = False
-
- if options.cookie_socket:
- config['cookie_socket'] = expand(options.cookie_socket)
-
- if options.cookie_jar:
- config['cookie_jar'] = expand(options.cookie_jar)
-
- if options.memory:
- config['cookie_jar'] = None
-
- if options.whitelist:
- config['cookie_whitelist'] = expand(options.whitelist)
-
- if options.whitelist or options.usewhitelist:
- config['use_whitelist'] = True
-
- if options.daemon_timeout:
- try:
- config['daemon_timeout'] = int(options.daemon_timeout)
-
- except ValueError:
- error("expected int argument for -t, --daemon-timeout")
-
- # Expand $VAR's in config keys that relate to paths.
- for key in ['cookie_socket', 'cookie_jar', 'cookie_whitelist']:
- if config[key]:
- config[key] = os.path.expandvars(config[key])
-
- if options.verbose:
- config['verbose'] = True
- import pprint
- sys.stderr.write("%s\n" % pprint.pformat(config))
-
- # It would be better if we didn't need to start this python process just
- # to send a command to the socket, but unfortunately socat doesn't seem
- # to support SEQPACKET.
- if action == "reload":
- send_command(config['cookie_socket'], "RELOAD")
-
- if action in ['stop', 'restart']:
- kill_daemon(config['cookie_socket'])
-
- if action in ['start', 'restart']:
- CookieMonster().run()
-
-
-if __name__ == "__main__":
- main()
diff --git a/examples/uzbl-cookie-manager.c b/examples/uzbl-cookie-manager.c
deleted file mode 100644
index 70addf3..0000000
--- a/examples/uzbl-cookie-manager.c
+++ /dev/null
@@ -1,381 +0,0 @@
-#define _POSIX_SOURCE
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <ctype.h>
-#include <signal.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/select.h>
-#include <sys/unistd.h>
-
-#include <sys/stat.h>
-#include <sys/file.h>
-#include <fcntl.h>
-#include <stdlib.h>
-
-#include <libsoup/soup-cookie.h>
-#include <libsoup/soup-cookie-jar-text.h>
-#include <libsoup/soup-uri.h>
-
-#include "../src/util.h"
-
-extern const XDG_Var XDG[];
-
-int verbose = 0;
-
-#define SOCK_BACKLOG 10
-#define MAX_COOKIE_LENGTH 4096
-
-char cookie_buffer[MAX_COOKIE_LENGTH];
-
-int setup_socket(const char *cookied_socket_path) {
- /* delete the cookie socket if it was left behind on a previous run */
- unlink(cookied_socket_path);
-
- int socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-
- if(socket_fd < 0) {
- fprintf(stderr, "socket failed (%s)\n", strerror(errno));
- return -1;
- }
-
- struct sockaddr_un sa;
- sa.sun_family = AF_UNIX;
- strcpy(sa.sun_path, cookied_socket_path);
-
- if(bind(socket_fd, (struct sockaddr*)&sa, sizeof(sa)) < 0) {
- fprintf(stderr, "bind failed (%s)\n", strerror(errno));
- return -1;
- }
-
- if(listen(socket_fd, SOCK_BACKLOG) < 0) {
- fprintf(stderr, "listen failed (%s)\n", strerror(errno));
- return -1;
- }
-
- return socket_fd;
-}
-
-const char *whitelist_path = NULL;
-GPtrArray *whitelisted_hosts = NULL;
-time_t whitelist_update_time = 0;
-
-void whitelist_line_cb(const gchar* line, void *user_data) {
- (void) user_data;
-
- gchar *norm_host;
-
- const gchar *p = line;
- while(isspace(*p))
- p++;
-
- if(p[0] == '#' || !p[0]) /* ignore comments and blank lines */
- return;
-
- if(p[0] == '.')
- norm_host = g_strdup(p);
- else
- norm_host = g_strconcat(".", p, NULL);
-
- g_ptr_array_add(whitelisted_hosts, g_strchomp(norm_host));
-}
-
-gboolean load_whitelist(const char *whitelist_path) {
- if(!file_exists(whitelist_path))
- return FALSE;
-
- /* check if the whitelist file was updated */
- struct stat f;
- if(stat(whitelist_path, &f) < 0)
- return FALSE;
-
- if(whitelisted_hosts == NULL)
- whitelisted_hosts = g_ptr_array_new();
-
- if(f.st_mtime > whitelist_update_time) {
- /* the file was updated, reload the whitelist */
- if(verbose) puts("reloading whitelist");
- while(whitelisted_hosts->len > 0) {
- g_free(g_ptr_array_index(whitelisted_hosts, 0));
- g_ptr_array_remove_index_fast(whitelisted_hosts, 0);
- }
- for_each_line_in_file(whitelist_path, whitelist_line_cb, NULL);
- whitelist_update_time = f.st_mtime;
- }
-
- return TRUE;
-}
-
-gboolean should_save_cookie(const char *host) {
- if(!load_whitelist(whitelist_path))
- return TRUE; /* some error with the file, assume no whitelist */
-
- /* we normalize the hostname so it has a . in front like the whitelist entries */
- gchar *test_host = (host[0] == '.') ? g_strdup(host) : g_strconcat(".", host, NULL);
- int hl = strlen(test_host);
-
- /* test against each entry in the whitelist */
- gboolean result = FALSE;
- guint i;
- for(i = 0; i < whitelisted_hosts->len; i++) {
- /* a match means the host ends with (or is equal to) the whitelist entry */
- const gchar *entry = g_ptr_array_index(whitelisted_hosts, i);
- int el = strlen(entry);
- result = (el <= hl) && !strcmp(test_host + (hl - el), entry);
-
- if(result)
- break;
- }
-
- g_free(test_host);
-
- return result;
-}
-
-void handle_request(SoupCookieJar *j, const char *buff, int len, int fd) {
- const char *command = buff;
-
- const char *scheme = command + strlen(command) + 1;
- if((scheme - buff) > len) {
- fprintf(stderr, "got malformed or partial request\n");
- return;
- }
-
- const char *host = scheme + strlen(scheme) + 1;
- if((host - buff) > len) {
- fprintf(stderr, "got malformed or partial request\n");
- return;
- }
-
- const char *path = host + strlen(host) + 1;
- if((path - buff) > len) {
- fprintf(stderr, "got malformed or partial request\n");
- return;
- }
-
- /* glue the parts back together into a SoupURI */
- char *u = g_strconcat(scheme, "://", host, path, NULL);
- if(verbose) printf("%s %s\n", command, u);
- SoupURI *uri = soup_uri_new(u);
- g_free(u);
-
- if(!strcmp(command, "GET")) {
- char *result = soup_cookie_jar_get_cookies(j, uri, TRUE);
- if(result) {
- if(verbose) puts(result);
- if(write(fd, result, strlen(result)+1) < 0)
- fprintf(stderr, "write failed (%s)", strerror(errno));
-
- g_free(result);
- } else {
- if(verbose) puts("-");
- if(write(fd, "", 1) < 0)
- fprintf(stderr, "write failed (%s)", strerror(errno));
- }
- } else if(!strcmp(command, "PUT")) {
- const char *name_and_val = path + strlen(path) + 1;
- if((name_and_val - buff) > len) {
- fprintf(stderr, "got malformed or partial request\n");
- return;
- }
-
- if(verbose) puts(name_and_val);
-
- if(should_save_cookie(host)) {
- char *eql = strchr(name_and_val, '=');
- eql[0] = 0;
-
- const char *name = name_and_val;
- const char *value = eql + 1;
-
- SoupCookie *cookie = soup_cookie_new(name, value, host, path, SOUP_COOKIE_MAX_AGE_ONE_YEAR);
-
- soup_cookie_jar_add_cookie(j, cookie);
- } else if(verbose)
- puts("no, blacklisted.");
-
- if(write(fd, "", 1) < 0)
- fprintf(stderr, "write failed (%s)", strerror(errno));
- }
-
- soup_uri_free(uri);
-}
-
-void
-wait_for_things_to_happen_and_then_do_things(SoupCookieJar* j, int cookie_socket) {
- GArray *connections = g_array_new (FALSE, FALSE, sizeof (int));
-
- while(1) {
- unsigned int i;
- int r;
- fd_set fs;
-
- int maxfd = cookie_socket;
- FD_ZERO(&fs);
- FD_SET(maxfd, &fs);
-
- for(i = 0; i < connections->len; i++) {
- int fd = g_array_index(connections, int, i);
- if(fd > maxfd) maxfd = fd;
- FD_SET(fd, &fs);
- }
-
- r = select(maxfd+1, &fs, NULL, NULL, NULL);
- if(r < 0) {
- fprintf(stderr, "select failed (%s)\n", strerror(errno));
- continue;
- }
-
- if(FD_ISSET(cookie_socket, &fs)) {
- /* handle new connection */
- int fd = accept(cookie_socket, NULL, NULL);
- g_array_append_val(connections, fd);
- if(verbose) puts("got connection.");
- }
-
- for(i = 0; i < connections->len; i++) {
- /* handle activity on a connection */
- int fd = g_array_index(connections, int, i);
- if(FD_ISSET(fd, &fs)) {
- r = read(fd, cookie_buffer, MAX_COOKIE_LENGTH);
- if(r < 0) {
- fprintf(stderr, "read failed (%s)\n", strerror(errno));
- continue;
- } else if(r == 0) {
- if(verbose) puts("client hung up.");
- g_array_remove_index(connections, i);
- i--; /* other elements in the array are moved down to fill the gap */
- continue;
- }
- cookie_buffer[r] = 0;
-
- handle_request(j, cookie_buffer, r, fd);
- }
- }
- }
-}
-
-void usage(const char *progname) {
- printf("%s [-s socket-path] [-f cookies.txt] [-w whitelist-file] [-n] [-v]\n", progname);
- puts("\t-n\tdon't daemonise the process");
- puts("\t-v\tbe verbose");
-}
-
-void daemonise() {
- int r = fork();
-
- if(r < 0) {
- fprintf(stderr, "fork failed (%s)", strerror(errno));
- exit(1);
- } else if (r > 0) {
- /* this is the parent, which has done its job */
- exit(0);
- }
-
- if(setsid() < 0) {
- fprintf(stderr, "setsid failed (%s)", strerror(errno));
- exit(1);
- }
-}
-
-const char *pid_file_path = NULL;
-const char *cookied_socket_path = NULL;
-
-void cleanup_after_signal(int signal) {
- (void) signal;
- unlink(pid_file_path);
- unlink(cookied_socket_path);
- exit(0);
-}
-
-int main(int argc, char *argv[]) {
- int i;
-
- const char *cookies_txt_path = NULL;
- gboolean foreground = FALSE;
-
- for(i = 1; i < argc && argv[i][0] == '-'; i++) {
- switch(argv[i][1]) {
- case 's':
- cookied_socket_path = argv[++i];
- break;
- case 'f':
- cookies_txt_path = argv[++i];
- break;
- case 'w':
- whitelist_path = argv[++i];
- break;
- case 'n':
- foreground = TRUE;
- break;
- case 'v':
- verbose = 1;
- break;
- default:
- usage(argv[0]);
- return 1;
- }
- }
-
- if(!foreground)
- daemonise();
-
- if(!cookies_txt_path)
- cookies_txt_path = g_strconcat(get_xdg_var(XDG[1]), "/uzbl/cookies.txt", NULL);
-
- if(!cookied_socket_path)
- cookied_socket_path = g_strconcat(get_xdg_var(XDG[2]), "/uzbl/cookie_daemon_socket", NULL);
-
- if(!whitelist_path)
- whitelist_path = g_strconcat(get_xdg_var(XDG[0]), "/uzbl/cookie_whitelist", NULL);
-
- /* write out and lock the pid file.
- * this ensures that only one uzbl-cookie-manager is running per-socket.
- * (we should probably also lock the cookies.txt to prevent accidents...) */
- pid_file_path = g_strconcat(cookied_socket_path, ".pid", NULL);
- int lockfd = open(pid_file_path, O_RDWR|O_CREAT, 0600);
- if(lockfd < 0) {
- fprintf(stderr, "couldn't open pid file %s (%s)\n", pid_file_path, strerror(errno));
- return 1;
- }
-
- if(flock(lockfd, LOCK_EX|LOCK_NB) < 0) {
- fprintf(stderr, "couldn't lock pid file %s (%s)\n", pid_file_path, strerror(errno));
- fprintf(stderr, "uzbl-cookie-manager is probably already running\n");
- return 1;
- }
-
- gchar* pids = g_strdup_printf("%d\n", getpid());
- write(lockfd, pids, strlen(pids));
- g_free(pids);
-
- struct sigaction sa;
- sa.sa_handler = cleanup_after_signal;
- if(sigaction(SIGINT, &sa, NULL) || sigaction(SIGTERM, &sa, NULL)) {
- fprintf(stderr, "sigaction failed (%s)\n", strerror(errno));
- return 1;
- }
-
- if(!foreground) {
- /* close STDIO */
- close(0);
- close(1);
- close(2);
- }
-
- g_type_init();
-
- SoupCookieJar *j = soup_cookie_jar_text_new(cookies_txt_path, FALSE);
-
- int cookie_socket = setup_socket(cookied_socket_path);
- if(cookie_socket < 0)
- return 1;
-
- wait_for_things_to_happen_and_then_do_things(j, cookie_socket);
-
- return 0;
-}
diff --git a/extras/vim/syntax/uzbl.vim b/extras/vim/syntax/uzbl.vim
index b8572c9..bf7108c 100644
--- a/extras/vim/syntax/uzbl.vim
+++ b/extras/vim/syntax/uzbl.vim
@@ -30,7 +30,7 @@ setl iskeyword=!-~,192-255
syn keyword uzblKeyword back forward scroll reload reload_ign_cache stop
syn keyword uzblKeyword zoom_in zoom_out toggle_zoom_type uri script
-syn keyword uzblKeyword toggle_status spawn sync_spawn sync_sh talk_to_socket
+syn keyword uzblKeyword toggle_status spawn sync_spawn sync_sh sync_spawn_exec
syn keyword uzblKeyword exit search search_reverse search_clear dehilight set
syn keyword uzblKeyword dump_config dump_config_as_events chain print event
syn keyword uzblKeyword request menu_add menu_link_add menu_image_add
diff --git a/src/callbacks.c b/src/callbacks.c
index 8cfb073..77b7cb6 100644
--- a/src/callbacks.c
+++ b/src/callbacks.c
@@ -1003,13 +1003,3 @@ populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) {
}
}
}
-
-void
-cmd_set_cookie_handler() {
- if(uzbl.behave.cookie_handler[0] == 0) {
- g_free(uzbl.behave.cookie_handler);
- uzbl.behave.cookie_handler = NULL;
- }
-
- uzbl_cookie_jar_set_handler(uzbl.net.soup_cookie_jar, uzbl.behave.cookie_handler);
-}
diff --git a/src/callbacks.h b/src/callbacks.h
index 899e959..13cb83d 100644
--- a/src/callbacks.h
+++ b/src/callbacks.h
@@ -216,6 +216,3 @@ scroll_vert_cb(GtkAdjustment *adjust, void *w);
gboolean
scroll_horiz_cb(GtkAdjustment *adjust, void *w);
-
-void
-cmd_set_cookie_handler();
diff --git a/src/cookie-jar.c b/src/cookie-jar.c
index 626e454..82a5269 100644
--- a/src/cookie-jar.c
+++ b/src/cookie-jar.c
@@ -1,51 +1,20 @@
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <poll.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <string.h>
-#include <errno.h>
-
-#include <libsoup/soup-uri.h>
#include <libsoup/soup-cookie.h>
#include "cookie-jar.h"
#include "uzbl-core.h"
#include "events.h"
-static void
-uzbl_cookie_jar_session_feature_init(SoupSessionFeatureInterface *iface, gpointer user_data);
-
-G_DEFINE_TYPE_WITH_CODE (UzblCookieJar, soup_cookie_jar_socket, SOUP_TYPE_COOKIE_JAR,
- G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE, uzbl_cookie_jar_session_feature_init))
+G_DEFINE_TYPE (UzblCookieJar, soup_cookie_jar_socket, SOUP_TYPE_COOKIE_JAR)
-static void request_started (SoupSessionFeature *feature, SoupSession *session, SoupMessage *msg, SoupSocket *socket);
static void changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie);
-static void setup_handler(UzblCookieJar *jar);
-
-static void connect_cookie_socket(UzblCookieJar *jar);
-static void disconnect_cookie_socket(UzblCookieJar *jar);
-
-static gchar *do_socket_request(UzblCookieJar *jar, gchar *request, int request_len);
-
-static bool has_socket_handler(UzblCookieJar *jar) {
- return jar->socket_path != NULL;
-}
-
static void
soup_cookie_jar_socket_init(UzblCookieJar *jar) {
- jar->handler = NULL;
- jar->socket_path = NULL;
- jar->connection_fd = -1;
- jar->in_get_callback = 0;
jar->in_manual_add = 0;
}
static void
finalize(GObject *object) {
- disconnect_cookie_socket(UZBL_COOKIE_JAR(object));
G_OBJECT_CLASS(soup_cookie_jar_socket_parent_class)->finalize(object);
}
@@ -55,120 +24,30 @@ soup_cookie_jar_socket_class_init(UzblCookieJarClass *socket_class) {
SOUP_COOKIE_JAR_CLASS(socket_class)->changed = changed;
}
-/* override SoupCookieJar's request_started handler */
-static void
-uzbl_cookie_jar_session_feature_init(SoupSessionFeatureInterface *iface, gpointer user_data) {
- (void) user_data;
- iface->request_started = request_started;
-}
-
UzblCookieJar *uzbl_cookie_jar_new() {
return g_object_new(UZBL_TYPE_COOKIE_JAR, NULL);
}
-void
-uzbl_cookie_jar_set_handler(UzblCookieJar *jar, const gchar* handler) {
- jar->handler = handler;
- setup_handler(jar);
-}
-
-char *get_cookies(UzblCookieJar *jar, SoupURI *uri) {
- gchar *result, *path;
- GString *s = g_string_new ("GET");
-
- path = uri->path[0] ? uri->path : "/";
-
- if(has_socket_handler(jar)) {
- g_string_append_c(s, 0); /* null-terminate the GET */
- g_string_append_len(s, uri->scheme, strlen(uri->scheme)+1);
- g_string_append_len(s, uri->host, strlen(uri->host)+1 );
- g_string_append_len(s, path, strlen(path)+1 );
-
- result = do_socket_request(jar, s->str, s->len);
- /* try it again; older cookie daemons closed the connection after each request */
- if(result == NULL)
- result = do_socket_request(jar, s->str, s->len);
- } else {
- g_string_append_printf(s, " '%s' '%s' '%s'", uri->scheme, uri->host, uri->path);
-
- run_handler(jar->handler, s->str);
- result = g_strdup(uzbl.comm.sync_stdout);
- }
- g_string_free(s, TRUE);
- return result;
-}
-
-/* this is a duplicate of SoupCookieJar's request_started that uses our get_cookies instead */
-static void
-request_started(SoupSessionFeature *feature, SoupSession *session,
- SoupMessage *msg, SoupSocket *socket) {
- (void) session; (void) socket;
- gchar *cookies;
-
- UzblCookieJar *jar = UZBL_COOKIE_JAR (feature);
- SoupURI *uri = soup_message_get_uri(msg);
- gboolean add_to_internal_jar = false;
-
- if(jar->handler) {
- cookies = get_cookies(jar, uri);
- } else {
- /* no handler is set, fall back to the internal soup cookie jar */
- cookies = soup_cookie_jar_get_cookies(SOUP_COOKIE_JAR(jar), soup_message_get_uri (msg), TRUE);
- }
-
- if (cookies && cookies[0] != 0) {
- const gchar *next_cookie_start = cookies;
-
- if (add_to_internal_jar) {
- /* add the cookie data that we just obtained from the cookie handler
- to the cookie jar so that javascript has access to them.
- we set this flag so that we don't trigger the PUT handler. */
- jar->in_get_callback = true;
- do {
- SoupCookie *soup_cookie = soup_cookie_parse(next_cookie_start, uri);
- if(soup_cookie)
- soup_cookie_jar_add_cookie(SOUP_COOKIE_JAR(uzbl.net.soup_cookie_jar), soup_cookie);
- next_cookie_start = strchr(next_cookie_start, ';');
- } while(next_cookie_start++ != NULL);
- jar->in_get_callback = false;
- }
-
- soup_message_headers_replace (msg->request_headers, "Cookie", cookies);
- } else {
- soup_message_headers_remove (msg->request_headers, "Cookie");
- }
-
- if(cookies)
- g_free (cookies);
-}
-
static void
changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) {
- SoupCookie * cookie = new_cookie ? new_cookie : old_cookie;
+ SoupCookie *cookie = new_cookie ? new_cookie : old_cookie;
UzblCookieJar *uzbl_jar = UZBL_COOKIE_JAR(jar);
- /* when Uzbl begins an HTTP request, it GETs cookies from the handler
- and then adds them to the cookie jar so that javascript can access
- these cookies. this causes a 'changed' callback, which we don't want
- to do anything, so we just return.
-
- (if SoupCookieJar let us override soup_cookie_jar_get_cookies we
- wouldn't have to do this.) */
- if(uzbl_jar->in_get_callback)
- return;
-
- gchar *scheme = cookie->secure ? "https" : "http";
-
- /* send a ADD or DELETE -_COOKIE event depending on what have changed */
+ /* send a ADD or DELETE -_COOKIE event depending on what has changed. these
+ * events aren't sent when a cookie changes due to an add/delete_cookie
+ * command because otherwise a loop would occur when a cookie change is
+ * propagated to other uzbl instances using add/delete_cookie. */
if(!uzbl_jar->in_manual_add) {
+ gchar *scheme = cookie->secure ? "https" : "http";
+
gchar *expires = NULL;
if(cookie->expires)
expires = g_strdup_printf ("%d", soup_date_to_time_t (cookie->expires));
gchar * eventstr = g_strdup_printf ("'%s' '%s' '%s' '%s' '%s' '%s'",
cookie->domain, cookie->path, cookie->name, cookie->value, scheme, expires?expires:"");
- if(new_cookie)
+ if(new_cookie)
send_event(ADD_COOKIE, eventstr, NULL);
else
send_event(DELETE_COOKIE, eventstr, NULL);
@@ -176,151 +55,4 @@ changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) {
if(expires)
g_free(expires);
}
-
- /* the cookie daemon is only interested in new cookies and changed
- ones, it can take care of deleting expired cookies on its own. */
- if(!new_cookie)
- return;
-
- GString *s = g_string_new ("PUT");
-
- if(has_socket_handler(uzbl_jar)) {
- g_string_append_c(s, 0); /* null-terminate the PUT */
- g_string_append_len(s, scheme, strlen(scheme)+1);
- g_string_append_len(s, new_cookie->domain, strlen(new_cookie->domain)+1 );
- g_string_append_len(s, new_cookie->path, strlen(new_cookie->path)+1 );
- g_string_append_printf(s, "%s=%s", new_cookie->name, new_cookie->value);
-
- gchar *result = do_socket_request(uzbl_jar, s->str, s->len+1);
- /* try it again; older cookie daemons closed the connection after each request */
- if(!result)
- result = do_socket_request(uzbl_jar, s->str, s->len+1);
-
- g_free(result);
- } else {
- g_string_append_printf(s, " '%s' '%s' '%s' '%s=%s'", scheme, new_cookie->domain, new_cookie->path, new_cookie->name, new_cookie->value);
-
- run_handler(uzbl_jar->handler, s->str);
- }
-
- g_string_free(s, TRUE);
-}
-
-static void
-setup_handler(UzblCookieJar *jar) {
- if(jar->handler && strncmp(jar->handler, "talk_to_socket", strlen("talk_to_socket")) == 0) {
- /* extract the socket path from the handler. */
- jar->socket_path = jar->handler + strlen("talk_to_socket");
- while(isspace(*jar->socket_path))
- jar->socket_path++;
- if(*jar->socket_path == 0)
- return; /* there was no path specified. */
- disconnect_cookie_socket(jar);
- connect_cookie_socket(jar);
- } else {
- jar->socket_path = NULL;
- }
-}
-
-static void
-connect_cookie_socket(UzblCookieJar *jar) {
- struct sockaddr_un sa;
- int fd;
-
- g_strlcpy(sa.sun_path, jar->socket_path, sizeof(sa.sun_path));
- sa.sun_family = AF_UNIX;
-
- /* create socket file descriptor and connect it to path */
- fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
- if(fd == -1) {
- g_printerr("connect_cookie_socket: creating socket failed (%s)\n", strerror(errno));
- return;
- }
-
- if(connect(fd, (struct sockaddr*)&sa, sizeof(sa))) {
- g_printerr("connect_cookie_socket: connect failed (%s)\n", strerror(errno));
- close(fd);
- return;
- }
-
- /* successful connection! */
- jar->connection_fd = fd;
-}
-
-static void
-disconnect_cookie_socket(UzblCookieJar *jar) {
- if(jar->connection_fd > 0) {
- close(jar->connection_fd);
- jar->connection_fd = -1;
- }
-}
-
-static gchar *do_socket_request(UzblCookieJar *jar, gchar *request, int request_length) {
- int len;
- ssize_t ret;
- struct pollfd pfd;
- gchar *result = NULL;
-
- if(jar->connection_fd < 0)
- connect_cookie_socket(jar); /* connection was lost, reconnect */
-
- /* write request */
- ret = write(jar->connection_fd, request, request_length);
- if(ret == -1) {
- g_printerr("talk_to_socket: write failed (%s)\n", strerror(errno));
- disconnect_cookie_socket(jar);
- return NULL;
- }
-
- /* wait for a response, with a 500ms timeout */
- pfd.fd = jar->connection_fd;
- pfd.events = POLLIN;
- while(1) {
- ret = poll(&pfd, 1, 500);
- if(ret == 1) break;
- if(ret == 0) errno = ETIMEDOUT;
- if(errno == EINTR) continue;
- g_printerr("talk_to_socket: poll failed while waiting for input (%s)\n",
- strerror(errno));
- if(errno != ETIMEDOUT)
- disconnect_cookie_socket(jar);
- return NULL;
- }
-
- /* get length of response */
- if(ioctl(jar->connection_fd, FIONREAD, &len) == -1) {
- g_printerr("talk_to_socket: cannot find daemon response length, "
- "ioctl failed (%s)\n", strerror(errno));
- disconnect_cookie_socket(jar);
- return NULL;
- }
-
- /* there was an empty response. */
- if(len == 0)
- return g_strdup("");
-
- /* there is a response, read it */
- result = g_malloc(len + 1);
- if(!result) {
- g_printerr("talk_to_socket: failed to allocate %d bytes\n", len);
- return NULL;
- }
- result[len] = 0; /* ensure result is null terminated */
-
- gchar *p = result;
- while(len > 0) {
- ret = read(jar->connection_fd, p, len);
- if(ret == -1) {
- g_printerr("talk_to_socket: failed to read from socket (%s)\n",
- strerror(errno));
- disconnect_cookie_socket(jar);
- g_free(result);
- return NULL;
- } else {
- len -= ret;
- p += ret;
- }
- }
-
- return result;
}
diff --git a/src/cookie-jar.h b/src/cookie-jar.h
index f3e3733..05f4a6f 100644
--- a/src/cookie-jar.h
+++ b/src/cookie-jar.h
@@ -10,12 +10,6 @@
typedef struct {
SoupCookieJar parent;
- const gchar *handler;
-
- const gchar *socket_path;
- int connection_fd;
-
- gboolean in_get_callback;
gboolean in_manual_add;
} UzblCookieJar;
@@ -25,10 +19,4 @@ typedef struct {
UzblCookieJar *uzbl_cookie_jar_new();
-void
-uzbl_cookie_jar_set_handler(UzblCookieJar *jar, const gchar *handler);
-
-char
-*get_cookies(UzblCookieJar *jar, SoupURI *uri);
-
#endif
diff --git a/src/uzbl-browser b/src/uzbl-browser
index faa2829..81645ca 100755
--- a/src/uzbl-browser
+++ b/src/uzbl-browser
@@ -64,13 +64,6 @@ then
export UZBL_UTIL_DIR
fi
-# uzbl-cookie-manager will exit if another instance is already running.
-# we could also check if its pid file exists to avoid having to spawn it.
-#if [ ! -f "$XDG_CACHE_HOME"/uzbl/cookie_daemon_socket.pid ]
-#then
-# ${UZBL_COOKIE_DAEMON:-uzbl-cookie-manager}
-#fi
-
# uzbl-event-manager will exit if one is already running.
# we could also check if its pid file exists to avoid having to spawn it.
DAEMON_SOCKET="$XDG_CACHE_HOME"/uzbl/event_daemon
diff --git a/src/uzbl-core.c b/src/uzbl-core.c
index b45a5ae..e1f042a 100644
--- a/src/uzbl-core.c
+++ b/src/uzbl-core.c
@@ -91,7 +91,6 @@ const struct var_name_to_ptr_t {
{ "title_format_short", PTR_V_STR(uzbl.behave.title_format_short, 1, NULL)},
{ "icon", PTR_V_STR(uzbl.gui.icon, 1, set_icon)},
{ "forward_keys", PTR_V_INT(uzbl.behave.forward_keys, 1, NULL)},
- { "cookie_handler", PTR_V_STR(uzbl.behave.cookie_handler, 1, cmd_set_cookie_handler)},
{ "authentication_handler", PTR_V_STR(uzbl.behave.authentication_handler, 1, set_authentication_handler)},
{ "scheme_handler", PTR_V_STR(uzbl.behave.scheme_handler, 1, NULL)},
{ "download_handler", PTR_V_STR(uzbl.behave.download_handler, 1, NULL)},
@@ -587,10 +586,10 @@ struct {const char *key; CommandInfo value;} cmdlist[] =
{ "script", {run_external_js, 0} },
{ "toggle_status", {toggle_status_cb, 0} },
{ "spawn", {spawn_async, 0} },
- { "sync_spawn", {spawn_sync, 0} }, // needed for cookie handler
+ { "sync_spawn", {spawn_sync, 0} },
{ "sync_spawn_exec", {spawn_sync_exec, 0} }, // needed for load_cookies.sh :(
{ "sh", {spawn_sh_async, 0} },
- { "sync_sh", {spawn_sh_sync, 0} }, // needed for cookie handler
+ { "sync_sh", {spawn_sh_sync, 0} },
{ "exit", {close_uzbl, 0} },
{ "search", {search_forward_text, TRUE} },
{ "search_reverse", {search_reverse_text, TRUE} },
diff --git a/src/uzbl-core.h b/src/uzbl-core.h
index 7a2adca..b58c8fe 100644
--- a/src/uzbl-core.h
+++ b/src/uzbl-core.h
@@ -138,7 +138,6 @@ typedef struct {
gchar* fifo_dir;
gchar* socket_dir;
- gchar* cookie_handler;
gchar* authentication_handler;
gchar* default_font_family;
gchar* monospace_font_family;