diff --git a/lib/geocoder/configuration.rb b/lib/geocoder/configuration.rb index 775a4ff39c68c659cd1618755e6664a31dcb98a3..7ee2776b4e33bb2e282489ef27aa3eb9ab87aab7 100644 --- a/lib/geocoder/configuration.rb +++ b/lib/geocoder/configuration.rb @@ -15,6 +15,9 @@ module Geocoder # use HTTPS for lookup requests? (if supported) [:use_https, false], + # use Proxy when http_proxy / https_proxy is set in ENV + [:use_proxy, true], + # API key for geocoding service [:api_key, nil], diff --git a/lib/geocoder/lookups/base.rb b/lib/geocoder/lookups/base.rb index 3960df8ba01b10e5c80c19a39fb1cffc1f3d65f7..d3687f895630a68353364ce0db39847330ef6c61 100644 --- a/lib/geocoder/lookups/base.rb +++ b/lib/geocoder/lookups/base.rb @@ -1,4 +1,6 @@ require 'net/http' +require 'uri' + unless defined?(ActiveSupport::JSON) begin require 'rubygems' # for Ruby 1.8 @@ -52,6 +54,23 @@ module Geocoder private # ------------------------------------------------------------- + ## + # Object used to fetch requests + # + def http_client + proxy_url = ENV[Geocoder::Configuration.use_https ? 'https_proxy' : 'http_proxy'] + return Net::HTTP unless Geocoder::Configuration.use_proxy && proxy_url + + begin + uri = URI.parse(proxy_url) + rescue URI::InvalidURIError + raise ConfigurationError, "The proxy URL in environment (" + + "#{Geocoder::Configuration.use_https ? 'https_proxy' : 'http_proxy'} => #{proxy_url}" + + ") was not parsed correctly by URI::Parse" + end + Net::HTTP::Proxy(uri.host, uri.port, uri.user, uri.password) + end + ## # Geocoder::Result object or nil on timeout or other error. # @@ -84,7 +103,7 @@ module Geocoder rescue TimeoutError warn "Geocoding API not responding fast enough " + "(see Geocoder::Configuration.timeout to set limit)." - end + end end ## @@ -117,7 +136,7 @@ module Geocoder timeout(Geocoder::Configuration.timeout) do url = query_url(query, reverse) unless cache and response = cache[url] - response = Net::HTTP.get_response(URI.parse(url)).body + response = http_client.get_response(URI.parse(url)).body if cache cache[url] = response end diff --git a/test/geocoder_test.rb b/test/geocoder_test.rb index b86b7db4f482572eca0f866ebe891c473449aa3d..e3cef93efb23b46a4b7ad1df5bba248cf0ca935d 100644 --- a/test/geocoder_test.rb +++ b/test/geocoder_test.rb @@ -20,6 +20,34 @@ class GeocoderTest < Test::Unit::TestCase # --- sanity checks --- + def test_uses_proxy_by_default + lookup = Geocoder::Lookup::Base.new + + ENV.delete 'http_proxy' + ENV.delete 'https_proxy' + assert ! lookup.send(:http_client).proxy_class? + + ENV['http_proxy'] = 'http://localhost' + assert_equal 'localhost', lookup.send(:http_client).proxy_address + + Geocoder::Configuration.use_https = true + ENV['https_proxy'] = 'https://localhost-ssl' + assert_equal 'localhost-ssl', lookup.send(:http_client).proxy_address + end + + def test_exception_raised_on_bad_proxy_url + ENV['http_proxy'] = ' \\_O< Quack Quack' + assert_raise Geocoder::ConfigurationError do + Geocoder::Lookup::Base.new.send(:http_client) + end + end + + def test_uses_direct_connection_when_forced + Geocoder::Configuration.use_proxy = false + ENV['http_proxy'] = 'http://localhost:8080' + assert ! Geocoder::Lookup::Base.new.send(:http_client).proxy_class? + end + def test_uses_https_for_secure_query Geocoder::Configuration.use_https = true g = Geocoder::Lookup::Google.new