Friday, 15 March 2013

Re-introducing... Mumpsimus.

A while ago I started playing around with a new way of debugging web apps. I basically piped the HTTP stream through UNIX pipes, using a combination of Perl scripts and other commands to modify HTTP headers and bodies on their way to and from the browser.

I've just started playing with the concept again and this time I've put the code on GitHub.

It's still in its really early days and I really only ever have time these days to pick at it occasionally.

Anyway, here's the relevant introduction from the README.

Introducing Mumpsimus: An experiment

A mumpsimus is a person who obstinately adheres to a custom or notion, even after it's been shown to be unreasonable (alternatively, the word may be used to describe the custom or notion itself).
It is said to have come from an illiterate 16th century priest, who was mispronouncing the Latin word "sumpsimus". When told of the error, he replied:
I will not change my old mumpsimus for your new sumpsimus
This Mumpsimus is a tool set for re-writing HTTP messages before they reach your browser or device. It will stubbornly mis-state both requests and responses -- even when someone thinks that's a bad idea.
For example, we might use Mumpsimus to stubbornly insist that all assets are cacheable. Or that none are. Or we might serve a local file when a remote one is requested. Or we might randomly scramble the Google Analytics tracking code, or strip out our Facebook cookie when visiting third party sites. Oh the places we'll go!
The original idea was a tool for debugging during web development. If that's your thing then check out the Charles Web Development Proxy. It's very handy. Mumpsimus is still a toy.

How it Works

The toolset is designed to work as a set of UNIX command-line programs that will co-operate using UNIX pipes. The basic idea is to feed in HTTP messages (requests or responses) via stdin, and have the (potentially) modified output printed on stdout. This in turn can be fed to another command and so on.
Here's a simple example:
$ mkfifo backpipe
$ nc -l 8080  < backpipe | log | nc proxy 3128 | log -v > backpipe
Or, if you have's Ncat tool:
$ ncat -l -k localhost 8080 -c "log | ncat proxy 3128 | log -v"
Log is part of Mumpsimus. It prints information about HTTP messages it sees on stderr. So these commands (the two blocks above are functionally equivalent):
  • Listens on port 8080 for browser requests (therefore set your proxy to localhost:8080)
  • Pipes the browser request through the log command, which will print one line on stderr per request
  • Pipes the request through another netcat instance which will forward it to a real proxy running on port 3128 (assumes the proxy's hostname is "proxy")
  • Pipes the response through another log command, this time also printing HTTP headers (-v turns this on)
  • The resulting output will be sent back to the browser.
Let's play with the Cache-Control header!
$ mkfifo backpipe
$ nc -l 8080  < backpipe | nc proxy 3128 \
    | sed -e 's/^Cache-Control: .*/Cache-Control: private/' \
    | log -v > backpipe
This will mean that all requests going back to the browser will have their Cache-Control header re-written to say "private", allowing our browser to cache locally.
Actually, all we're doing above we could do already without Mumpsimus. The problem with it is that any line beginning "Cache-Control" will be re-written, not just headers. The pipeif tool can help, since it knows HTTP:
$ nc -l 8080  < backpipe | nc proxy 3128 \
    | pipeif -h -c "sed -e 's/^Cache-Control: .*/Cache-Control: private/'" \
    | log -v > backpipe
Now that sed command will only apply to HTTP headers, because that's what pipeif does.


For now you'll need to grab the code from GitHub and compile it yourself:
$ ./configure --prefix=~/mumpsimus
$ make check && make install