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", { |