In my current undertaking (don’t worry: I’ll get better soon :-) of revamping my Web sites and un-mechanizing their back-ends (that’s the software that powers them – what where you thinking of?), I’m leaving Yourls. Yourls is Your Own URL Shortener, a small set of PHP scripts that allow you to run your own URL shortening service.

Yourls screen shot

Yourls has worked well for me – no complaints whatsoever. It is very feature rich (see above screen shot for a current example taken from the CouchDB reference card download URL) but

  • I don’t need the bells and whistles
  • I don’t want the required MySQL back-end

And because of the move from the old site I’d have to dump the database tables and fiddle around with the URLs anyway, to get them to point to the new locations.

Enter yaus

yaus is Yet Another URL Shortener. (I really tried, honest, but I couldn’t find a shorter name for it.) yaus is the complete, minimalistic and ballistic opposite of Yourls. It has neither bells nor whistles, but it is very fast. To be honest, that’s about all the good I can say of it, but it works very well for me.

I need some sort of data store in which to record URLs, and I’ve chosen CDB for it, a small and very fast file-based database, sort of like an associative array on disk. There are two implementations I’m aware of: Dan Bernstein’s original cdb and Michael Tokarev’s TinyCDB. I’ve chosen the latter.

yaus needs a key (the bit we tack onto a particular URL) and a URL to which it should redirect. The source for the lot is a …. (drum roll) … plain text file that looks like this:


Those lines (first white-space-separated word is the key, next comes the URL) are best written to a CDB database with the cdb utility. In fact the provided Makefile has a make data target for doing just that:

cdb -cm -t data.temp data.cdb <

(The data.temp file is a temporary file into which cdb starts writing. If all goes well, it is atomically renamed to data.cdb.)

Export from Yourls

Being the lazy type that I am, I obviously didn’t want to enter all the URLs again and risk breaking something. So I exported the Yourls database table into a file.

	SELECT keyword, url FROM yourls_url WHERE clicks > 0 
	    INTO OUTFILE '/tmp/' 

In my particular case (moving from one site to another) I have to additionally massage the URLs translating from the old to the new domains. In doing that, I’ll check with an HTTP HEAD request that the resources still exist, and for those that do, I pipe the key and url into cdb to get my data.cdb file built.

sed -e 's|||' < | while read key url
    curl -sSf -I "$url" > /dev/null && echo "$key $url"
done | cdb -cm -t data.temp data.cdb

Testing locally

To get yaus running, I recommend you first test it on the command-line. Assuming the you saw above has been converted into data.cdb:

  ./yaus jp
  Status: 301
  X-redirector: yaus
  Content-length: 0
  Content-type: text/plain

That looks OK: the Location: header has been issued. Now add a + symbol to the end of the key:

  ./yaus jp+
  Content-type: text/html

  <a href=''></a>

Notice how the content type and the response body have changed. More on that later, but you can hopefully see it coming.

Adding to Apache

I’m using yaus on Apache so I’ll show you its configuration there. yaus is to be located at the /: URI, because I like the look of it, and it is short. (You can easily locate it anywhere you desire, such as at /my-special-cool-redirector, but you do remember that we’re trying to shorten URLs? :-)

So, what I want is, say, URLS to look like this (recall that the word ip in this example is the key):

I create the directory called : and create the following .htaccess file in it:

  Options +ExecCGI -Indexes

  AddHandler cgi-script .cgi
  DirectoryIndex yaus.cgi

  RewriteEngine on
  RewriteBase /:
  RewriteCond     %{REQUEST_FILENAME}     !yaus.cgi
  RewriteRule ^(.*)$      yaus.cgi?$1     [PT,QSA]

If you choose a different directory, you’ll have to change the RewriteBase as well.

Let’s test

Now for a test with curl.

  $ curl -D /tmp/x
  $ cat /tmp/x
  HTTP/1.1 301 Moved Permanently
  Date: Thu, 09 Jun 2011 19:37:09 GMT
  Server: Apache/2.2.3 (CentOS)
  X-redirector: yaus
  Content-length: 0
  Connection: close
  Content-Type: text/plain

Looks good. (Why didn’t curl show the content of the target URL? Because I omitted the -L option thereby disabling curl from following redirects.)

So, go head and try our URL:

The plus

What’s with the + character we saw above? Well, if you tack that on to the key, the user isn’t redirected but gets the chance to see what the redirection would lead to:

Plussed keys

Creating yaus was a bit of fun, and it has all-in-all possibly even saved me time during this “transition” phase. The source code for yaus is available here.

URL, Apache, htaccess, CGI, and CDB :: 09 Jun 2011 :: e-mail