plugins/mod_http.lua
author Matthew Wild <mwild1@gmail.com>
Wed, 11 Sep 2019 15:10:31 +0100
changeset 10262 4ff2f14f9ac7
parent 9856 6ea3cafb6ac3
child 10319 d4c538a7d655
permissions -rw-r--r--
mod_http: Add support for configuring CORS Access-Control-Allow-Credentials
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4635
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     1
-- Prosody IM
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
     2
-- Copyright (C) 2008-2012 Matthew Wild
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
     3
-- Copyright (C) 2008-2012 Waqas Hussain
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5427
diff changeset
     4
--
4635
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     5
-- This project is MIT/X11 licensed. Please see the
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     6
-- COPYING file in the source package for more information.
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     7
--
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     8
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     9
module:set_global();
4774
b2ed4e1bcb6e mod_http: Depend on mod_http_errors
Matthew Wild <mwild1@gmail.com>
parents: 4736
diff changeset
    10
module:depends("http_errors");
4635
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    11
5374
b62c6cbcb065 mod_http: Import portmanager
Kim Alvefur <zash@zash.se>
parents: 5332
diff changeset
    12
local portmanager = require "core.portmanager";
4892
6c8074f47ca4 mod_http: Add module:http_url([app_name,][default_path]) for a module to get a guess at its external URL
Matthew Wild <mwild1@gmail.com>
parents: 4774
diff changeset
    13
local moduleapi = require "core.moduleapi";
6c8074f47ca4 mod_http: Add module:http_url([app_name,][default_path]) for a module to get a guess at its external URL
Matthew Wild <mwild1@gmail.com>
parents: 4774
diff changeset
    14
local url_parse = require "socket.url".parse;
5093
1ce9e8068dda mod_http: Rework how module:http_url() builds the url.
Kim Alvefur <zash@zash.se>
parents: 5092
diff changeset
    15
local url_build = require "socket.url".build;
9507
cfbea3064aa9 mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents: 9506
diff changeset
    16
local normalize_path = require "util.http".normalize_path;
9801
071538a567d5 mod_http: Determine CORS methods to whitelist from actual methods used
Kim Alvefur <zash@zash.se>
parents: 9800
diff changeset
    17
local set = require "util.set";
4892
6c8074f47ca4 mod_http: Add module:http_url([app_name,][default_path]) for a module to get a guess at its external URL
Matthew Wild <mwild1@gmail.com>
parents: 4774
diff changeset
    18
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
    19
local server = require "net.http.server";
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
    20
4736
3514338c59c3 net.http.server, mod_http: Support http_default_host config option to specify where to direct requests for unknown HTTP vhosts
Matthew Wild <mwild1@gmail.com>
parents: 4724
diff changeset
    21
server.set_default_host(module:get_option_string("http_default_host"));
3514338c59c3 net.http.server, mod_http: Support http_default_host config option to specify where to direct requests for unknown HTTP vhosts
Matthew Wild <mwild1@gmail.com>
parents: 4724
diff changeset
    22
7583
588ed6451984 mod_http: Allow configuring http parser size limits
Kim Alvefur <zash@zash.se>
parents: 6601
diff changeset
    23
server.set_option("body_size_limit", module:get_option_number("http_max_content_size"));
588ed6451984 mod_http: Allow configuring http parser size limits
Kim Alvefur <zash@zash.se>
parents: 6601
diff changeset
    24
server.set_option("buffer_size_limit", module:get_option_number("http_max_buffer_size"));
588ed6451984 mod_http: Allow configuring http parser size limits
Kim Alvefur <zash@zash.se>
parents: 6601
diff changeset
    25
9797
9993fd021d19 mod_http: Solve CORS problems once and for all
Kim Alvefur <zash@zash.se>
parents: 9507
diff changeset
    26
-- CORS settigs
9801
071538a567d5 mod_http: Determine CORS methods to whitelist from actual methods used
Kim Alvefur <zash@zash.se>
parents: 9800
diff changeset
    27
local opt_methods = module:get_option_set("access_control_allow_methods", { "GET", "OPTIONS" });
9797
9993fd021d19 mod_http: Solve CORS problems once and for all
Kim Alvefur <zash@zash.se>
parents: 9507
diff changeset
    28
local opt_headers = module:get_option_set("access_control_allow_headers", { "Content-Type" });
10262
4ff2f14f9ac7 mod_http: Add support for configuring CORS Access-Control-Allow-Credentials
Matthew Wild <mwild1@gmail.com>
parents: 9856
diff changeset
    29
