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.lua53
1 files changed, 47 insertions, 6 deletions
diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua
index a1d409bd..8ef06dc2 100644
--- a/plugins/mod_http.lua
+++ b/plugins/mod_http.lua
@@ -14,6 +14,7 @@ local moduleapi = require "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 server = require "net.http.server";
@@ -22,6 +23,12 @@ server.set_default_host(module:get_option_string("http_default_host"));
server.set_option("body_size_limit", module:get_option_number("http_max_content_size"));
server.set_option("buffer_size_limit", module:get_option_number("http_max_buffer_size"));
+-- CORS settigs
+local opt_methods = module:get_option_set("access_control_allow_methods", { "GET", "OPTIONS" });
+local opt_headers = module:get_option_set("access_control_allow_headers", { "Content-Type" });
+local opt_credentials = module:get_option_boolean("access_control_allow_credentials", false);
+local opt_max_age = module:get_option_number("access_control_max_age", 2 * 60 * 60);
+
local function get_http_event(host, app_path, key)
local method, path = key:match("^(%S+)%s+(.+)$");
if not method then -- No path specified, default to "" (base path)
@@ -83,6 +90,16 @@ function moduleapi.http_url(module, app_name, default_path)
return "http://disabled.invalid/";
end
+local function apply_cors_headers(response, methods, headers, max_age, allow_credentials, origin)
+ response.headers.access_control_allow_methods = tostring(methods);
+ response.headers.access_control_allow_headers = tostring(headers);
+ response.headers.access_control_max_age = tostring(max_age)
+ response.headers.access_control_allow_origin = origin or "*";
+ if allow_credentials then
+ response.headers.access_control_allow_credentials = "true";
+ end
+end
+
function module.add_host(module)
local host = module.host;
if host ~= "*" then
@@ -101,9 +118,27 @@ function module.add_host(module)
end
apps[app_name] = apps[app_name] or {};
local app_handlers = apps[app_name];
+
+ local app_methods = opt_methods;
+
+ local function cors_handler(event_data)
+ local request, response = event_data.request, event_data.response;
+ apply_cors_headers(response, app_methods, opt_headers, opt_max_age, opt_credentials, request.headers.origin);
+ end
+
+ local function options_handler(event_data)
+ cors_handler(event_data);
+ return "";
+ end
+
for key, handler in pairs(event.item.route or {}) do
local event_name = get_http_event(host, app_path, key);
if event_name then
+ local method = event_name:match("^%S+");
+ if not app_methods:contains(method) then
+ app_methods = app_methods + set.new{ method };
+ end
+ local options_event_name = event_name:gsub("^%S+", "OPTIONS");
if type(handler) ~= "function" then
local data = handler;
handler = function () return data; end
@@ -119,8 +154,14 @@ function module.add_host(module)
module:hook_object_event(server, event_name:sub(1, -2), redir_handler, -1);
end
if not app_handlers[event_name] then
- app_handlers[event_name] = handler;
+ app_handlers[event_name] = {
+ main = handler;
+ cors = cors_handler;
+ options = options_handler;
+ };
module:hook_object_event(server, event_name, handler);
+ module:hook_object_event(server, event_name, cors_handler, 1);
+ module:hook_object_event(server, options_event_name, options_handler, -1);
else
module:log("warn", "App %s added handler twice for '%s', ignoring", app_name, event_name);
end
@@ -139,8 +180,11 @@ function module.add_host(module)
local function http_app_removed(event)
local app_handlers = apps[event.item.name];
apps[event.item.name] = nil;
- for event_name, handler in pairs(app_handlers) do
- module:unhook_object_event(server, event_name, handler);
+ for event_name, handlers in pairs(app_handlers) do
+ module:unhook_object_event(server, event_name, handlers.main);
+ module:unhook_object_event(server, event_name, handlers.cors);
+ local options_event_name = event_name:gsub("^%S+", "OPTIONS");
+ module:unhook_object_event(server, options_event_name, handlers.options);
end
end
@@ -195,9 +239,6 @@ module:provides("net", {
listener = server.listener;
default_port = 5281;
encryption = "ssl";
- ssl_config = {
- verify = "none";
- };
multiplex = {
pattern = "^[A-Z]";
};