How to set the Expires header with Apache 2 and mod_expires

Apache posted 5 months ago by christian

First you need to enable the mod_expires module:

   1  a2enmod expires

Next add this to your configuration:

   1  ExpiresActive On
   2  # Set Expires header to current time by default
   3  ExpiresDefault A0
   4  
   5  <FilesMatch "\.(flv|ico|pdf|avi|mov|ppt|doc|mp3|wmv|wav)$">
   6    ExpiresDefault "access plus 30 days"
   7  </FilesMatch>
   8  
   9  <FilesMatch "\.(jpg|jpeg|png|gif|swf|bmp|)$">
  10    ExpiresDefault "access plus 7 days"
  11  </FilesMatch>
  12  
  13  <FilesMatch "\.(txt|xml|js|css)$">
  14    ExpiresDefault "access plus 1 day"
  15  </FilesMatch>

Now restart Apache:

   1  $ sudo /etc/init.d/apache2 force-reload

Check that the proper headers are set with Firebug, Yahoo YSlow or Google Page speed.

Tagged apache, expires, mod_expires, header, caching

How to support conditional gets in Rails

Ruby posted 10 months ago by christian

From the When to Tell Your Kids About Client Caching RailsConf presentation

   1  def fresh?(response)
   2  def stale?(:etag => @object, :last_modified => updated_at.utc)
   3  def not_modified?(modified_at)
   4  def etag_matches?(etag)

   1  class PeopleController < ApplicationController
   2  	def show
   3  		@person = Person.find(params[:id])
   4  		response.last_modified = @person.updated_at.utc
   5  		response.etag = @person	
   6  		return head(:not_modified) if request.fresh?(response)
   7  
   8  		respond_to do |wants|
   9  			#...
  10  		end
  11  	end
  12  end

   1  response.etag = @person # => “5cb44721b6ce18857ff6900486dc4aba”
   2  @person.cache_key # => "people/5-20071224150000"

   1  class PeopleController < ApplicationController
   2  	def show
   3  		@person = Person.find(params[:id])
   4  		if stale?(:etag => @person, :last_modified => @person.updated_at.utc)
   5  			respond_to do |wants|
   6  			#...
   7  			end
   8  		end
   9  	end
  10  end

Tagged caching, rails, last_modified, etag, fresh

Geolocation with MaxMind's GeoIP and the geoip-city RubyGem

Ruby posted about 1 year ago by christian

Install GeoIP library

   1  wget http://www.maxmind.com/download/geoip/api/c/GeoIP.tar.gz
   2  tar -zxvf GeoIP.tar.gz
   3  cd GeoIP
   4  ./configure --prefix=/opt/GeoIP
   5  make && sudo make install

Install the geoip-city gem

   1  gem install geoip_city -- --with-geoip-dir=/opt/GeoIP

Test the bindings

   1  curl -O http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
   2  gunzip GeoLiteCity.dat.gz

Fire up IRB and try the following code:

   1  require 'rubygems'
   2  require 'geoip_city'
   3  db = GeoIPCity::Database.new('GeoLiteCity.dat')
   4  result = db.look_up('192.143.34.23')
   5  p result

Another option is to use hostip.info’s database, as described in this article.

Create a wrapper

   1  require 'rubygems'
   2  require 'geoip_city'
   3  require 'ostruct'
   4  
   5  class Location < OpenStruct
   6  end
   7  
   8  class GeoIP
   9    class << self
  10      DB = GeoIPCity::Database.new('GeoLiteCity.dat')
  11  
  12      def lookup(ip)
  13        if result = DB.look_up(ip)
  14          location = Location.new
  15  
  16          #
  17          # {:country_code=>"FR", :country_code3=>"FRA", :country_name=>"France", :latitude=>46.0, :longitude=>2.0}
  18          #
  19          result.each do |key, val| 
  20            location.send "#{key}=", val
  21          end
  22        end
  23  
  24        location
  25      end
  26    end
  27  end

Add some Rails caching

Combined with the above code this will give you cached IP lookups:

   1  class GeoIP
   2  
   3    class << self
   4      def lookup_with_caching(ip)
   5        Rails.cache.fetch(ip, :expires_in => 1.month) do 
   6          lookup_without_caching(ip)
   7        end
   8      end
   9  
  10      alias_method_chain :lookup, :caching
  11    end
  12  end

Alternatives

If you’re unable to install the C extension you might want to have a look at the geoip gem, which is a pure Ruby library that can read the MaxMind’s geoip database. It’s slower but easier to install: http://geoip.rubyforge.org/

Tagged geoip, geolocation, maxmind, caching, rails