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