From 8a6a899414523a99ac229e625032f9e6102ee049 Mon Sep 17 00:00:00 2001 From: Michael S. Klishin Date: Tue, 1 Jul 2008 11:52:20 +0300 Subject: [PATCH] Request#remote_ip does not fail when REMOTE_ADDR is a comma-separated list anymore. In some particular cases with Nginx and some ISPs REMOTE_ADDR happens to be a comma-separated list of IP addresses so checking for local request passes a string with commas to IPAddr.new and causes exceptions. Exception notifier plugin does such checks in production environment, for instance. Semantics of REMOTE_ADDR being a list is unclear but some real world applications prove it may be the case. This patch makes Request#remote_ip gracefully handle cases when REMOTE_ADDR is a comma-separated list of IPs. --- actionpack/lib/action_controller/request.rb | 8 +++++--- actionpack/test/controller/request_test.rb | 4 ++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb index 9b02f2c..ad1fe11 100755 --- a/actionpack/lib/action_controller/request.rb +++ b/actionpack/lib/action_controller/request.rb @@ -135,10 +135,12 @@ module ActionController # delimited list in the case of multiple chained proxies; the last # address which is not trusted is the originating IP. def remote_ip - if TRUSTED_PROXIES !~ @env['REMOTE_ADDR'] - return @env['REMOTE_ADDR'] - end + remote_addr_list = @env['REMOTE_ADDR'] && @env['REMOTE_ADDR'].split(',').collect(&:strip) + unless remote_addr_list.blank? + not_trusted_addrs = remote_addr_list.reject {|addr| addr =~ TRUSTED_PROXIES} + return not_trusted_addrs.first unless not_trusted_addrs.empty? + end remote_ips = @env['HTTP_X_FORWARDED_FOR'] && @env['HTTP_X_FORWARDED_FOR'].split(',') if @env.include? 'HTTP_CLIENT_IP' diff --git a/actionpack/test/controller/request_test.rb b/actionpack/test/controller/request_test.rb index 2bd489b..2e363e9 100644 --- a/actionpack/test/controller/request_test.rb +++ b/actionpack/test/controller/request_test.rb @@ -30,6 +30,10 @@ class RequestTest < Test::Unit::TestCase @request.env['HTTP_X_FORWARDED_FOR'] = 'unknown,3.4.5.6' assert_equal '3.4.5.6', @request.remote_ip + @request.env['REMOTE_ADDR'] = '7.8.9.10,3.4.5.6' + assert_equal '7.8.9.10', @request.remote_ip + @request.env.delete('REMOTE_ADDR') + @request.env['HTTP_X_FORWARDED_FOR'] = '172.16.0.1,3.4.5.6' assert_equal '3.4.5.6', @request.remote_ip -- 1.5.6.rc0