From 33d6521a19c2f3455dc7dfab6bd851cb29edefc8 Mon Sep 17 00:00:00 2001
From: Nik Wakelin <me@nikwakelin.com>
Date: Fri, 27 Jun 2014 12:32:28 +0800
Subject: [PATCH] Look for the IP address as filled in by Action Dispatch if
 present, otherwise fall back on raygun.remote_ip then REMOTE_ADDR

---
 lib/raygun/client.rb     | 11 +++++++++-
 test/unit/client_test.rb | 46 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/lib/raygun/client.rb b/lib/raygun/client.rb
index d3a098e..a5b6b9c 100644
--- a/lib/raygun/client.rb
+++ b/lib/raygun/client.rb
@@ -2,6 +2,9 @@ module Raygun
   # client for the Raygun REST APIv1
   # as per http://raygun.io/raygun-providers/rest-json-api?v=1
   class Client
+
+    ENV_IP_ADDRESS_KEYS = %w(action_dispatch.remote_ip raygun.remote_ip REMOTE_ADDR)
+
     include HTTParty
 
     base_uri "https://api.raygun.io/"
@@ -73,7 +76,7 @@ def request_information(env)
           hostName:    env["SERVER_NAME"],
           url:         env["PATH_INFO"],
           httpMethod:  env["REQUEST_METHOD"],
-          iPAddress:   env["REMOTE_ADDR"],
+          iPAddress:   ip_address_from(env),
           queryString: Rack::Utils.parse_nested_query(env["QUERY_STRING"]),
           form:        form_data(env),
           headers:     headers(env),
@@ -142,5 +145,11 @@ def filter_params(params_hash, extra_filter_keys = nil)
         end
       end
 
+      def ip_address_from(env_hash)
+        ENV_IP_ADDRESS_KEYS.each do |key_to_try|
+          return env_hash[key_to_try] unless env_hash[key_to_try].nil? || env_hash[key_to_try] == ""
+        end
+      end
+
   end
 end
diff --git a/test/unit/client_test.rb b/test/unit/client_test.rb
index c474fa3..3d7338c 100644
--- a/test/unit/client_test.rb
+++ b/test/unit/client_test.rb
@@ -226,4 +226,50 @@ def test_filtering_nested_params
     assert_equal expected_form_hash, @client.send(:request_information, post_body_env_hash)[:form]
   end
 
+  def test_ip_address_from_action_dispatch
+    sample_env_hash = {
+      "HTTP_VERSION"=>"HTTP/1.1",
+      "HTTP_HOST"=>"localhost:3000",
+      "HTTP_CONNECTION"=>"keep-alive",
+      "HTTP_CACHE_CONTROL"=>"max-age=0",
+      "HTTP_ACCEPT"=>"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
+      "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.22 Safari/537.36",
+      "HTTP_ACCEPT_ENCODING"=>"gzip,deflate,sdch",
+      "HTTP_ACCEPT_LANGUAGE"=>"en-US,en;q=0.8",
+      "HTTP_COOKIE"=>"cookieval",
+      "GATEWAY_INTERFACE"=>"CGI/1.2",
+      "SERVER_PORT"=>"3000",
+      "SERVER_PROTOCOL"=>"HTTP/1.1",
+      "SCRIPT_NAME"=>"",
+      "REMOTE_ADDR"=>"127.0.0.1",
+      "action_dispatch.remote_ip"=>"123.456.789.012"
+    }
+
+    assert_equal "123.456.789.012", @client.send(:ip_address_from, sample_env_hash)
+    assert_equal "123.456.789.012", @client.send(:request_information, sample_env_hash)[:iPAddress]
+  end
+
+  def test_ip_address_from_raygun_specific_key
+    sample_env_hash = {
+      "HTTP_VERSION"=>"HTTP/1.1",
+      "HTTP_HOST"=>"localhost:3000",
+      "HTTP_CONNECTION"=>"keep-alive",
+      "HTTP_CACHE_CONTROL"=>"max-age=0",
+      "HTTP_ACCEPT"=>"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
+      "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.22 Safari/537.36",
+      "HTTP_ACCEPT_ENCODING"=>"gzip,deflate,sdch",
+      "HTTP_ACCEPT_LANGUAGE"=>"en-US,en;q=0.8",
+      "HTTP_COOKIE"=>"cookieval",
+      "GATEWAY_INTERFACE"=>"CGI/1.2",
+      "SERVER_PORT"=>"3000",
+      "SERVER_PROTOCOL"=>"HTTP/1.1",
+      "SCRIPT_NAME"=>"",
+      "REMOTE_ADDR"=>"127.0.0.1",
+      "raygun.remote_ip"=>"123.456.789.012"
+    }
+
+    assert_equal "123.456.789.012", @client.send(:ip_address_from, sample_env_hash)
+    assert_equal "123.456.789.012", @client.send(:request_information, sample_env_hash)[:iPAddress]
+  end
+
 end