diff --git a/lib/hits.ex b/lib/hits.ex index e594ce8..9615844 100644 --- a/lib/hits.ex +++ b/lib/hits.ex @@ -131,4 +131,24 @@ defmodule Hits do ua end + + def get_user_ip_address(conn) do + get_x_forwarded_for_ip(conn.req_headers) || + Enum.join(Tuple.to_list(conn.remote_ip), ".") + end + + defp get_x_forwarded_for_ip(headers) do + case Enum.find(headers, fn {k, _} -> k == "x-forwarded-for" end) do + # header doesn't exist + nil -> + nil + + # header exists and can contains multiple ips + {_, ips} -> + ips + |> String.split(",") + |> List.first() + |> String.trim() + end + end end diff --git a/lib/hits_web/controllers/hit_controller.ex b/lib/hits_web/controllers/hit_controller.ex index 66e5abb..38ea0a0 100644 --- a/lib/hits_web/controllers/hit_controller.ex +++ b/lib/hits_web/controllers/hit_controller.ex @@ -55,7 +55,7 @@ defmodule HitsWeb.HitController do useragent = Hits.get_user_agent_string(conn) # remote_ip comes in as a Tuple {192, 168, 1, 42} >> 192.168.1.42 (dot quad) - ip = Enum.join(Tuple.to_list(conn.remote_ip), ".") + ip = Hits.get_user_ip_address(conn) # TODO: perform IP Geolocation lookup here so we can insert lat/lon for map! # insert the useragent: diff --git a/lib/hits_web/controllers/page_controller.ex b/lib/hits_web/controllers/page_controller.ex index 53c8420..8b9dadf 100644 --- a/lib/hits_web/controllers/page_controller.ex +++ b/lib/hits_web/controllers/page_controller.ex @@ -5,7 +5,7 @@ defmodule HitsWeb.PageController do render(conn, "index.html") end - def error(conn, %{"user" => user, "repository" => repository} = params) do + def error(conn, %{"user" => user, "repository" => repository}) do render(conn, "error.html", user: user, repository: repository) end end diff --git a/test/hits_web/controllers/hit_controller_test.exs b/test/hits_web/controllers/hit_controller_test.exs index 78ea244..b83191b 100644 --- a/test/hits_web/controllers/hit_controller_test.exs +++ b/test/hits_web/controllers/hit_controller_test.exs @@ -12,6 +12,16 @@ defmodule HitsWeb.HitControllerTest do assert res.resp_body =~ Hits.make_badge(1) end + test "GET /user1/repo1.svg", %{conn: conn} do + res = + put_req_header(conn, "user-agent", "Hackintosh") + |> put_req_header("x-forwarded-for", "127.0.0.1, 127.0.0.2") + |> put_req_header("accept-language", "en-GB,en;q=0.5") + |> get("/user1/repo1.svg") + + assert res.resp_body =~ Hits.make_badge(1) + end + test "test counter increments! GET /totes/amaze.svg", %{conn: conn} do put_req_header(conn, "user-agent", "Hackintosh") |> put_req_header("accept-language", "en-GB,en;q=0.5")