Everyone and their dog uses some sort of URL shortening service these days. While it's handy to cram an URL into short messages like those used on Twitter it's not always considered best practice for a bunch of reasons.

Since quite a few applications these days use Twitter feeds and similar services to gather new content, it'd be great to expand those URLs and undo any damage that these services cause.

Borrowing heavily from a Ruby based Twitter client I've extracted a module which can be used to do just that. Without further ado... here it is.

require 'net/http'

module BarkingIguana
  module ExpandUrl
    def expand_urls!
      ExpandUrl.services.each do |service|
        gsub!(service[:pattern]) { |match|
          ExpandUrl.expand($2, service[:host]) || $1
        }
      end
    end

    def expand_urls
      s = dup
      s.expand_urls!
      s
    end

    def ExpandUrl.services
      [
        { :host => "tinyurl.com", :pattern => %r'(http://tinyurl\.com(/[\w/]+))' },
        { :host => "is.gd", :pattern => %r'(http://is\.gd(/[\w/]+))' },
        { :host => "bit.ly", :pattern => %r'(http://bit\.ly(/[\w/]+))' },
        { :host => "ff.im", :pattern => %r'(http://ff\.im(/[\w/]+))'},
      ]
    end

    def ExpandUrl.expand(path, host)
      result = ::Net::HTTP.new(host).head(path)
      case result
      when ::Net::HTTPRedirection
        result['Location']
      end
    end
  end
end

To use it, first include the module into String.

class String
  include BarkingIguana::ExpandUrl
end

Then simply call expand_urls or expand_urls! on the text that contains shortened URLs. The bang method changes the string in-place where the regular method returns a copy of the string and leaves the original unchanged.

s = "http://tinyurl.com/asdf"
s.expand_urls!
puts s.inspect
# => "http://support.microsoft.com/default.aspx?scid=kb;EN-US;158122"

At the moment it supports ff.im, is.gd, bit.ly and tinyurl. If you can suggest any other services I'd love to hear about them. This code - like the original implementation - is released under the MIT licence. The full code including licence and RDoc can be found at http://pastie.org/471016. Enjoy!

written by
Craig
published
2009-05-07
Disagree? Found a typo? Got a question?
If you'd like to have a conversation about this post, email craig@barkingiguana.com. I don't bite.
You can verify that I've written this post by following the verification instructions:
curl -LO http://barkingiguana.com/2009/05/07/expanding-shortened-urls-in-a-ruby-string.html.orig
curl -LO http://barkingiguana.com/2009/05/07/expanding-shortened-urls-in-a-ruby-string.html.orig.asc
gpg --verify expanding-shortened-urls-in-a-ruby-string.html.orig{.asc,}