Saturday, May 26, 2007

Configuring HTTP Timeout for Rails GeoKit::Geocoders Plugin

Problem Description:
My internet connection is pretty spotty and when it drops out, the
IpGeocoder.geocode(request_ip)
functionality from the GeoKit::Geocoders Plugin takes forever and a day to resolve.

Problem Solution:
I directly hacked
vendor/plugins/geokit/lib/geo_kit/geocoders.rb
as follows:

class IpGeocoder < Geocoder

private

# Given an IP address, returns a GeoLoc instance which contains latitude,
# longitude, city, and country code. Sets the success attribute to false if the ip
# parameter does not match an ip address.
def self.do_geocode(ip)
return GeoLoc.new unless /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?$/.match(ip)
# response = Net::HTTP.get_response('api.hostip.info', "/get_html.php?ip=#{ip}&position=true")

domain = 'api.hostip.info'
path = '/get_html.php'
pars = "ip=#{ip}&position=true"
h = Net::HTTP::new(domain)
h.read_timeout = 2
begin
response = h.post(path, pars)
rescue TimeoutError => e
raise "Error calling #{domain}, #{path}, #{pars}: #{e.inspect}"
end

response.is_a?(Net::HTTPSuccess) ? parse_body(response.body) : GeoLoc.new
rescue
logger.error "Caught an error during HostIp geocoding call: "+$!
return GeoLoc.new
end