Mercurial > prosody-hg
comparison plugins/mod_http.lua @ 9797:071538a567d5
mod_http: Determine CORS methods to whitelist from actual methods used
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Thu, 17 Jan 2019 20:42:38 +0100 |
| parents | adfb29f44412 |
| children | 6ea3cafb6ac3 |
comparison
equal
deleted
inserted
replaced
| 9796:adfb29f44412 | 9797:071538a567d5 |
|---|---|
| 12 local portmanager = require "core.portmanager"; | 12 local portmanager = require "core.portmanager"; |
| 13 local moduleapi = require "core.moduleapi"; | 13 local moduleapi = require "core.moduleapi"; |
| 14 local url_parse = require "socket.url".parse; | 14 local url_parse = require "socket.url".parse; |
| 15 local url_build = require "socket.url".build; | 15 local url_build = require "socket.url".build; |
| 16 local normalize_path = require "util.http".normalize_path; | 16 local normalize_path = require "util.http".normalize_path; |
| 17 local set = require "util.set"; | |
| 17 | 18 |
| 18 local server = require "net.http.server"; | 19 local server = require "net.http.server"; |
| 19 | 20 |
| 20 server.set_default_host(module:get_option_string("http_default_host")); | 21 server.set_default_host(module:get_option_string("http_default_host")); |
| 21 | 22 |
| 22 server.set_option("body_size_limit", module:get_option_number("http_max_content_size")); | 23 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")); | 24 server.set_option("buffer_size_limit", module:get_option_number("http_max_buffer_size")); |
| 24 | 25 |
| 25 -- CORS settigs | 26 -- CORS settigs |
| 26 local opt_methods = module:get_option_set("access_control_allow_methods", { "GET", "POST", "PUT", "OPTIONS" }); | 27 local opt_methods = module:get_option_set("access_control_allow_methods", { "GET", "OPTIONS" }); |
| 27 local opt_headers = module:get_option_set("access_control_allow_headers", { "Content-Type" }); | 28 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); | 29 local opt_max_age = module:get_option_number("access_control_max_age", 2 * 60 * 60); |
| 29 | 30 |
| 30 local function get_http_event(host, app_path, key) | 31 local function get_http_event(host, app_path, key) |
| 31 local method, path = key:match("^(%S+)%s+(.+)$"); | 32 local method, path = key:match("^(%S+)%s+(.+)$"); |
| 112 return; | 113 return; |
| 113 end | 114 end |
| 114 apps[app_name] = apps[app_name] or {}; | 115 apps[app_name] = apps[app_name] or {}; |
| 115 local app_handlers = apps[app_name]; | 116 local app_handlers = apps[app_name]; |
| 116 | 117 |
| 118 local app_methods = opt_methods; | |
| 119 | |
| 117 local function cors_handler(event_data) | 120 local function cors_handler(event_data) |
| 118 local request, response = event_data.request, event_data.response; | 121 local request, response = event_data.request, event_data.response; |
| 119 apply_cors_headers(response, opt_methods, opt_headers, opt_max_age, request.headers.origin); | 122 apply_cors_headers(response, app_methods, opt_headers, opt_max_age, request.headers.origin); |
| 120 end | 123 end |
| 121 | 124 |
| 122 local function options_handler(event_data) | 125 local function options_handler(event_data) |
| 123 cors_handler(event_data); | 126 cors_handler(event_data); |
| 124 return ""; | 127 return ""; |
| 125 end | 128 end |
| 126 | 129 |
| 127 for key, handler in pairs(event.item.route or {}) do | 130 for key, handler in pairs(event.item.route or {}) do |
| 128 local event_name = get_http_event(host, app_path, key); | 131 local event_name = get_http_event(host, app_path, key); |
| 129 if event_name then | 132 if event_name then |
| 133 local method = event_name:match("^%S+"); | |
| 134 if not app_methods:contains(method) then | |
| 135 app_methods = app_methods + set.new{ method }; | |
| 136 end | |
| 130 local options_event_name = event_name:gsub("^%S+", "OPTIONS"); | 137 local options_event_name = event_name:gsub("^%S+", "OPTIONS"); |
| 131 if type(handler) ~= "function" then | 138 if type(handler) ~= "function" then |
| 132 local data = handler; | 139 local data = handler; |
| 133 handler = function () return data; end | 140 handler = function () return data; end |
| 134 elseif event_name:sub(-2, -1) == "/*" then | 141 elseif event_name:sub(-2, -1) == "/*" then |
