Sunday, February 8, 2015

Roll Your Own Short Links


I decided the other day that I wanted a better way to share content with people. Whether it be a PDF or a youtube URL, or something out of my dropbox. Now, none of that is difficult, I will grant you. It's pretty easy to email or SMS someone a link, even a longer dropbox content link or one of those expansively long blog links generated from the title. Sure, great for SEO, a real pain to dictate to someone over the phone. And you always take the chance their email app or server or whatever will crush the link into a ball of twisted metal.

So, it seemed to me there must be a way to do this better and in a reusable way. And would it hurt if I enhanced my own branding a little (eg huff.po, nerdi.st, hlp.sc, tmblr.co, wp.me) ? Maybe, but let's assume not.

Better yet, if I set this up in a way that I can easily configure and maintain the redirections from anywhere, that's a bonus.

It occurs to me that I can do all this with Edge80 without having to worry about development tools or deployment or servers or whatever. And not having to worry about commissioning or deployment is one of my favourite things. Better than raindrops on roses.

So, my basic plan is to use a nice short domain and to have short, simple paths essentially resolve redirects to longer URLs. That way the minimum processing needs to take place. For example if I were to attempt to proxy content, this would require me to do processing and URL changes when handling things like youtube URLs. The Edge80 libraries make that easy, but it's not necessary for this use. Here we just want to make sure people end up in the right place.
It's actually pretty easy to return a redirect (301) in Edge80, which is the pivotal part of what we want to do. Let's look at the code to return a redirect to edge80.com.
<rule name="a_redirect">
  <set-cache aggressive="true" cookies="ignore" insecure="true"/>
  <compose>
    <header name="Location" value="http://www.edge80.com"/>
    <script>
        <![CDATA[
        document.responseCode = 301;
        ]]>
    </script>
  </compose>
</rule>
The way I decided to configure this is to put some paths and associated URLs in a text file. Here is an example:
e80vids,https://www.youtube.com/channel/UCaa_-DZyObm7ZHAMMEmoRUA
e80els,http://doc.edge80.com/XML/Resource/Elements
henge,https://www.google.com.au/maps/place/Stonehenge/@51.178882,-1.826216,17z/data=!3m1!4b1!4m2!3m1!1s0x4873e63b850af611:0x979170e2bcd3d2dd
I drop this in the public folder of my dropbox for convenience. It's such a quick and easy way to HTTP share a file, it suits this circumstance quite neatly. I can easily add redirects to the file wherever I am, even on my phone. I then add some code to the Edge80 script to pull this file when needed, and parse it for paths to redirect to.
First a setting to know where to get the file of redirections.
<rule name="definitions" priority="-100">
    <prerequisite>
        <defmac name="links_src" value="https://dl.dropboxusercontent.com/your_dropbox_account/links.txt" />
        <!-- A Default place to redirect to. -->
        <defmac name="redirect" value="http://www.edge80.com" />
    </prerequisite>
</rule>
Then when a path comes in we look up in this file and decide on a destination URL using some javascript.
<rule comment="Standard Redirect Rule" match-host="*">
    <apply name="definitions" />
    <!-- Some standard aggressive caching. -->
    <set-cache aggressive="true" cookies="ignore" insecure="true"/>
    <compose buffer="links">
        <!-- Fetch the links config file into a buffer called links -->
        <fetch type="url" url="${links_src}"/>
    </compose>
    <compose>
        <script>
            <![CDATA[
            var lines = dombufs['links'].value.split('\n');
            for (var n = 0; n < lines.length; n++) {
                if (lines[n].length > 2 && lines[n].search(",") > -1) {
                    var key = lines[n].split(',')[0];
                    if (key == request.path.substr(1)) {
                        macros.redirect = lines[n].substr(key.length+1);
                    }
                }
            }
            document.responseCode = 301;
            ]]>
        </script>
        <header name="Location" value="${redirect}"/>
    </compose>
</rule>
Because the result is cached aggressively this same 301 result will be returned on subsequent requests for the same path, until the cache expires. So, even though there is a little script run on each of the first requests for each path, the caching makes subsequent requests for the same thing very very speedy indeed.
Want to see it at work? The links given as samples above are, of course, live. Try them here:


And you can download the complete Edge80 source code for this little utility at http://rjm.link/redirector (Right Click to save for best result)