ring 2024-05-20

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))))