Software / code / prosody
Comparison
plugins/mod_http.lua @ 11410:2ea70d291429
mod_http: Consolidate handling of proxied connection details
Trying to move everything relating to proxies and X-Forwarded-Foo into a
single place.
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sat, 27 Feb 2021 21:37:56 +0100 |
| parent | 11409:d30c44a829c1 |
| child | 11727:f3aee8a825cc |
comparison
equal
deleted
inserted
replaced
| 11409:d30c44a829c1 | 11410:2ea70d291429 |
|---|---|
| 257 end | 257 end |
| 258 end | 258 end |
| 259 return false | 259 return false |
| 260 end | 260 end |
| 261 | 261 |
| 262 local function get_ip_from_request(request) | 262 local function get_forwarded_connection_info(request) --> ip:string, secure:boolean |
| 263 local ip = request.ip; | 263 local ip = request.ip; |
| 264 local secure = request.secure; -- set by net.http.server | |
| 264 local forwarded_for = request.headers.x_forwarded_for; | 265 local forwarded_for = request.headers.x_forwarded_for; |
| 265 if forwarded_for and is_trusted_proxy(ip) then | 266 if forwarded_for then |
| 266 -- luacheck: ignore 631 | 267 -- luacheck: ignore 631 |
| 267 -- This logic looks weird at first, but it makes sense. | 268 -- This logic looks weird at first, but it makes sense. |
| 268 -- The for loop will take the last non-trusted-proxy IP from `forwarded_for`. | 269 -- The for loop will take the last non-trusted-proxy IP from `forwarded_for`. |
| 269 -- We append the original request IP to the header. Then, since the last IP wins, there are two cases: | 270 -- We append the original request IP to the header. Then, since the last IP wins, there are two cases: |
| 270 -- Case a) The original request IP is *not* in trusted proxies, in which case the X-Forwarded-For header will, effectively, be ineffective; the original request IP will win because it overrides any other IP in the header. | 271 -- Case a) The original request IP is *not* in trusted proxies, in which case the X-Forwarded-For header will, effectively, be ineffective; the original request IP will win because it overrides any other IP in the header. |
| 276 if not is_trusted_proxy(forwarded_ip) then | 277 if not is_trusted_proxy(forwarded_ip) then |
| 277 ip = forwarded_ip; | 278 ip = forwarded_ip; |
| 278 end | 279 end |
| 279 end | 280 end |
| 280 end | 281 end |
| 281 return ip; | 282 |
| 283 secure = secure or request.headers.x_forwarded_proto == "https"; | |
| 284 | |
| 285 return ip, secure; | |
| 282 end | 286 end |
| 283 | 287 |
| 284 module:wrap_object_event(server._events, false, function (handlers, event_name, event_data) | 288 module:wrap_object_event(server._events, false, function (handlers, event_name, event_data) |
| 285 local request = event_data.request; | 289 local request = event_data.request; |
| 286 if request then | 290 if request and is_trusted_proxy(request.ip) then |
| 287 -- Not included in eg http-error events | 291 -- Not included in eg http-error events |
| 288 request.ip = get_ip_from_request(request); | 292 request.ip, request.secure = get_forwarded_connection_info(request); |
| 289 | |
| 290 if not request.secure and request.headers.x_forwarded_proto == "https" and is_trusted_proxy(request.conn:ip()) then | |
| 291 request.secure = true; | |
| 292 end | |
| 293 end | 293 end |
| 294 return handlers(event_name, event_data); | 294 return handlers(event_name, event_data); |
| 295 end); | 295 end); |
| 296 | 296 |
| 297 module:provides("net", { | 297 module:provides("net", { |