My personal URL shortener, ye.gg

 
To my surprise and delight, I noticed yesterday that the domain ye.gg was available, and I quickly gobbled it up. .gg is the country code for Guernsey, one of the Channel Islands. It wasn't cheap (GBP 88.00, ~$135 USD), but it's worth it to me!

Side note: in this process I found Domainr, which helps you find short domains.

Unlike godaddy et al., it took ~24hr for the .gg domain to be setup in DNS. So while I was waiting yesterday, I searched for a provider to run my URL shortener. The two providers I found that seemed like they may work were bit.ly Pro and awe.sm, which TechCrunch apparently uses.

I was quickly accepted into the free beta of bit.ly Pro (thanks!), but it has two limitations that prevent me from using it. First, they won't redirect ye.gg/ (with no shortcode) to my Web site. Second, they share the hashspace with everyone else, meaning I can't make ye.gg/1 ye.gg/2 etc. because they're already taken by regular bit.ly users.

Awe.sm looks cool, but they're in closed beta or are charging $99/mo. I'm only going to be making a few short URLs a month (for blog posts), so that price seemed way too steep. I emailed asking if I could get it in on the beta, but haven't heard back.  I can't blame them for not turning around in minutes, but I'm itching to get this thing up!

So I decided to roll my own thing for now--the most basic thing I could come up with in a few minutes. Here's what I did.

  • Pointed the DNS to my server that runs this Web site (via DNS Made Easy).

  • Cooked up this small Perl package.
package yegg;

use nginx;

sub is_rewrite {
    my $r = shift;

    my $uri = $r->uri || '';
    return 0 if !$uri || $uri =~ /[^0-9a-d]/o;

    my $rewrite = 0;
    my $file = qq(/usr/local/ye.gg/$uri);
    if (-f $file) {
        open(IN,'<',$file);
        $rewrite = <IN>;
        chomp($rewrite);
        close(IN);
    }

    return $rewrite;
}

1;

This is intended to run within nginx (my Web server), using the embedded Perl module. All it does is look for the existence of a file matching the URL in the /usr/local/ye.gg/ directory. If found, it opens the file and returns the URL within it. So if I want to make http://ye.gg/angel work I just create the file '/usr/local/ye.gg/angel' and put 'http://www.gabrielweinberg.com/angel.html' in it.

  • Added this code to nginx conf.
    perl_require "/usr/local/etc/nginx/yegg.pm";
    perl_set  $rewrite  '
sub {
  my $r = shift;
  return yegg::is_rewrite($r);
  return "";
}
';

This just uses the the above package and puts it into the $rewrite variable. So when a request comes in, it sets that variable by running the function I defined in the package (is_rewrite).

  • Added more code to my nginx conf.
    server {
        server_name  ye.gg *.ye.gg;

        if ($rewrite) {
          rewrite ^. $rewrite permanent;
        }

        location / {
          rewrite ^(.*) http://www.gabrielweinberg.com permanent;
        }
    }

This says if $rewrite exists (there is a URL to go to), redirect to it. Otherwise, always redirect to my home page.

And that's it--it works! One issue with this setup that I couldn't immediately solve is it checks for the file existence on every request, regardless of whether they are ye.gg request or for other domains. That is, perl_require and perl_set don't seem to operate within server blocks. Not sure why. Anyway, I'll leave that for another day unless anyone has any insight.
Or follow via RSS.   Or by email: