Skip to content
Browse files

add x-forwarded-for header to the client

This adds the way to find out the actual ip of the client machine, even
if it is hidden behind a local reverse proxy.
  • Loading branch information...
1 parent 3876754 commit 4aab135bc6fffb0b13979e240479c24a3f553b06 @Gibheer Gibheer committed Mar 5, 2014
Showing with 35 additions and 4 deletions.
  1. +14 −1 lib/zero/request/client.rb
  2. +21 −3 spec/unit/zero/request/client/address_spec.rb
View
15 lib/zero/request/client.rb
@@ -4,6 +4,8 @@ class Request
class Client
# the key for the ip of the client
KEY_REMOTE_ADDR = 'REMOTE_ADDR'
+ # in proxy setups, this is the real address of the client
+ KEY_FORWARDED_FOR = 'X_FORWARDED_FOR'
# the key for the hostname
KEY_REMOTE_HOST = 'REMOTE_HOST'
# the key for the user agent
@@ -12,7 +14,10 @@ class Client
# creates a new client with the data of the request environment
# @param environment a hash representation of the request
def initialize(environment)
- @address = environment[KEY_REMOTE_ADDR]
+ # extract the two possible ips
+ @forwarded_for = environment[KEY_FORWARDED_FOR]
+ @remote_address = environment[KEY_REMOTE_ADDR]
+ @address = forwarded_for || remote_address
@hostname = environment[KEY_REMOTE_HOST]
@user_agent = environment[KEY_USER_AGENT]
end
@@ -26,6 +31,14 @@ def initialize(environment)
# the user agent of the client
# @return [String] the user agent of the client
attr_reader :user_agent
+
+ # get the forwarded address, set in proxy setups
+ # @return [String] the address set in KEY_FORWARDED_FOR header
+ attr_reader :forwarded_for
+
+ # get the remote address given by KEY_REMOTE_ADDR
+ # @return [String] the remote address defined in KEY_REMOTE_ADDR header
+ attr_reader :remote_address
end
end
end
View
24 spec/unit/zero/request/client/address_spec.rb
@@ -2,8 +2,26 @@
describe Zero::Request::Client, '#address' do
subject { Zero::Request::Client.new(env) }
- let(:address) { '127.0.0.1' }
- let(:env) { {'REMOTE_ADDR' => address} }
- its(:address) { should == address }
+ context 'without a proxy' do
+ let(:address) { '127.0.0.1' }
+ let(:env) { {'REMOTE_ADDR' => address} }
+
+ its(:address) { should == address }
+ end
+
+ context 'with a proxy' do
+ let(:proxy) { '127.0.0.1' }
+ let(:address) { '192.168.42.3' }
+ let(:env) do
+ {
+ 'REMOTE_ADDR' => proxy,
+ 'X_FORWARDED_FOR' => address
+ }
+ end
+
+ its(:address) { should == address }
+ its(:remote_address) { should == proxy }
+ its(:forwarded_for) { should == address }
+ end
end

0 comments on commit 4aab135

Please sign in to comment.
Something went wrong with that request. Please try again.