Comments (5)
Well, I wrote my own, simpler plug and did some logging. My route action was getting called before my plug! Turns out I added my plug below plug :match
, which is where I had added RemoteIp
as well. I moved my plug up above plug :match
and everything worked as expected. So, noobie mistake, but it may be worth adding to the readme.
from remote_ip.
What do the req_headers
look like in the Plug.Conn
when a request comes through your load balancer?
The selection algorithm is described in this section of the README. My guess - though I can't be sure - is that you need to specify the :proxies
option for your setup. (If this poses a problem, I'd love to know how the interface could be improved!)
from remote_ip.
I'm having the same issue. My request headers look like this:
[
{"host", "blah.herokuapp.com"},
{"connection", "close"},
{"accept", "application/json, text/javascript, */*; q=0.01"},
{"origin", "http://blah.netlify.com"},
{"user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"},
{"content-type", "multipart/form-data; boundary=----WebKitFormBoundaryxd0LvDA6YTTuBemj"},
{"referer", "http://blah.netlify.com/contact"},
{"accept-encoding", "gzip, deflate, br"},
{"accept-language", "en-US,en;q=0.8"},
{"x-request-id", "7debd32d-ec89-4079-9245-55d535eae6e2"},
{"x-forwarded-for", "75.171.251.123"},
{"x-forwarded-proto", "https"},
{"x-forwarded-port", "443"},
{"via", "1.1 vegur"},
{"connect-time", "1"},
{"x-request-start", "1488493100272"},
{"total-route-time", "2001"},
{"content-length", "929"}
]
from remote_ip.
🤔 Quite odd, because in isolation it appears to be fine:
iex(2)> conn = %Plug.Conn{remote_ip: {127,0,0,1}, req_headers: headers}
%Plug.Conn{adapter: {Plug.Conn, :...}, assigns: %{}, before_send: [],
body_params: %Plug.Conn.Unfetched{aspect: :body_params},
cookies: %Plug.Conn.Unfetched{aspect: :cookies}, halted: false,
host: "www.example.com", method: "GET", owner: nil,
params: %Plug.Conn.Unfetched{aspect: :params}, path_info: [], peer: nil,
port: 0, private: %{},
query_params: %Plug.Conn.Unfetched{aspect: :query_params}, query_string: "",
remote_ip: {127, 0, 0, 1}, req_cookies: %Plug.Conn.Unfetched{aspect: :cookies},
req_headers: [{"host", "blah.herokuapp.com"}, {"connection", "close"},
{"accept", "application/json, text/javascript, */*; q=0.01"},
{"origin", "http://blah.netlify.com"},
{"user-agent",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"},
{"content-type",
"multipart/form-data; boundary=----WebKitFormBoundaryxd0LvDA6YTTuBemj"},
{"referer", "http://blah.netlify.com/contact"},
{"accept-encoding", "gzip, deflate, br"},
{"accept-language", "en-US,en;q=0.8"},
{"x-request-id", "7debd32d-ec89-4079-9245-55d535eae6e2"},
{"x-forwarded-for", "75.171.251.123"}, {"x-forwarded-proto", "https"},
{"x-forwarded-port", "443"}, {"via", "1.1 vegur"}, {"connect-time", "1"},
{"x-request-start", "1488493100272"}, {"total-route-time", "2001"},
{"content-length", "929"}], request_path: "", resp_body: nil,
resp_cookies: %{},
resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}],
scheme: :http, script_name: [], secret_key_base: nil, state: :unset,
status: nil}
iex(3)> RemoteIp.call(conn, RemoteIp.init).remote_ip
{75, 171, 251, 123}
Indeed, RemoteIp
has tests to the effect.
I also couldn't reproduce in a new Phoenix app:
diff --git a/lib/hello_phoenix/endpoint.ex b/lib/hello_phoenix/endpoint.ex
index 2e33241..3929269 100644
--- a/lib/hello_phoenix/endpoint.ex
+++ b/lib/hello_phoenix/endpoint.ex
@@ -3,6 +3,8 @@ defmodule HelloPhoenix.Endpoint do
socket "/socket", HelloPhoenix.UserSocket
+ plug RemoteIp
+
# Serve at "/" the static files from "priv/static" directory.
#
# You should set gzip to true if you are running phoenix.digest
diff --git a/mix.exs b/mix.exs
index 6be9357..5797663 100644
--- a/mix.exs
+++ b/mix.exs
@@ -37,7 +37,8 @@ defmodule HelloPhoenix.Mixfile do
{:phoenix_html, "~> 2.6"},
{:phoenix_live_reload, "~> 1.0", only: :dev},
{:gettext, "~> 0.11"},
- {:cowboy, "~> 1.0"}]
+ {:cowboy, "~> 1.0"},
+ {:remote_ip, "~> 0.1"}]
end
# Aliases are shortcuts or tasks specific to the current project.
diff --git a/mix.lock b/mix.lock
index ac61ff7..b1d9de8 100644
--- a/mix.lock
+++ b/mix.lock
@@ -1,4 +1,5 @@
-%{"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], []},
+%{"combine": {:hex, :combine, "0.9.6", "8d1034a127d4cbf6924c8a5010d3534d958085575fa4d9b878f200d79ac78335", [:mix], []},
+ "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], []},
"cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, optional: false]}]},
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], []},
"db_connection": {:hex, :db_connection, "1.1.1", "f9d246e8f65b9490945cf7360875eee18fcec9a0115207603215eb1fd94c39ef", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, optional: true]}]},
@@ -6,6 +7,7 @@
"ecto": {:hex, :ecto, "2.1.3", "ffb24e150b519a4c0e4c84f9eabc8587199389bc499195d5d1a93cd3b2d9a045", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, optional: true]}]},
"fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], []},
"gettext": {:hex, :gettext, "0.13.1", "5e0daf4e7636d771c4c71ad5f3f53ba09a9ae5c250e1ab9c42ba9edccc476263", [:mix], []},
+ "inet_cidr": {:hex, :inet_cidr, "1.0.2", "1acc8b89670aaf4aec7dd36d08f33d6ba6155be0fa30169abdb86b8431ecb175", [:mix], []},
"mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], []},
"phoenix": {:hex, :phoenix, "1.2.1", "6dc592249ab73c67575769765b66ad164ad25d83defa3492dc6ae269bd2a68ab", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, optional: false]}, {:plug, "~> 1.1", [hex: :plug, optional: false]}, {:poison, "~> 1.5 or ~> 2.0", [hex: :poison, optional: false]}]},
"phoenix_ecto": {:hex, :phoenix_ecto, "3.2.2", "2e51c57614528b130d54019e78349f83a5b5d53b3b2ef775dbc30df7e1fecb45", [:mix], [{:ecto, "~> 2.1", [hex: :ecto, optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, optional: false]}, {:plug, "~> 1.0", [hex: :plug, optional: false]}]},
@@ -16,4 +18,5 @@
"poison": {:hex, :poison, "2.2.0", "4763b69a8a77bd77d26f477d196428b741261a761257ff1cf92753a0d4d24a63", [:mix], []},
"poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], []},
"postgrex": {:hex, :postgrex, "0.13.1", "ebf17b7348922af9db8b4d70f946328ab9ef5123526bf05567d9306393fce104", [:mix], [{:connection, "~> 1.0", [hex: :connection, optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, optional: false]}]},
- "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], []}}
+ "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], []},
+ "remote_ip": {:hex, :remote_ip, "0.1.3", "9175e63ce23eece9253bdd17edbd2262bd91c5b700987f6ce0044e504ba42089", [:mix], [{:combine, "~> 0.9.2", [hex: :combine, optional: false]}, {:inet_cidr, "~> 1.0", [hex: :inet_cidr, optional: false]}, {:plug, "~> 1.2", [hex: :plug, optional: false]}]}}
diff --git a/web/templates/page/index.html.eex b/web/templates/page/index.html.eex
index 8ff4b81..dc00fb3 100644
--- a/web/templates/page/index.html.eex
+++ b/web/templates/page/index.html.eex
@@ -1,5 +1,5 @@
<div class="jumbotron">
- <h2><%= gettext "Welcome to %{name}", name: "Phoenix!" %></h2>
+ <h2>Welcome, <%= @conn.remote_ip |> :inet.ntoa |> to_string %></h2>
<p class="lead">A productive web framework that<br />does not compromise speed and maintainability.</p>
</div>
$ mix phoenix.server
$ curl localhost:4000 -s | grep Welcome
<h2>Welcome, 127.0.0.1</h2>
$ curl localhost:4000 -s -H'X-Forwarded-For: 1.2.3.4' | grep Welcome
<h2>Welcome, 1.2.3.4</h2>
My remaining guess is that it has something to do with whatever other plugs you're using. Maybe you should try logging the IP in between every plug in your pipeline? 🤷♂️ Let me know how it goes!
from remote_ip.
Oh, cool! Glad you got it working, @adsteel. Hadn't thought of that issue, but it makes sense. Will definitely update the readme when I get a moment.
from remote_ip.
Related Issues (16)
- Add inet_cidr to included_applications HOT 5
- @reserved is incorrect HOT 1
- problem with rewritten IP HOT 2
- :combine should not be in :included_applications
- Dialyzer warning HOT 5
- Question about mapped-ipv4 ipv6 format HOT 3
- Export `RemoteIp.Block` as its own package? HOT 8
- X-Forwarded-For is parsed incorrectly! HOT 3
- Good article on `x-forwarded-for` parsing HOT 10
- Support for `Fly-Client-IP`? HOT 7
- Plug.Conn also has get_peer_data, which returns the original ip HOT 3
- Parse X-Forwarded-Port and X-Forwarded-Proto HOT 3
- Doesn't Work Running Server in Docker Container HOT 5
- Any way to pass runtime information to `init` HOT 1
- RFC1918 IPs shouldn't be discarded by default HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from remote_ip.