Mercurial > prosody-hg
comparison plugins/mod_http.lua @ 12443:17d87fb2312a 0.12
mod_http: Reintroduce support for disabling or limiting CORS (fixes #1730)
This is far better than pre-0.12, because we now have a universal way to
configure and enable/disable CORS on a per-module basis.
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Mon, 28 Mar 2022 14:40:21 +0100 |
| parents | a19d435dee90 |
| children | b33558969b3e |
comparison
equal
deleted
inserted
replaced
| 12441:dc6263625069 | 12443:17d87fb2312a |
|---|---|
| 29 | 29 |
| 30 server.set_option("body_size_limit", module:get_option_number("http_max_content_size")); | 30 server.set_option("body_size_limit", module:get_option_number("http_max_content_size")); |
| 31 server.set_option("buffer_size_limit", module:get_option_number("http_max_buffer_size")); | 31 server.set_option("buffer_size_limit", module:get_option_number("http_max_buffer_size")); |
| 32 | 32 |
| 33 -- CORS settings | 33 -- CORS settings |
| 34 local cors_overrides = module:get_option("http_cors_override", {}); | |
| 34 local opt_methods = module:get_option_set("access_control_allow_methods", { "GET", "OPTIONS" }); | 35 local opt_methods = module:get_option_set("access_control_allow_methods", { "GET", "OPTIONS" }); |
| 35 local opt_headers = module:get_option_set("access_control_allow_headers", { "Content-Type" }); | 36 local opt_headers = module:get_option_set("access_control_allow_headers", { "Content-Type" }); |
| 37 local opt_origins = module:get_option_set("access_control_allow_origins"); | |
| 36 local opt_credentials = module:get_option_boolean("access_control_allow_credentials", false); | 38 local opt_credentials = module:get_option_boolean("access_control_allow_credentials", false); |
| 37 local opt_max_age = module:get_option_number("access_control_max_age", 2 * 60 * 60); | 39 local opt_max_age = module:get_option_number("access_control_max_age", 2 * 60 * 60); |
| 38 | 40 |
| 39 local function get_http_event(host, app_path, key) | 41 local function get_http_event(host, app_path, key) |
| 40 local method, path = key:match("^(%S+)%s+(.+)$"); | 42 local method, path = key:match("^(%S+)%s+(.+)$"); |
| 107 module:log("warn", "No http ports enabled, can't generate an external URL"); | 109 module:log("warn", "No http ports enabled, can't generate an external URL"); |
| 108 end | 110 end |
| 109 return "http://disabled.invalid/"; | 111 return "http://disabled.invalid/"; |
| 110 end | 112 end |
| 111 | 113 |
| 112 local function apply_cors_headers(response, methods, headers, max_age, allow_credentials, origin) | 114 local function apply_cors_headers(response, methods, headers, max_age, allow_credentials, allowed_origins, origin) |
| 115 if allowed_origins and not allowed_origins[origin] then | |
| 116 return; | |
| 117 end | |
| 113 response.headers.access_control_allow_methods = tostring(methods); | 118 response.headers.access_control_allow_methods = tostring(methods); |
| 114 response.headers.access_control_allow_headers = tostring(headers); | 119 response.headers.access_control_allow_headers = tostring(headers); |
| 115 response.headers.access_control_max_age = tostring(max_age) | 120 response.headers.access_control_max_age = tostring(max_age) |
| 116 response.headers.access_control_allow_origin = origin or "*"; | 121 response.headers.access_control_allow_origin = origin or "*"; |
| 117 if allow_credentials then | 122 if allow_credentials then |
| 139 local app_handlers = apps[app_name]; | 144 local app_handlers = apps[app_name]; |
| 140 | 145 |
| 141 local app_methods = opt_methods; | 146 local app_methods = opt_methods; |
| 142 local app_headers = opt_headers; | 147 local app_headers = opt_headers; |
| 143 local app_credentials = opt_credentials; | 148 local app_credentials = opt_credentials; |
| 149 local app_origins; | |
| 150 if opt_origins and not (opt_origins:empty() or opt_origins:contains("*")) then | |
| 151 opt_origins = opt_origins._items; | |
| 152 end | |
| 144 | 153 |
| 145 local function cors_handler(event_data) | 154 local function cors_handler(event_data) |
| 146 local request, response = event_data.request, event_data.response; | 155 local request, response = event_data.request, event_data.response; |
| 147 apply_cors_headers(response, app_methods, app_headers, opt_max_age, app_credentials, request.headers.origin); | 156 apply_cors_headers(response, app_methods, app_headers, opt_max_age, app_credentials, app_origins, request.headers.origin); |
| 148 end | 157 end |
| 149 | 158 |
| 150 local function options_handler(event_data) | 159 local function options_handler(event_data) |
| 151 cors_handler(event_data); | 160 cors_handler(event_data); |
| 152 return ""; | 161 return ""; |
| 153 end | 162 end |
| 154 | 163 |
| 155 if event.item.cors then | 164 local cors = cors_overrides[app_name] or event.item.cors; |
| 156 local cors = event.item.cors; | 165 if cors then |
| 157 if cors.credentials ~= nil then | 166 if cors.enabled ~= false then |
| 158 app_credentials = cors.credentials; | 167 if cors.credentials ~= nil then |
| 159 end | 168 app_credentials = cors.credentials; |
| 160 if cors.headers then | 169 end |
| 161 for header, enable in pairs(cors.headers) do | 170 if cors.headers then |
| 162 if enable and not app_headers:contains(header) then | 171 for header, enable in pairs(cors.headers) do |
| 163 app_headers = app_headers + set.new { header }; | 172 if enable and not app_headers:contains(header) then |
| 164 elseif not enable and app_headers:contains(header) then | 173 app_headers = app_headers + set.new { header }; |
| 165 app_headers = app_headers - set.new { header }; | 174 elseif not enable and app_headers:contains(header) then |
| 175 app_headers = app_headers - set.new { header }; | |
| 176 end | |
| 177 end | |
| 178 end | |
| 179 if cors.origins then | |
| 180 if cors.origins == "*" or cors.origins[1] == "*" then | |
| 181 app_origins = nil; | |
| 182 else | |
| 183 app_origins = set.new(cors.origins)._items; | |
| 166 end | 184 end |
| 167 end | 185 end |
| 168 end | 186 end |
| 169 end | 187 end |
| 170 | 188 |
