Skip to content

Commit

Permalink
Adding a new remote_ip method to get the ip of the client with some f…
Browse files Browse the repository at this point in the history
…allbacks. Fixes #1000
  • Loading branch information
jwoertink committed Mar 21, 2020
1 parent c641406 commit f7f670b
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
32 changes: 32 additions & 0 deletions spec/lucky/action_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,12 @@ class ParamsWithDefaultParamsLast < TestAction
end
end

class TestActionWithRemoteIp < TestAction
get "/remote-ip" do
plain_text remote_ip
end
end

describe Lucky::Action do
it "has a url helper" do
Lucky::RouteHelper.temp_config(base_uri: "example.com") do
Expand Down Expand Up @@ -323,6 +329,32 @@ describe Lucky::Action do
end
end
end

describe "getting the remote_ip" do
it "returns the fallback local address" do
response = TestActionWithRemoteIp.new(build_context(path: "/remote-ip"), params).call
response.body.to_s.should eq "127.0.0.1"
end

it "returns the X_FORWARDED_FOR address" do
headers = HTTP::Headers.new
headers["HTTP_X_FORWARDED_FOR"] = "1.2.3.4,127.0.0.1"
request = HTTP::Request.new("GET", "/remote-ip", body: "", headers: headers)
context = build_context(request)

response = TestActionWithRemoteIp.new(context, params).call
response.body.to_s.should eq "1.2.3.4"
end

it "returns the original remote_address" do
request = HTTP::Request.new("GET", "/remote-ip", body: "", headers: HTTP::Headers.new)
request.remote_address = "1.2.3.4"
context = build_context(request)

response = TestActionWithRemoteIp.new(context, params).call
response.body.to_s.should eq "1.2.3.4"
end
end
end

private def assert_route_added?(expected_route)
Expand Down
1 change: 1 addition & 0 deletions src/lucky/action.cr
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ abstract class Lucky::Action
include Lucky::ActionCallbacks
include Lucky::Redirectable
include Lucky::VerifyAcceptsFormat
include Lucky::RemoteIpAddress

# Must be defined here instead of in Renderable
# Otherwise it clashes with ErrorAction#render
Expand Down
15 changes: 15 additions & 0 deletions src/lucky/remote_ip_address.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module Lucky::RemoteIpAddress
# Returns a `String` IP Address of the remote client by
# looking at a few different possible options.
#
# * HTTP_X_FORWARDED_FOR header
# * REMOTE_ADDRESS header
# * Fallback to localhost 127.0.0.1
def remote_ip : String
request = @context.request

request.headers["HTTP_X_FORWARDED_FOR"]?.try(&.split(',').first) ||
request.remote_address ||
"127.0.0.1"
end
end

0 comments on commit f7f670b

Please sign in to comment.