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]; |