diff --git a/lib/httparrot/ip_handler.ex b/lib/httparrot/ip_handler.ex index a78ebc1..7c2527a 100644 --- a/lib/httparrot/ip_handler.ex +++ b/lib/httparrot/ip_handler.ex @@ -10,8 +10,21 @@ defmodule HTTParrot.IPHandler do def get_json(req, state) do {{ip, _port}, req} = :cowboy_req.peer(req) + {:ok, forwarded_for, _} = :cowboy_req.parse_header(<<"x-forwarded-for">>, req) + case forwarded_for do + :undefined -> + {response(ip), req, state} + _ -> + {response(to_tuple(forwarded_for)), req, state} + end + end - {response(ip), req, state} + defp to_tuple(client_ip) do + client_ip + |> hd + |> String.split(".") + |> Enum.map(fn(x) -> String.to_integer(x) end) + |> List.to_tuple end defp response(:local) do diff --git a/test/ip_handler_test.exs b/test/ip_handler_test.exs index 426c590..b8634f1 100644 --- a/test/ip_handler_test.exs +++ b/test/ip_handler_test.exs @@ -13,6 +13,7 @@ defmodule HTTParrot.IPHandlerTest do test "returns prettified json with origin" do ip = {127, 1, 2, 3} expect(:cowboy_req, :peer, 1, {{ip, :host}, :req2}) + expect(:cowboy_req, :parse_header, 2, {:ok, :undefined, :req2}) expect(JSX, :encode!, [{[[origin: "127.1.2.3"]], :json}]) assert get_json(:req1, :state) == {:json, :req2, :state} @@ -21,8 +22,21 @@ defmodule HTTParrot.IPHandlerTest do assert validate JSX end + test "returns prettified json with client ip when available" do + ip = {127, 1, 2, 3} + expect(:cowboy_req, :peer, 1, {{ip, :host}, :req2}) + expect(:cowboy_req, :parse_header, 2, {:ok, ["190.1.2.3"], :req2}) + expect(JSX, :encode!, [{[[origin: "190.1.2.3"]], :json}]) + + assert get_json(:req1, :state) == {:json, :req2, :state} + + assert validate :cowboy_req + assert validate JSX + end + test "returns empty when running over unix sockets" do expect(:cowboy_req, :peer, 1, {{:local, ""}, :req2}) + expect(:cowboy_req, :parse_header, 2, {:ok, :undefined, :req2}) expect(JSX, :encode!, [{[[origin: ""]], :json}]) assert get_json(:req1, :state) == {:json, :req2, :state}