Whats the best way to get the client ip from a ring request map?
remote-addr seems to be a list as a string. Would the first entry in the list be the client ip? It doesn't really say in the spec.
According to the spec it shouldn't be a list
Running the server on localhost and doing a get request from my browser I get this on the server :remote-addr "[0:0:0:0:0:0:0:1]"
I am using compojure for routing would that cause it?
That's odd. Which server are you using?
I'm using Jetty and these are the relevant package versions as well. [ring/ring "1.12.1"] [ring/ring-core "1.12.1"] [ring/ring-jetty-adapter "1.12.1"] [ring/ring-defaults "0.4.0"] [ring-cors "0.1.13"] [toyokumo/ring-middleware-csp "0.4.63"] [compojure "1.7.1"]
I believe "[0:0:0:0:0:0:0:1]" is an IPv6 literal address, not a list. See https://www.rfc-editor.org/rfc/rfc3986 for details.
It will also depend on what you have in front of your web server (load balancer, CDN, etc). We have CloudFlare and a load balancer, so here's our middleware for getting the actual client IP:
(fn [req]
(let [headers (:headers req)
fwd-for (some-> (get headers "x-forwarded-for")
(str/split #",")
(first)
(str/trim))
raw-ip (or (get headers "cf-connecting-ipv6")
(get headers "cf-connecting-ip")
fwd-for
(:remote-addr req))
country (get headers "cf-ipcountry")
req+ip
(cond-> (assoc req :remote-addr-raw raw-ip)
fwd-for (assoc :remote-addr fwd-for)
country (assoc :remote-addr-country country))]
(with-log-context (if-let [ip (:remote-addr req+ip)] {:ip ip} {})
(handler req+ip))))