aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mod_http.lua
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mod_http.lua')
-rw-r--r--plugins/mod_http.lua57
1 files changed, 47 insertions, 10 deletions
diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua
index 0cee26c4..b52f4b44 100644
--- a/plugins/mod_http.lua
+++ b/plugins/mod_http.lua
@@ -11,19 +11,21 @@ pcall(function ()
module:depends("http_errors");
end);
-local portmanager = require "core.portmanager";
-local moduleapi = require "core.moduleapi";
+local portmanager = require "prosody.core.portmanager";
+local moduleapi = require "prosody.core.moduleapi";
local url_parse = require "socket.url".parse;
local url_build = require "socket.url".build;
-local normalize_path = require "util.http".normalize_path;
-local set = require "util.set";
+local http_util = require "prosody.util.http";
+local normalize_path = http_util.normalize_path;
+local set = require "prosody.util.set";
+local array = require "util.array";
-local ip_util = require "util.ip";
+local ip_util = require "prosody.util.ip";
local new_ip = ip_util.new_ip;
local match_ip = ip_util.match;
local parse_cidr = ip_util.parse_cidr;
-local server = require "net.http.server";
+local server = require "prosody.net.http.server";
server.set_default_host(module:get_option_string("http_default_host"));
@@ -75,11 +77,11 @@ end
local ports_by_scheme = { http = 80, https = 443, };
-- Helper to deduce a module's external URL
-function moduleapi.http_url(module, app_name, default_path)
+function moduleapi.http_url(module, app_name, default_path, mode)
app_name = app_name or (module.name:gsub("^http_", ""));
local external_url = url_parse(module:get_option_string("http_external_url"));
- if external_url then
+ if external_url and mode ~= "internal" then
local url = {
scheme = external_url.scheme;
host = external_url.host;
@@ -112,12 +114,16 @@ function moduleapi.http_url(module, app_name, default_path)
return "http://disabled.invalid/";
end
+local function header_set_tostring(header_value)
+ return array(header_value:items()):concat(", ");
+end
+
local function apply_cors_headers(response, methods, headers, max_age, allow_credentials, allowed_origins, origin)
if allowed_origins and not allowed_origins[origin] then
return;
end
- response.headers.access_control_allow_methods = tostring(methods);
- response.headers.access_control_allow_headers = tostring(headers);
+ response.headers.access_control_allow_methods = header_set_tostring(methods);
+ response.headers.access_control_allow_headers = header_set_tostring(headers);
response.headers.access_control_max_age = tostring(max_age)
response.headers.access_control_allow_origin = origin or "*";
if allow_credentials then
@@ -292,7 +298,13 @@ module.add_host(module); -- set up handling on global context too
local trusted_proxies = module:get_option_set("trusted_proxies", { "127.0.0.1", "::1" })._items;
+--- deal with [ipv6]:port / ip:port format
+local function normal_ip(ip)
+ return ip:match("^%[([%x:]*)%]") or ip:match("^([%d.]+)") or ip;
+end
+
local function is_trusted_proxy(ip)
+ ip = normal_ip(ip);
if trusted_proxies[ip] then
return true;
end
@@ -308,6 +320,30 @@ end
local function get_forwarded_connection_info(request) --> ip:string, secure:boolean
local ip = request.ip;
local secure = request.secure; -- set by net.http.server
+
+ local forwarded = http_util.parse_forwarded(request.headers.forwarded);
+ if forwarded then
+ request.forwarded = forwarded;
+ for i = #forwarded, 1, -1 do
+ local proxy = forwarded[i]
+ if is_trusted_proxy(ip) then
+ ip = normal_ip(proxy["for"]);
+ secure = secure and proxy.proto == "https";
+ else
+ break
+ end
+ end
+ end
+
+ return ip, secure;
+end
+
+-- TODO switch to RFC 7239 by default once support is more common
+if module:get_option_boolean("http_legacy_x_forwarded", true) then
+function get_forwarded_connection_info(request) --> ip:string, secure:boolean
+ local ip = request.ip;
+ local secure = request.secure; -- set by net.http.server
+
local forwarded_for = request.headers.x_forwarded_for;
if forwarded_for then
-- luacheck: ignore 631
@@ -330,6 +366,7 @@ local function get_forwarded_connection_info(request) --> ip:string, secure:bool
return ip, secure;
end
+end
module:wrap_object_event(server._events, false, function (handlers, event_name, event_data)
local request = event_data.request;