Back to Blog

Get in Touch

Integrating Akamai HTTP Downloads to your Rails Application

By Raymond Law April 26, 2010 in rails akamai

Missing

I recently had to integrate Akamai HTTP Downloads to a Rails project. The goal is to take advantage Akamai’s large global network of edge servers to serve large file downloads over HTTP to client browsers. These edge servers are distributed and optimized to cache and serve static contents to customers. They also decrease the load on the application servers. Since these large files (i.e. apps, games, tarballs, …etc.) remain static most of the time (except when there are new releases), it would be wasteful to transmit them using the application server’s bandwidth, which is better used to transmit dynamic content that can’t be cached.

First, you need to set up your Akamai configurations at Akamai EdgeControl HTTP Downloads Configurations, and download the URL-based token generator? and put them in RAILS_ROOT/lib. I will show how to use both the Perl and C versions.

To allow easier configuration, I set up a config/akamai.yml file that looks like:

production:
  protocol: http://
  domain: cdn.example.com
  keyname: __gda__
  window: 28800
  salt: secret
  tokenizer: perl
  extensions:
    - .zip
    - .exe
    - .msi
    - .dmg
    - .gz
    - .7z

Akamai only requires a token for files that have these extensions. For images and videos, you do not need to generate a token. The akamaized method first checks the file’s extension to determine if a token needs to be generated. If it does, the method calls the token generator to get a filename with the token appended. Finally, the complete Akamai URL is built with protocol, domain, and the new filename.

def akamaized(filename)
  extension = filename[filename.rindex(/\..*$/)..-1]
  if AKAMAI['extensions'].include?(extension)
    extension_fix = "?ext=#{extension}"
    filename_with_extension_fix = "#{filename}#{extension_fix}"
    filename_with_token = `#{AKAMAI['tokenizer']} -I '#{RAILS_ROOT}/lib/UrlAuthPerl-1.1.1' '#{RAILS_ROOT}/lib/UrlAuthPerl-1.1.1/akam-edge-auth-url.pl' '#{filename_with_extension_fix}' #{AKAMAI['keyname']} #{AKAMAI['window']} #{AKAMAI['salt']}`
    akamai_filename = "#{AKAMAI['protocol']}#{AKAMAI['domain']}#{filename_with_token}"
  else
    akamai_filename = "#{AKAMAI['protocol']}#{AKAMAI['domain']}#{filename}"
  end
end

Depending on how you manage file assets in your Rails application, you may choose how to use akamaized. For example, if you use attachment_fu for file uploads, you may want to override attachment_fu’s public_filename method and enable it only for production so that your developers can still call public_filename to take advantage of Akamai HTTP Downloads. It will be transparent to them.

I showed the Perl version first because both Mac and Linux have the standard Perl interpreter installed and it is more cross-platform-friendly. If you want to use the C version if that’s a bit faster, you would have in your config/akamai.yml:

  tokenizer: lib/URLAuthC-1.1.3/genURL

and your akamaized method:

    filename_with_token = `cd #{RAILS_ROOT}/#{AKAMAI['tokenizer'][0..AKAMAI['tokenizer'].rindex('/')]} ; .#{AKAMAI['tokenizer'][AKAMAI['tokenizer'].rindex('/')..-1]} -u '#{filename_with_extension_fix}' -p #{AKAMAI['keyname']} -w #{AKAMAI['window']} -s #{AKAMAI['salt']}`

This sums up how you can take advantage of Akamai HTTP Downloads to serve large static files faster to your users and decrease the load on your application server. In my next post, I will show how to use Akamai’s Content Control Utility API to purge cached content on the Akamai edge servers, so that you can make new releases of your apps, games, tarballs, …etc. readily available to your users.

Tags:

rails akamai
Medium

Raymond Law

Raymond has extensive background in C++ data modeling and simulation, picked up working for a defense contractor. He also studied PHP before discovering the beauty of Ruby on Rails and joining forces with the Web 2.0 list managmenent site, OnMyList.com Ray is now a senior engineer with Intridea, where he specializes in agile development and behavior-driven development with Ruby on Rails. He is proficient in front-end design, back-end business logic, deployment setups, as well as DBMS.

More posts by Raymond Law

Raymond Law

Rails adds a pretty cool Object#try method. From Rails doc:

try(...

Raymond Law

Raymond Law