Mercurial > prosody-modules
comparison mod_http_upload/mod_http_upload.lua @ 2731:d48faff92490
mod_http_upload: Remove MIME type restrictions and checking (fixes #958)
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sat, 22 Jul 2017 23:14:13 +0200 |
| parents | 785465f8af3d |
| children | b1c5b0c369c2 |
comparison
equal
deleted
inserted
replaced
| 2730:cd828b1cb5b9 | 2731:d48faff92490 |
|---|---|
| 29 | 29 |
| 30 -- config | 30 -- config |
| 31 local file_size_limit = module:get_option_number(module.name .. "_file_size_limit", 1024 * 1024); -- 1 MB | 31 local file_size_limit = module:get_option_number(module.name .. "_file_size_limit", 1024 * 1024); -- 1 MB |
| 32 local quota = module:get_option_number(module.name .. "_quota"); | 32 local quota = module:get_option_number(module.name .. "_quota"); |
| 33 local max_age = module:get_option_number(module.name .. "_expire_after"); | 33 local max_age = module:get_option_number(module.name .. "_expire_after"); |
| 34 local allowed_file_types = module:get_option_set(module.name .. "_allowed_file_types"); | |
| 35 | 34 |
| 36 --- sanity | 35 --- sanity |
| 37 local parser_body_limit = module:context("*"):get_option_number("http_max_content_size", 10*1024*1024); | 36 local parser_body_limit = module:context("*"):get_option_number("http_max_content_size", 10*1024*1024); |
| 38 if file_size_limit > parser_body_limit then | 37 if file_size_limit > parser_body_limit then |
| 39 module:log("warn", "%s_file_size_limit exceeds HTTP parser limit on body size, capping file size to %d B", | 38 module:log("warn", "%s_file_size_limit exceeds HTTP parser limit on body size, capping file size to %d B", |
| 44 -- depends | 43 -- depends |
| 45 module:depends("http"); | 44 module:depends("http"); |
| 46 module:depends("disco"); | 45 module:depends("disco"); |
| 47 | 46 |
| 48 local http_files = module:depends("http_files"); | 47 local http_files = module:depends("http_files"); |
| 49 local mime_map = module:shared("/*/http_files/mime").types; | |
| 50 | 48 |
| 51 -- namespaces | 49 -- namespaces |
| 52 local namespace = "urn:xmpp:http:upload:0"; | 50 local namespace = "urn:xmpp:http:upload:0"; |
| 53 local legacy_namespace = "urn:xmpp:http:upload"; | 51 local legacy_namespace = "urn:xmpp:http:upload"; |
| 54 | 52 |
| 108 sum = sum + item.size; | 106 sum = sum + item.size; |
| 109 end | 107 end |
| 110 return sum < quota; | 108 return sum < quota; |
| 111 end | 109 end |
| 112 | 110 |
| 113 local function handle_request(origin, stanza, xmlns, filename, filesize, mimetype) | 111 local function handle_request(origin, stanza, xmlns, filename, filesize) |
| 114 local username, host = origin.username, origin.host; | 112 local username, host = origin.username, origin.host; |
| 115 -- local clients only | 113 -- local clients only |
| 116 if origin.type ~= "c2s" then | 114 if origin.type ~= "c2s" then |
| 117 module:log("debug", "Request for upload slot from a %s", origin.type); | 115 module:log("debug", "Request for upload slot from a %s", origin.type); |
| 118 origin.send(st.error_reply(stanza, "cancel", "not-authorized")); | 116 origin.send(st.error_reply(stanza, "cancel", "not-authorized")); |
| 137 return true; | 135 return true; |
| 138 elseif not check_quota(username, host, filesize) then | 136 elseif not check_quota(username, host, filesize) then |
| 139 module:log("debug", "Upload of %dB by %s would exceed quota", filesize, origin.full_jid); | 137 module:log("debug", "Upload of %dB by %s would exceed quota", filesize, origin.full_jid); |
| 140 origin.send(st.error_reply(stanza, "wait", "resource-constraint", "Quota reached")); | 138 origin.send(st.error_reply(stanza, "wait", "resource-constraint", "Quota reached")); |
| 141 return true; | 139 return true; |
| 142 end | |
| 143 | |
| 144 if mime_map then | |
| 145 local file_ext = filename:match("%.([^.]+)$"); | |
| 146 if not mimetype then | |
| 147 mimetype = "application/octet-stream"; | |
| 148 if file_ext then | |
| 149 mimetype = mime_map[file_ext] or mimetype; | |
| 150 end | |
| 151 else | |
| 152 if (not file_ext and mimetype ~= "application/octet-stream") or (file_ext and mime_map[file_ext] ~= mimetype) then | |
| 153 origin.send(st.error_reply(stanza, "modify", "bad-request", "MIME type does not match file extension")); | |
| 154 return true; | |
| 155 end | |
| 156 end | |
| 157 end | |
| 158 | |
| 159 if allowed_file_types then | |
| 160 if not (allowed_file_types:contains(mimetype) or allowed_file_types:contains(mimetype:gsub("/.*", "/*"))) then | |
| 161 origin.send(st.error_reply(stanza, "cancel", "not-allowed", "File type not allowed")); | |
| 162 return true; | |
| 163 end | |
| 164 end | 140 end |
| 165 | 141 |
| 166 local reply = st.reply(stanza); | 142 local reply = st.reply(stanza); |
| 167 reply:tag("slot", { xmlns = xmlns }); | 143 reply:tag("slot", { xmlns = xmlns }); |
| 168 | 144 |
| 205 module:hook("iq/host/"..namespace..":request", function (event) | 181 module:hook("iq/host/"..namespace..":request", function (event) |
| 206 local stanza, origin = event.stanza, event.origin; | 182 local stanza, origin = event.stanza, event.origin; |
| 207 local request = stanza.tags[1]; | 183 local request = stanza.tags[1]; |
| 208 local filename = request.attr.filename; | 184 local filename = request.attr.filename; |
| 209 local filesize = tonumber(request.attr.size); | 185 local filesize = tonumber(request.attr.size); |
| 210 local mimetype = request.attr["content-type"]; | 186 return handle_request(origin, stanza, namespace, filename, filesize); |
| 211 return handle_request(origin, stanza, namespace, filename, filesize, mimetype); | |
| 212 end); | 187 end); |
| 213 | 188 |
| 214 module:hook("iq/host/"..legacy_namespace..":request", function (event) | 189 module:hook("iq/host/"..legacy_namespace..":request", function (event) |
| 215 local stanza, origin = event.stanza, event.origin; | 190 local stanza, origin = event.stanza, event.origin; |
| 216 local request = stanza.tags[1]; | 191 local request = stanza.tags[1]; |
| 217 local filename = request:get_child_text("filename"); | 192 local filename = request:get_child_text("filename"); |
| 218 local filesize = tonumber(request:get_child_text("size")); | 193 local filesize = tonumber(request:get_child_text("size")); |
| 219 local mimetype = request:get_child_text("content-type"); | 194 return handle_request(origin, stanza, legacy_namespace, filename, filesize); |
| 220 return handle_request(origin, stanza, legacy_namespace, filename, filesize, mimetype); | |
| 221 end); | 195 end); |
| 222 | 196 |
| 223 -- http service | 197 -- http service |
| 224 local function upload_data(event, path) | 198 local function upload_data(event, path) |
| 225 local uploader = pending_slots[path]; | 199 local uploader = pending_slots[path]; |
