The shortfalls of imapproxy, or: wonko looks a gift horse in the mouth

For those times when I’m away from home and need to check my email, there’s nothing better than a web-based IMAP client. I run a private installation of Imp restricted to allow connections only to wonko.com and a few other mail servers. While perusing my server logs today, I noticed that a few of my friends have been using it quite a lot to check their own email, which I think is cool; Imp is a great mail client and I like being able to provide a service for my friends.

Unfortunately, like all PHP-based webmail systems, Imp is unable to maintain IMAP connections between pageviews due to PHP’s stateless architecture. This means that each time someone clicks on a link, Imp has to reconnect to the IMAP server. For users whose mail is hosted on wonko.com this is pretty fast, but for people using remote IMAP servers, this can be painfully slow. I couldn’t stand the thought of my poor friends having to endure slow load times, so I set about improving the situation. What I needed was a program that would act as a proxy between Imp and the remote IMAP servers, keeping connections open between page requests.

There are two programs that do this, both called (unsurprisingly) imapproxy. One of them was once a side project of Horde (the folks responsible for Imp), but it’s no longer being maintained. The other one is being actively maintained and appears to be widely used.

Neither of them supports caching connections to more than one remote server.

It seems simple enough. imapproxy runs as a daemon on the local machine, accepts connections from clients, and passes those connections to a remote server specified in the imapproxy config file. Only one remote server, though. This makes sense, because imapproxy has no way of identifying which incoming connections are for which remote server. But would it have killed the developers to have imapproxy automatically start multiple daemon processes on a range of consecutive ports if multiple remote servers are specified in the config file?

I can probably accomplish the same thing with a shell script and some tweaking, but it would have been nice not to have to do any work, you know?