local opt_credentials = module:get_option_boolean("access_control_allow_credentials", false);
9797
9993fd021d19 mod_http: Solve CORS problems once and for all
Kim Alvefur <zash@zash.se>
parents: 9507
diff changeset
    30
local opt_max_age = module:get_option_number("access_control_max_age", 2 * 60 * 60);
9993fd021d19 mod_http: Solve CORS problems once and for all
Kim Alvefur <zash@zash.se>
parents: 9507
diff changeset
    31
4667
d0cfc49f3f2b mod_http: Support for default_path in apps
Matthew Wild <mwild1@gmail.com>
parents: 4664
diff changeset
    32
local function get_http_event(host, app_path, key)
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
    33
	local method, path = key:match("^(%S+)%s+(.+)$");
4721
1c6c4c53f08a mod_http: Routes now require a method to be specified, but the path has become optional (defaults to the base path with no trailing '/'
Matthew Wild <mwild1@gmail.com>
parents: 4720
diff changeset
    34
	if not method then -- No path specified, default to "" (base path)
1c6c4c53f08a mod_http: Routes now require a method to be specified, but the path has become optional (defaults to the base path with no trailing '/'
Matthew Wild <mwild1@gmail.com>
parents: 4720
diff changeset
    35
		method, path = key, "";
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
    36
	end
4721
1c6c4c53f08a mod_http: Routes now require a method to be specified, but the path has become optional (defaults to the base path with no trailing '/'
Matthew Wild <mwild1@gmail.com>
parents: 4720
diff changeset
    37
	if method:sub(1,1) == "/" then
1c6c4c53f08a mod_http: Routes now require a method to be specified, but the path has become optional (defaults to the base path with no trailing '/'
Matthew Wild <mwild1@gmail.com>
parents: 4720
diff changeset
    38
		return nil;
1c6c4c53f08a mod_http: Routes now require a method to be specified, but the path has become optional (defaults to the base path with no trailing '/'
Matthew Wild <mwild1@gmail.com>
parents: 4720
diff changeset
    39
	end
5092
a89f8f2f2943 mod_http: Don't produce paths with double / if a module is set to serve /
Kim Alvefur <zash@zash.se>
parents: 4915
diff changeset
    40
	if app_path == "/" and path:sub(1,1) == "/" then
a89f8f2f2943 mod_http: Don't produce paths with double / if a module is set to serve /
Kim Alvefur <zash@zash.se>
parents: 4915
diff changeset
    41
		app_path = "";
a89f8f2f2943 mod_http: Don't produce paths with double / if a module is set to serve /
Kim Alvefur <zash@zash.se>
parents: 4915
diff changeset
    42
	end
9379
220468f7a103 mod_http: Support global HTTP modules
Kim Alvefur <zash@zash.se>
parents: 9341
diff changeset
    43
	if host == "*" then
220468f7a103 mod_http: Support global HTTP modules
Kim Alvefur <zash@zash.se>
parents: 9341
diff changeset
    44
		return method:upper().." "..app_path..path;
220468f7a103 mod_http: Support global HTTP modules
Kim Alvefur <zash@zash.se>
parents: 9341
diff changeset
    45
	else
220468f7a103 mod_http: Support global HTTP modules
Kim Alvefur <zash@zash.se>
parents: 9341
diff changeset
    46
		return method:upper().." "..host..app_path..path;
220468f7a103 mod_http: Support global HTTP modules
Kim Alvefur <zash@zash.se>
parents: 9341
diff changeset
    47
	end
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
    48
end
4635
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    49
4702
5a85e541de1a mod_http: Switch to single option for specifying HTTP app bases, http_paths. Keys are app/module names, values are base paths.
Matthew Wild <mwild1@gmail.com>
parents: 4696
diff changeset
    50
local function get_base_path(host_module, app_name, default_app_path)
5332
5b73ac268a9e mod_http: Expand $host in http_paths
Kim Alvefur <zash@zash.se>
parents: 5230
diff changeset
    51
	return (normalize_path(host_module:get_option("http_paths", {})[app_name] -- Host
4702
5a85e541de1a mod_http: Switch to single option for specifying HTTP app bases, http_paths. Keys are app/module names, values are base paths.
Matthew Wild <mwild1@gmail.com>
parents: 4696
diff changeset
    52
		or module:get_option("http_paths", {})[app_name] -- Global
5332
5b73ac268a9e mod_http: Expand $host in http_paths
Kim Alvefur <zash@zash.se>
parents: 5230
diff changeset
    53
		or default_app_path)) -- Default
6025
583e5c1365fe mod_http: Use hostname from the correct context (thanks gryffus)
Kim Alvefur <zash@zash.se>
parents: 5427
diff changeset
    54
		:gsub("%$(%w+)", { host = host_module.host });
4892
6c8074f47ca4 mod_http: Add module:http_url([app_name,][default_path]) for a module to get a guess at its external URL
Matthew Wild <mwild1@gmail.com>
parents: 4774
diff changeset
    55
end
6c8074f47ca4 mod_http: Add module:http_url([app_name,][default_path]) for a module to get a guess at its external URL
Matthew Wild <mwild1@gmail.com>
parents: 4774
diff changeset
    56
6507
e1659f32852e mod_http: For URLs that end with / or wildcard handlers, add a low-priority redirect from without to with slash
Kim Alvefur <zash@zash.se>
parents: 6086
diff changeset
    57
local function redir_handler(event)
e1659f32852e mod_http: For URLs that end with / or wildcard handlers, add a low-priority redirect from without to with slash
Kim Alvefur <zash@zash.se>
parents: 6086
diff changeset
    58
	event.response.headers.location = event.request.path.."/";
7521
829ebe806e82 mod_http: Fix indentation in redir_handler
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 7362
diff changeset
    59
	if event.request.url.query then
829ebe806e82 mod_http: Fix indentation in redir_handler
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 7362
diff changeset
    60
		event.response.headers.location = event.response.headers.location .. "?" .. event.request.url.query
829ebe806e82 mod_http: Fix indentation in redir_handler
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 7362
diff changeset
    61
	end
6507
e1659f32852e mod_http: For URLs that end with / or wildcard handlers, add a low-priority redirect from without to with slash
Kim Alvefur <zash@zash.se>
parents: 6086
diff changeset
    62
	return 301;
e1659f32852e mod_http: For URLs that end with / or wildcard handlers, add a low-priority redirect from without to with slash
Kim Alvefur <zash@zash.se>
parents: 6086
diff changeset
    63
end
e1659f32852e mod_http: For URLs that end with / or wildcard handlers, add a low-priority redirect from without to with slash
Kim Alvefur <zash@zash.se>
parents: 6086
diff changeset
    64
5093
1ce9e8068dda mod_http: Rework how module:http_url() builds the url.
Kim Alvefur <zash@zash.se>
parents: 5092
diff changeset
    65
local ports_by_scheme = { http = 80, https = 443, };
1ce9e8068dda mod_http: Rework how module:http_url() builds the url.
Kim Alvefur <zash@zash.se>
parents: 5092
diff changeset
    66
4892
6c8074f47ca4 mod_http: Add module:http_url([app_name,][default_path]) for a module to get a guess at its external URL
Matthew Wild <mwild1@gmail.com>
parents: 4774
diff changeset
    67
-- Helper to deduce a module's external URL
6c8074f47ca4 mod_http: Add module:http_url([app_name,][default_path]) for a module to get a guess at its external URL
Matthew Wild <mwild1@gmail.com>
parents: 4774
diff changeset
    68
function moduleapi.http_url(module, app_name, default_path)
6c8074f47ca4 mod_http: Add module:http_url([app_name,][default_path]) for a module to get a guess at its external URL
Matthew Wild <mwild1@gmail.com>
parents: 4774
diff changeset
    69
	app_name = app_name or (module.name:gsub("^http_", ""));
5183
8461e8ed7c09 mod_http: Rename variable for clarity
Matthew Wild <mwild1@gmail.com>
parents: 5180
diff changeset
    70
	local external_url = url_parse(module:get_option_string("http_external_url")) or {};
6026
8a8be471ec72 mod_http: Fix http_external_url setting without an explicit port
Kim Alvefur <zash@zash.se>
parents: 6025
diff changeset
    71
	if external_url.scheme and external_url.port == nil then
8a8be471ec72 mod_http: Fix http_external_url setting without an explicit port
Kim Alvefur <zash@zash.se>
parents: 6025
diff changeset
    72
		external_url.port = ports_by_scheme[external_url.scheme];
8a8be471ec72 mod_http: Fix http_external_url setting without an explicit port
Kim Alvefur <zash@zash.se>
parents: 6025
diff changeset
    73
	end
4892
6c8074f47ca4 mod_http: Add module:http_url([app_name,][default_path]) for a module to get a guess at its external URL
Matthew Wild <mwild1@gmail.com>
parents: 4774
diff changeset
    74
	local services = portmanager.get_active_services();
4915
3fbc01d1fc5a mod_http: Fix traceback when no HTTP services succeed in binding
Matthew Wild <mwild1@gmail.com>
parents: 4911
diff changeset
    75
	local http_services = services:get("https") or services:get("http") or {};
8972
48d0b908f8b6 mod_http: Silecence harmless warnings
Kim Alvefur <zash@zash.se>
parents: 8599
diff changeset
    76
	for interface, ports in pairs(http_services) do -- luacheck: ignore 213/interface
8973
75c3b1bd9d7b mod_http: Rename loop variable to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8972
diff changeset
    77
		for port, service in pairs(ports) do -- luacheck: ignore 512
5093
1ce9e8068dda mod_http: Rework how module:http_url() builds the url.
Kim Alvefur <zash@zash.se>
parents: 5092
diff changeset
    78
			local url = {
8973
75c3b1bd9d7b mod_http: Rename loop variable to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8972
diff changeset
    79
				scheme = (external_url.scheme or service[1].service.name);
5190
76c73bd3d483 mod_http: Make module:http_url() aware of http_host
Kim Alvefur <zash@zash.se>
parents: 5183
diff changeset
    80
				host = (external_url.host or module:get_option_string("http_host", module.host));
5183
8461e8ed7c09 mod_http: Rename variable for clarity
Matthew Wild <mwild1@gmail.com>
parents: 5180
diff changeset
    81
				port = tonumber(external_url.port) or port or 80;
9505
09e7b0048ebe mod_http: Make sure path from http_external_url always ends with a slash (fixes #1183)
Kim Alvefur <zash@zash.se>
parents: 7870
diff changeset
    82
				path = normalize_path(external_url.path or "/", true)..
5093
1ce9e8068dda mod_http: Rework how module:http_url() builds the url.
Kim Alvefur <zash@zash.se>
parents: 5092
diff changeset
    83
					(get_base_path(module, app_name, default_path or "/"..app_name):sub(2));
1ce9e8068dda mod_http: Rework how module:http_url() builds the url.
Kim Alvefur <zash@zash.se>
parents: 5092
diff changeset
    84
			}
1ce9e8068dda mod_http: Rework how module:http_url() builds the url.
Kim Alvefur <zash@zash.se>
parents: 5092
diff changeset
    85
			if ports_by_scheme[url.scheme] == url.port then url.port = nil end
1ce9e8068dda mod_http: Rework how module:http_url() builds the url.
Kim Alvefur <zash@zash.se>
parents: 5092
diff changeset
    86
			return url_build(url);
4892
6c8074f47ca4 mod_http: Add module:http_url([app_name,][default_path]) for a module to get a guess at its external URL
Matthew Wild <mwild1@gmail.com>
parents: 4774
diff changeset
    87
		end
6c8074f47ca4 mod_http: Add module:http_url([app_name,][default_path]) for a module to get a guess at its external URL
Matthew Wild <mwild1@gmail.com>
parents: 4774
diff changeset
    88
	end
6601
4b4852c4f96a mod_http: Return a static string from module:http_url() when no ports are enabled and log a warning
Kim Alvefur <zash@zash.se>
parents: 6600
diff changeset
    89
	module:log("warn", "No http ports enabled, can't generate an external URL");
4b4852c4f96a mod_http: Return a static string from module:http_url() when no ports are enabled and log a warning
Kim Alvefur <zash@zash.se>
parents: 6600
diff changeset
    90
	return "http://disabled.invalid/";
4702
5a85e541de1a mod_http: Switch to single option for specifying HTTP app bases, http_paths. Keys are app/module names, values are base paths.
Matthew Wild <mwild1@gmail.com>
parents: 4696
diff changeset
    91
end
5a85e541de1a mod_http: Switch to single option for specifying HTTP app bases, http_paths. Keys are app/module names, values are base paths.
Matthew Wild <mwild1@gmail.com>
parents: 4696
diff changeset
    92
10262
4ff2f14f9ac7 mod_http: Add support for configuring CORS Access-Control-Allow-Credentials
Matthew Wild <mwild1@gmail.com>
parents: 9856
diff changeset
    93
local function apply_cors_headers(response, methods, headers, max_age, allow_credentials, origin)
9797
9993fd021d19 mod_http: Solve CORS problems once and for all
Kim Alvefur <zash@zash.se>
parents: 9507
diff changeset
    94
	response.headers.access_control_allow_methods = tostring(methods);
9993fd021d19 mod_http: Solve CORS problems once and for all
Kim Alvefur <zash@zash.se>
parents: 9507
diff changeset
    95
	response.headers.access_control_allow_headers = tostring(headers);
9993fd021d19 mod_http: Solve CORS problems once and for all
Kim Alvefur <zash@zash.se>
parents: 9507
diff changeset
    96
	response.headers.access_control_max_age = tostring(max_age)
9993fd021d19 mod_http: Solve CORS problems once and for all
Kim Alvefur <zash@zash.se>
parents: 9507
diff changeset
    97
	response.headers.access_control_allow_origin = origin or "*";
10262
4ff2f14f9ac7 mod_http: Add support for configuring CORS Access-Control-Allow-Credentials
Matthew Wild <mwild1@gmail.com>
parents: 9856
diff changeset
    98
	if allow_credentials then
4ff2f14f9ac7 mod_http: Add support for configuring CORS Access-Control-Allow-Credentials
Matthew Wild <mwild1@gmail.com>
parents: 9856
diff changeset
    99
		response.headers.access_control_allow_credentials = "true";
4ff2f14f9ac7 mod_http: Add support for configuring CORS Access-Control-Allow-Credentials
Matthew Wild <mwild1@gmail.com>
parents: 9856
diff changeset
   100
	end
9797
9993fd021d19 mod_http: Solve CORS problems once and for all
Kim Alvefur <zash@zash.se>
parents: 9507
diff changeset
   101
end
9993fd021d19 mod_http: Solve CORS problems once and for all
Kim Alvefur <zash@zash.se>
parents: 9507
diff changeset
   102
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   103
function module.add_host(module)
9379
220468f7a103 mod_http: Support global HTTP modules
Kim Alvefur <zash@zash.se>
parents: 9341
diff changeset
   104
	local host = module.host;
220468f7a103 mod_http: Support global HTTP modules
Kim Alvefur <zash@zash.se>
parents: 9341
diff changeset
   105
	if host ~= "*" then
220468f7a103 mod_http: Support global HTTP modules
Kim Alvefur <zash@zash.se>
parents: 9341
diff changeset
   106
		host = module:get_option_string("http_host", host);
220468f7a103 mod_http: Support global HTTP modules
Kim Alvefur <zash@zash.se>
parents: 9341
diff changeset
   107
	end
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   108
	local apps = {};
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   109
	module.environment.apps = apps;
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   110
	local function http_app_added(event)
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   111
		local app_name = event.item.name;
4667
d0cfc49f3f2b mod_http: Support for default_path in apps
Matthew Wild <mwild1@gmail.com>
parents: 4664
diff changeset
   112
		local default_app_path = event.item.default_path or "/"..app_name;
4892
6c8074f47ca4 mod_http: Add module:http_url([app_name,][default_path]) for a module to get a guess at its external URL
Matthew Wild <mwild1@gmail.com>
parents: 4774
diff changeset
   113
		local app_path = get_base_path(module, app_name, default_app_path);
6c8074f47ca4 mod_http: Add module:http_url([app_name,][default_path]) for a module to get a guess at its external URL
Matthew Wild <mwild1@gmail.com>
parents: 4774
diff changeset
   114
		if not app_name then
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   115
			-- TODO: Link to docs
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   116
			module:log("error", "HTTP app has no 'name', add one or use module:provides('http', app)");
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   117
			return;
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   118
		end
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   119
		apps[app_name] = apps[app_name] or {};
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   120
		local app_handlers = apps[app_name];
9797
9993fd021d19 mod_http: Solve CORS problems once and for all
Kim Alvefur <zash@zash.se>
parents: 9507
diff changeset
   121
9801
071538a567d5 mod_http: Determine CORS methods to whitelist from actual methods used
Kim Alvefur <zash@zash.se>
parents: 9800
diff changeset
   122
		local app_methods = opt_methods;
071538a567d5 mod_http: Determine CORS methods to whitelist from actual methods used
Kim Alvefur <zash@zash.se>
parents: 9800
diff changeset
   123
9797
9993fd021d19 mod_http: Solve CORS problems once and for all
Kim Alvefur <zash@zash.se>
parents: 9507
diff changeset
   124
		local function cors_handler(event_data)
9993fd021d19 mod_http: Solve CORS problems once and for all
Kim Alvefur <zash@zash.se>
parents: 9507
diff changeset
   125
			local request, response = event_data.request, event_data.response;
10262
4ff2f14f9ac7 mod_http: Add support for configuring CORS Access-Control-Allow-Credentials
Matthew Wild <mwild1@gmail.com>
parents: 9856
diff changeset
   126
			apply_cors_headers(response, app_methods, opt_headers, opt_max_age, opt_credentials, request.headers.origin);
9797
9993fd021d19 mod_http: Solve CORS problems once and for all
Kim Alvefur <zash@zash.se>
parents: 9507
diff changeset
   127
		end
9993fd021d19 mod_http: Solve CORS problems once and for all
Kim Alvefur <zash@zash.se>
parents: 9507
diff changeset
   128
9800
adfb29f44412 mod_http: Set up to handle OPTIONS
Kim Alvefur <zash@zash.se>
parents: 9797
diff changeset
   129
		local function options_handler(event_data)
adfb29f44412 mod_http: Set up to handle OPTIONS
Kim Alvefur <zash@zash.se>
parents: 9797
diff changeset
   130
			cors_handler(event_data);
adfb29f44412 mod_http: Set up to handle OPTIONS
Kim Alvefur <zash@zash.se>
parents: 9797
diff changeset
   131
			return "";
adfb29f44412 mod_http: Set up to handle OPTIONS
Kim Alvefur <zash@zash.se>
parents: 9797
diff changeset
   132
		end
adfb29f44412 mod_http: Set up to handle OPTIONS
Kim Alvefur <zash@zash.se>
parents: 9797
diff changeset
   133
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   134
		for key, handler in pairs(event.item.route or {}) do
4667
d0cfc49f3f2b mod_http: Support for default_path in apps
Matthew Wild <mwild1@gmail.com>
parents: 4664
diff changeset
   135
			local event_name = get_http_event(host, app_path, key);
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   136
			if event_name then
9801
071538a567d5 mod_http: Determine CORS methods to whitelist from actual methods used
Kim Alvefur <zash@zash.se>
parents: 9800
diff changeset
   137
				local method = event_name:match("^%S+");
071538a567d5 mod_http: Determine CORS methods to whitelist from actual methods used
Kim Alvefur <zash@zash.se>
parents: 9800
diff changeset
   138
				if not app_methods:contains(method) then
071538a567d5 mod_http: Determine CORS methods to whitelist from actual methods used
Kim Alvefur <zash@zash.se>
parents: 9800
diff changeset
   139
					app_methods = app_methods + set.new{ method };
071538a567d5 mod_http: Determine CORS methods to whitelist from actual methods used
Kim Alvefur <zash@zash.se>
parents: 9800
diff changeset
   140
				end
9800
adfb29f44412 mod_http: Set up to handle OPTIONS
Kim Alvefur <zash@zash.se>
parents: 9797
diff changeset
   141
				local options_event_name = event_name:gsub("^%S+", "OPTIONS");
4724
a8c234332258 mod_http: Allow a route value to be static data rather than a handler function
Matthew Wild <mwild1@gmail.com>
parents: 4721
diff changeset
   142
				if type(handler) ~= "function" then
a8c234332258 mod_http: Allow a route value to be static data rather than a handler function
Matthew Wild <mwild1@gmail.com>
parents: 4721
diff changeset
   143
					local data = handler;
a8c234332258 mod_http: Allow a route value to be static data rather than a handler function
Matthew Wild <mwild1@gmail.com>
parents: 4721
diff changeset
   144
					handler = function () return data; end
a8c234332258 mod_http: Allow a route value to be static data rather than a handler function
Matthew Wild <mwild1@gmail.com>
parents: 4721
diff changeset
   145
				elseif event_name:sub(-2, -1) == "/*" then
5230
6f5640375358 mod_http: Fix path length pattern
Kim Alvefur <zash@zash.se>
parents: 5204
diff changeset
   146
					local base_path_len = #event_name:match("/.+$");
4669
0e0a72679f77 mod_http: Pass portion of path that matched wildcard to wildcard handlers, as a second parameter
Matthew Wild <mwild1@gmail.com>
parents: 4667
diff changeset
   147
					local _handler = handler;
8975
0b254439d451 mod_http: Rename argument to avoid name clash with outer scope [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8974
diff changeset
   148
					handler = function (_event)
0b254439d451 mod_http: Rename argument to avoid name clash with outer scope [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8974
diff changeset
   149
						local path = _event.request.path:sub(base_path_len);
0b254439d451 mod_http: Rename argument to avoid name clash with outer scope [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8974
diff changeset
   150
						return _handler(_event, path);
4669
0e0a72679f77 mod_http: Pass portion of path that matched wildcard to wildcard handlers, as a second parameter
Matthew Wild <mwild1@gmail.com>
parents: 4667
diff changeset
   151
					end;
6507
e1659f32852e mod_http: For URLs that end with / or wildcard handlers, add a low-priority redirect from without to with slash
Kim Alvefur <zash@zash.se>
parents: 6086
diff changeset
   152
					module:hook_object_event(server, event_name:sub(1, -3), redir_handler, -1);
e1659f32852e mod_http: For URLs that end with / or wildcard handlers, add a low-priority redirect from without to with slash
Kim Alvefur <zash@zash.se>
parents: 6086
diff changeset
   153
				elseif event_name:sub(-1, -1) == "/" then
e1659f32852e mod_http: For URLs that end with / or wildcard handlers, add a low-priority redirect from without to with slash
Kim Alvefur <zash@zash.se>
parents: 6086
diff changeset
   154
					module:hook_object_event(server, event_name:sub(1, -2), redir_handler, -1);
4669
0e0a72679f77 mod_http: Pass portion of path that matched wildcard to wildcard handlers, as a second parameter
Matthew Wild <mwild1@gmail.com>
parents: 4667
diff changeset
   155
				end
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   156
				if not app_handlers[event_name] then
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   157
					app_handlers[event_name] = handler;
4696
4700e318add1 mod_http: Use module:hook/unhook_event_object() so that handlers get unregistered if mod_http is unloaded
Matthew Wild <mwild1@gmail.com>
parents: 4678
diff changeset
   158
					module:hook_object_event(server, event_name, handler);
9797
9993fd021d19 mod_http: Solve CORS problems once and for all
Kim Alvefur <zash@zash.se>
parents: 9507
diff changeset
   159
					module:hook_object_event(server, event_name, cors_handler, 1);
9800
adfb29f44412 mod_http: Set up to handle OPTIONS
Kim Alvefur <zash@zash.se>
parents: 9797
diff changeset
   160
					module:hook_object_event(server, options_event_name, options_handler, -1);
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   161
				else
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   162
					module:log("warn", "App %s added handler twice for '%s', ignoring", app_name, event_name);
4636
41983ec223f0 mod_http: Include handlers of non-global modules.
Waqas Hussain <waqas20@gmail.com>
parents: 4635
diff changeset
   163
				end
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   164
			else
7362
a5a080c12c96 Update every link to the documentation to use HTTPS
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 7250
diff changeset
   165
				module:log("error", "Invalid route in %s, %q. See https://prosody.im/doc/developers/http#routes", app_name, key);
4636
41983ec223f0 mod_http: Include handlers of non-global modules.
Waqas Hussain <waqas20@gmail.com>
parents: 4635
diff changeset
   166
			end
4635
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   167
		end
6600
321321f566fb mod_http: Log a debug message when adding new http apps and warn if no http ports are enabled
Kim Alvefur <zash@zash.se>
parents: 6599
diff changeset
   168
		local services = portmanager.get_active_services();
321321f566fb mod_http: Log a debug message when adding new http apps and warn if no http ports are enabled
Kim Alvefur <zash@zash.se>
parents: 6599
diff changeset
   169
		if services:get("https") or services:get("http") then
321321f566fb mod_http: Log a debug message when adding new http apps and warn if no http ports are enabled
Kim Alvefur <zash@zash.se>
parents: 6599
diff changeset
   170
			module:log("debug", "Serving '%s' at %s", app_name, module:http_url(app_name, app_path));
321321f566fb mod_http: Log a debug message when adding new http apps and warn if no http ports are enabled
Kim Alvefur <zash@zash.se>
parents: 6599
diff changeset
   171
		else
321321f566fb mod_http: Log a debug message when adding new http apps and warn if no http ports are enabled
Kim Alvefur <zash@zash.se>
parents: 6599
diff changeset
   172
			module:log("warn", "Not listening on any ports, '%s' will be unreachable", app_name);
321321f566fb mod_http: Log a debug message when adding new http apps and warn if no http ports are enabled
Kim Alvefur <zash@zash.se>
parents: 6599
diff changeset
   173
		end
4635
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   174
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5427
diff changeset
   175
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   176
	local function http_app_removed(event)
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   177
		local app_handlers = apps[event.item.name];
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   178
		apps[event.item.name] = nil;
8974
e59207c909c0 mod_http: Rename loop variable to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8973
diff changeset
   179
		for event_name, handler in pairs(app_handlers) do
e59207c909c0 mod_http: Rename loop variable to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8973
diff changeset
   180
			module:unhook_object_event(server, event_name, handler);
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   181
		end
4636
41983ec223f0 mod_http: Include handlers of non-global modules.
Waqas Hussain <waqas20@gmail.com>
parents: 4635
diff changeset
   182
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5427
diff changeset
   183
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   184
	module:handle_items("http-provider", http_app_added, http_app_removed);
4736
3514338c59c3 net.http.server, mod_http: Support http_default_host config option to specify where to direct requests for unknown HTTP vhosts
Matthew Wild <mwild1@gmail.com>
parents: 4724
diff changeset
   185
9379
220468f7a103 mod_http: Support global HTTP modules
Kim Alvefur <zash@zash.se>
parents: 9341
diff changeset
   186
	if host ~= "*" then
220468f7a103 mod_http: Support global HTTP modules
Kim Alvefur <zash@zash.se>
parents: 9341
diff changeset
   187
		server.add_host(host);
220468f7a103 mod_http: Support global HTTP modules
Kim Alvefur <zash@zash.se>
parents: 9341
diff changeset
   188
		function module.unload()
220468f7a103 mod_http: Support global HTTP modules
Kim Alvefur <zash@zash.se>
parents: 9341
diff changeset
   189
			server.remove_host(host);
220468f7a103 mod_http: Support global HTTP modules
Kim Alvefur <zash@zash.se>
parents: 9341
diff changeset
   190
		end
4736
3514338c59c3 net.http.server, mod_http: Support http_default_host config option to specify where to direct requests for unknown HTTP vhosts
Matthew Wild <mwild1@gmail.com>
parents: 4724
diff changeset
   191
	end
4635
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   192
end
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   193
9379
220468f7a103 mod_http: Support global HTTP modules
Kim Alvefur <zash@zash.se>
parents: 9341
diff changeset
   194
module.add_host(module); -- set up handling on global context too
220468f7a103 mod_http: Support global HTTP modules
Kim Alvefur <zash@zash.se>
parents: 9341
diff changeset
   195
8597
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   196
local trusted_proxies = module:get_option_set("trusted_proxies", { "127.0.0.1", "::1" })._items;
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   197
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   198
local function get_ip_from_request(request)
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   199
	local ip = request.conn:ip();
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   200
	local forwarded_for = request.headers.x_forwarded_for;
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   201
	if forwarded_for then
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   202
		forwarded_for = forwarded_for..", "..ip;
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   203
		for forwarded_ip in forwarded_for:gmatch("[^%s,]+") do
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   204
			if not trusted_proxies[forwarded_ip] then
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   205
				ip = forwarded_ip;
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   206
			end
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   207
		end
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   208
	end
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   209
	return ip;
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   210
end
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   211
8599
71da54c7f797 mod_http: Pass util.events object to API, fixes traceback
Kim Alvefur <zash@zash.se>
parents: 8597
diff changeset
   212
module:wrap_object_event(server._events, false, function (handlers, event_name, event_data)
8597
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   213
	local request = event_data.request;
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   214
	if request then
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   215
		-- Not included in eg http-error events
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   216
		request.ip = get_ip_from_request(request);
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   217
	end
9341
9beb767295d4 Revert 2dc7490899ae::5d6b252bc36f: Unfinished and broken
Kim Alvefur <zash@zash.se>
parents: 9339
diff changeset
   218
	return handlers(event_name, event_data);
8597
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   219
end);
b4a0bc46c82d mod_http: Set request.ip on all HTTP requests (moves code out of mod_bosh) (fixes #540)
Kim Alvefur <zash@zash.se>
parents: 7871
diff changeset
   220
5120
bcabea740c00 mod_{admin_telnet,c2s,component,http,net_multiplex,s2s}: Use module:provides() instead of module:add_item().
Waqas Hussain <waqas20@gmail.com>
parents: 5093
diff changeset
   221
module:provides("net", {
4635
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   222
	name = "http";
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   223
	listener = server.listener;
4635
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   224
	default_port = 5280;
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   225
	multiplex = {
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   226
		pattern = "^[A-Z]";
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   227
	};
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   228
});
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   229
5120
bcabea740c00 mod_{admin_telnet,c2s,component,http,net_multiplex,s2s}: Use module:provides() instead of module:add_item().
Waqas Hussain <waqas20@gmail.com>
parents: 5093
diff changeset
   230
module:provides("net", {
4635
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   231
	name = "https";
4664
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   232
	listener = server.listener;
7438b3c68576 mod_http: Revamp module for new API and config
Matthew Wild <mwild1@gmail.com>
parents: 4636
diff changeset
   233
	default_port = 5281;
4635
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   234
	encryption = "ssl";
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   235
	multiplex = {
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   236
		pattern = "^[A-Z]";
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   237
	};
ea5215bd2783 mod_http: Provide HTTP service.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   238
});