Software /
code /
prosody
Comparison
plugins/mod_http.lua @ 9793:9993fd021d19
mod_http: Solve CORS problems once and for all
This blindly allows any cross-site requests.
Future work should add an API to allow each HTTP app some influence over
this for each HTTP path
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Thu, 04 Oct 2018 12:22:12 +0200 |
parent | 9504:cfbea3064aa9 |
child | 9796:adfb29f44412 |
comparison
equal
deleted
inserted
replaced
9792:561b0e20e901 | 9793:9993fd021d19 |
---|---|
19 | 19 |
20 server.set_default_host(module:get_option_string("http_default_host")); | 20 server.set_default_host(module:get_option_string("http_default_host")); |
21 | 21 |
22 server.set_option("body_size_limit", module:get_option_number("http_max_content_size")); | 22 server.set_option("body_size_limit", module:get_option_number("http_max_content_size")); |
23 server.set_option("buffer_size_limit", module:get_option_number("http_max_buffer_size")); | 23 server.set_option("buffer_size_limit", module:get_option_number("http_max_buffer_size")); |
24 | |
25 -- CORS settigs | |
26 local opt_methods = module:get_option_set("access_control_allow_methods", { "GET", "POST", "PUT", "OPTIONS" }); | |
27 local opt_headers = module:get_option_set("access_control_allow_headers", { "Content-Type" }); | |
28 local opt_max_age = module:get_option_number("access_control_max_age", 2 * 60 * 60); | |
24 | 29 |
25 local function get_http_event(host, app_path, key) | 30 local function get_http_event(host, app_path, key) |
26 local method, path = key:match("^(%S+)%s+(.+)$"); | 31 local method, path = key:match("^(%S+)%s+(.+)$"); |
27 if not method then -- No path specified, default to "" (base path) | 32 if not method then -- No path specified, default to "" (base path) |
28 method, path = key, ""; | 33 method, path = key, ""; |
81 end | 86 end |
82 module:log("warn", "No http ports enabled, can't generate an external URL"); | 87 module:log("warn", "No http ports enabled, can't generate an external URL"); |
83 return "http://disabled.invalid/"; | 88 return "http://disabled.invalid/"; |
84 end | 89 end |
85 | 90 |
91 local function apply_cors_headers(response, methods, headers, max_age, origin) | |
92 response.headers.access_control_allow_methods = tostring(methods); | |
93 response.headers.access_control_allow_headers = tostring(headers); | |
94 response.headers.access_control_max_age = tostring(max_age) | |
95 response.headers.access_control_allow_origin = origin or "*"; | |
96 end | |
97 | |
86 function module.add_host(module) | 98 function module.add_host(module) |
87 local host = module.host; | 99 local host = module.host; |
88 if host ~= "*" then | 100 if host ~= "*" then |
89 host = module:get_option_string("http_host", host); | 101 host = module:get_option_string("http_host", host); |
90 end | 102 end |
99 module:log("error", "HTTP app has no 'name', add one or use module:provides('http', app)"); | 111 module:log("error", "HTTP app has no 'name', add one or use module:provides('http', app)"); |
100 return; | 112 return; |
101 end | 113 end |
102 apps[app_name] = apps[app_name] or {}; | 114 apps[app_name] = apps[app_name] or {}; |
103 local app_handlers = apps[app_name]; | 115 local app_handlers = apps[app_name]; |
116 | |
117 local function cors_handler(event_data) | |
118 local request, response = event_data.request, event_data.response; | |
119 apply_cors_headers(response, opt_methods, opt_headers, opt_max_age, request.headers.origin); | |
120 end | |
121 | |
104 for key, handler in pairs(event.item.route or {}) do | 122 for key, handler in pairs(event.item.route or {}) do |
105 local event_name = get_http_event(host, app_path, key); | 123 local event_name = get_http_event(host, app_path, key); |
106 if event_name then | 124 if event_name then |
107 if type(handler) ~= "function" then | 125 if type(handler) ~= "function" then |
108 local data = handler; | 126 local data = handler; |
119 module:hook_object_event(server, event_name:sub(1, -2), redir_handler, -1); | 137 module:hook_object_event(server, event_name:sub(1, -2), redir_handler, -1); |
120 end | 138 end |
121 if not app_handlers[event_name] then | 139 if not app_handlers[event_name] then |
122 app_handlers[event_name] = handler; | 140 app_handlers[event_name] = handler; |
123 module:hook_object_event(server, event_name, handler); | 141 module:hook_object_event(server, event_name, handler); |
142 module:hook_object_event(server, event_name, cors_handler, 1); | |
124 else | 143 else |
125 module:log("warn", "App %s added handler twice for '%s', ignoring", app_name, event_name); | 144 module:log("warn", "App %s added handler twice for '%s', ignoring", app_name, event_name); |
126 end | 145 end |
127 else | 146 else |
128 module:log("error", "Invalid route in %s, %q. See https://prosody.im/doc/developers/http#routes", app_name, key); | 147 module:log("error", "Invalid route in %s, %q. See https://prosody.im/doc/developers/http#routes", app_name, key); |