Mercurial > prosody-modules
annotate mod_http_upload/mod_http_upload.lua @ 2684:e491a15d7621
mod_http_upload: Switch to using a map store
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Thu, 13 Apr 2017 22:18:28 +0200 |
parents | d0948bd96a7b |
children | 5f0b755b42a3 |
rev | line source |
---|---|
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
1 -- mod_http_upload |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
2 -- |
2677
6daaa1ad2559
mod_http_upload: Add option for expiry of files after a configurable time (closes #557)
Kim Alvefur <zash@zash.se>
parents:
2667
diff
changeset
|
3 -- Copyright (C) 2015-2017 Kim Alvefur |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
4 -- |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
5 -- This file is MIT/X11 licensed. |
2065
624e3fed6f92
mod_http_upload: Trim trailing whitespace
Kim Alvefur <zash@zash.se>
parents:
2053
diff
changeset
|
6 -- |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
7 -- Implementation of HTTP Upload file transfer mechanism used by Conversations |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
8 -- |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
9 |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
10 -- imports |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
11 local st = require"util.stanza"; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
12 local lfs = require"lfs"; |
2286
0a3f526779a1
mod_http_upload: Construct the upload slot URL using the LuaSocket URL library (fixes #717)
Kim Alvefur <zash@zash.se>
parents:
2285
diff
changeset
|
13 local url = require "socket.url"; |
2066
cb74e4ab13f0
mod_http_upload: Advertise maximum file size in disco#info (Per XEP-0363 v0.2)
Kim Alvefur <zash@zash.se>
parents:
2065
diff
changeset
|
14 local dataform = require "util.dataforms".new; |
1912
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
15 local t_concat = table.concat; |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
16 local t_insert = table.insert; |
1914
b01d60dfa405
mod_http_upload: Add missing local of string.upper (Thanks Thilo)
Kim Alvefur <zash@zash.se>
parents:
1912
diff
changeset
|
17 local s_upper = string.upper; |
2665
cfb7936ff61f
mod_http_upload: Use the new util.id if available (in 0.10+)
Kim Alvefur <zash@zash.se>
parents:
2651
diff
changeset
|
18 local have_id, id = pcall(require, "util.id"); -- Only available in 0.10+ |
2646
45ef16ebe565
mod_http_upload: Generate shorter directory names (closes #822)
Kim Alvefur <zash@zash.se>
parents:
2641
diff
changeset
|
19 local uuid = require"util.uuid".generate; |
2665
cfb7936ff61f
mod_http_upload: Use the new util.id if available (in 0.10+)
Kim Alvefur <zash@zash.se>
parents:
2651
diff
changeset
|
20 if have_id then |
2666
99c0b1bacdcd
mod_http_upload: Where did those parenthesis come from?
Kim Alvefur <zash@zash.se>
parents:
2665
diff
changeset
|
21 uuid = id.medium; |
2646
45ef16ebe565
mod_http_upload: Generate shorter directory names (closes #822)
Kim Alvefur <zash@zash.se>
parents:
2641
diff
changeset
|
22 end |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
23 |
2646
45ef16ebe565
mod_http_upload: Generate shorter directory names (closes #822)
Kim Alvefur <zash@zash.se>
parents:
2641
diff
changeset
|
24 local function join_path(...) -- COMPAT util.path was added in 0.10 |
2476
024a4143baef
mod_http_upload: Add missing return statement
Kim Alvefur <zash@zash.se>
parents:
2475
diff
changeset
|
25 return table.concat({ ... }, package.config:sub(1,1)); |
1815
abacf6698d97
mod_http_upload: Include join_path function, should make it work with 0.9.x
Kim Alvefur <zash@zash.se>
parents:
1805
diff
changeset
|
26 end |
abacf6698d97
mod_http_upload: Include join_path function, should make it work with 0.9.x
Kim Alvefur <zash@zash.se>
parents:
1805
diff
changeset
|
27 |
1851
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1850
diff
changeset
|
28 -- config |
2053
40056a27f394
mod_http_upload: Lower default size limit to 1MB
Kim Alvefur <zash@zash.se>
parents:
1967
diff
changeset
|
29 local file_size_limit = module:get_option_number(module.name .. "_file_size_limit", 1024 * 1024); -- 1 MB |
2678
2dec7cad9218
mod_http_upload: Implement quota support (closes #823)
Kim Alvefur <zash@zash.se>
parents:
2677
diff
changeset
|
30 local quota = module:get_option_number(module.name .. "_quota"); |
2677
6daaa1ad2559
mod_http_upload: Add option for expiry of files after a configurable time (closes #557)
Kim Alvefur <zash@zash.se>
parents:
2667
diff
changeset
|
31 local max_age = module:get_option_number(module.name .. "_expire_after"); |
2683
d0948bd96a7b
mod_http_upload: Add support for limiting file types to upload
Kim Alvefur <zash@zash.se>
parents:
2682
diff
changeset
|
32 local allowed_file_types = module:get_option_set(module.name .. "_allowed_file_types"); |
1851
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1850
diff
changeset
|
33 |
2285
f1923bf329a3
mod_http_upload: Warn if upload size limit set higher than body size limit in http parser (applies to 0.10+)
Kim Alvefur <zash@zash.se>
parents:
2231
diff
changeset
|
34 --- sanity |
f1923bf329a3
mod_http_upload: Warn if upload size limit set higher than body size limit in http parser (applies to 0.10+)
Kim Alvefur <zash@zash.se>
parents:
2231
diff
changeset
|
35 local parser_body_limit = module:context("*"):get_option_number("http_max_content_size", 10*1024*1024); |
f1923bf329a3
mod_http_upload: Warn if upload size limit set higher than body size limit in http parser (applies to 0.10+)
Kim Alvefur <zash@zash.se>
parents:
2231
diff
changeset
|
36 if file_size_limit > parser_body_limit then |
2648
4c92e2e897c8
mod_http_upload: Split some long lines [luacheck]
Kim Alvefur <zash@zash.se>
parents:
2647
diff
changeset
|
37 module:log("warn", "%s_file_size_limit exceeds HTTP parser limit on body size, capping file size to %d B", |
4c92e2e897c8
mod_http_upload: Split some long lines [luacheck]
Kim Alvefur <zash@zash.se>
parents:
2647
diff
changeset
|
38 module.name, parser_body_limit); |
2285
f1923bf329a3
mod_http_upload: Warn if upload size limit set higher than body size limit in http parser (applies to 0.10+)
Kim Alvefur <zash@zash.se>
parents:
2231
diff
changeset
|
39 file_size_limit = parser_body_limit; |
f1923bf329a3
mod_http_upload: Warn if upload size limit set higher than body size limit in http parser (applies to 0.10+)
Kim Alvefur <zash@zash.se>
parents:
2231
diff
changeset
|
40 end |
f1923bf329a3
mod_http_upload: Warn if upload size limit set higher than body size limit in http parser (applies to 0.10+)
Kim Alvefur <zash@zash.se>
parents:
2231
diff
changeset
|
41 |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
42 -- depends |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
43 module:depends("http"); |
1805
25c28644fae8
mod_http_upload: Depend on mod_disco, allows it to be discovered when set up as a component
Kim Alvefur <zash@zash.se>
parents:
1772
diff
changeset
|
44 module:depends("disco"); |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
45 |
2680
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
46 local http_files = module:depends("http_files"); |
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
47 local mime_map = module:shared("/*/http_files/mime").types; |
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
48 |
2641
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
49 -- namespaces |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
50 local namespace = "urn:xmpp:http:upload:0"; |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
51 local legacy_namespace = "urn:xmpp:http:upload"; |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
52 |
2287 | 53 -- identity and feature advertising |
2444
3e9f9cef9c0e
mod_http_upload: Add missing semicolon
Kim Alvefur <zash@zash.se>
parents:
2443
diff
changeset
|
54 module:add_identity("store", "file", module:get_option_string("name", "HTTP File Upload")); |
2641
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
55 module:add_feature(namespace); |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
56 module:add_feature(legacy_namespace); |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
57 |
2066
cb74e4ab13f0
mod_http_upload: Advertise maximum file size in disco#info (Per XEP-0363 v0.2)
Kim Alvefur <zash@zash.se>
parents:
2065
diff
changeset
|
58 module:add_extension(dataform { |
2641
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
59 { name = "FORM_TYPE", type = "hidden", value = namespace }, |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
60 { name = "max-file-size", type = "text-single" }, |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
61 }:form({ ["max-file-size"] = tostring(file_size_limit) }, "result")); |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
62 |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
63 module:add_extension(dataform { |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
64 { name = "FORM_TYPE", type = "hidden", value = legacy_namespace }, |
2066
cb74e4ab13f0
mod_http_upload: Advertise maximum file size in disco#info (Per XEP-0363 v0.2)
Kim Alvefur <zash@zash.se>
parents:
2065
diff
changeset
|
65 { name = "max-file-size", type = "text-single" }, |
cb74e4ab13f0
mod_http_upload: Advertise maximum file size in disco#info (Per XEP-0363 v0.2)
Kim Alvefur <zash@zash.se>
parents:
2065
diff
changeset
|
66 }:form({ ["max-file-size"] = tostring(file_size_limit) }, "result")); |
cb74e4ab13f0
mod_http_upload: Advertise maximum file size in disco#info (Per XEP-0363 v0.2)
Kim Alvefur <zash@zash.se>
parents:
2065
diff
changeset
|
67 |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
68 -- state |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
69 local pending_slots = module:shared("upload_slots"); |
2684
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
70 local used_slots = module:open_store(); |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
71 local slot_map = module:open_store(nil, "map"); |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
72 |
1967
2ce2b194d501
mod_http_upload: Make file system path configurable
Kim Alvefur <zash@zash.se>
parents:
1966
diff
changeset
|
73 local storage_path = module:get_option_string(module.name .. "_path", join_path(prosody.paths.data, module.name)); |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
74 lfs.mkdir(storage_path); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
75 |
2684
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
76 local function k(u, h) return h ~= module.host and u .. "@" .. h or u; end |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
77 |
2677
6daaa1ad2559
mod_http_upload: Add option for expiry of files after a configurable time (closes #557)
Kim Alvefur <zash@zash.se>
parents:
2667
diff
changeset
|
78 local function expire(username, host) |
6daaa1ad2559
mod_http_upload: Add option for expiry of files after a configurable time (closes #557)
Kim Alvefur <zash@zash.se>
parents:
2667
diff
changeset
|
79 if not max_age then return true; end |
2684
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
80 local uploads, err = used_slots:get(k(username, host)); |
2677
6daaa1ad2559
mod_http_upload: Add option for expiry of files after a configurable time (closes #557)
Kim Alvefur <zash@zash.se>
parents:
2667
diff
changeset
|
81 if not uploads then return true; end |
6daaa1ad2559
mod_http_upload: Add option for expiry of files after a configurable time (closes #557)
Kim Alvefur <zash@zash.se>
parents:
2667
diff
changeset
|
82 local expiry = os.time() - max_age; |
2684
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
83 local upload_window = os.time() - 900; |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
84 for slot, item in pairs(uploads) do |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
85 local full_filename = join_path(storage_path, item.dir, item.filename); |
2677
6daaa1ad2559
mod_http_upload: Add option for expiry of files after a configurable time (closes #557)
Kim Alvefur <zash@zash.se>
parents:
2667
diff
changeset
|
86 if item.time < expiry then |
2684
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
87 local deleted, whynot = os.remove(full_filename); |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
88 if deleted then |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
89 module:log("debug", "Deleted expired upload %s", item.filename); |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
90 else |
2677
6daaa1ad2559
mod_http_upload: Add option for expiry of files after a configurable time (closes #557)
Kim Alvefur <zash@zash.se>
parents:
2667
diff
changeset
|
91 module:log("warn", "Could not delete expired upload %s: %s", item.filename, whynot or "delete failed"); |
6daaa1ad2559
mod_http_upload: Add option for expiry of files after a configurable time (closes #557)
Kim Alvefur <zash@zash.se>
parents:
2667
diff
changeset
|
92 end |
2684
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
93 uploads[slot] = nil; |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
94 elseif item.time < upload_window and not lfs.attributes(full_filename) then |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
95 pending_slots[slot] = nil; |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
96 uploads[slot] = nil; |
2677
6daaa1ad2559
mod_http_upload: Add option for expiry of files after a configurable time (closes #557)
Kim Alvefur <zash@zash.se>
parents:
2667
diff
changeset
|
97 end |
2684
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
98 end |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
99 return used_slots:set(k(username, host), uploads); |
2677
6daaa1ad2559
mod_http_upload: Add option for expiry of files after a configurable time (closes #557)
Kim Alvefur <zash@zash.se>
parents:
2667
diff
changeset
|
100 end |
6daaa1ad2559
mod_http_upload: Add option for expiry of files after a configurable time (closes #557)
Kim Alvefur <zash@zash.se>
parents:
2667
diff
changeset
|
101 |
2678
2dec7cad9218
mod_http_upload: Implement quota support (closes #823)
Kim Alvefur <zash@zash.se>
parents:
2677
diff
changeset
|
102 local function check_quota(username, host, does_it_fit) |
2dec7cad9218
mod_http_upload: Implement quota support (closes #823)
Kim Alvefur <zash@zash.se>
parents:
2677
diff
changeset
|
103 if not quota then return true; end |
2684
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
104 local uploads, err = used_slots:get(k(username, host)); |
2678
2dec7cad9218
mod_http_upload: Implement quota support (closes #823)
Kim Alvefur <zash@zash.se>
parents:
2677
diff
changeset
|
105 if not uploads then return true; end |
2dec7cad9218
mod_http_upload: Implement quota support (closes #823)
Kim Alvefur <zash@zash.se>
parents:
2677
diff
changeset
|
106 local sum = does_it_fit or 0; |
2684
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
107 for _, item in pairs(uploads) do |
2678
2dec7cad9218
mod_http_upload: Implement quota support (closes #823)
Kim Alvefur <zash@zash.se>
parents:
2677
diff
changeset
|
108 sum = sum + item.size; |
2dec7cad9218
mod_http_upload: Implement quota support (closes #823)
Kim Alvefur <zash@zash.se>
parents:
2677
diff
changeset
|
109 end |
2dec7cad9218
mod_http_upload: Implement quota support (closes #823)
Kim Alvefur <zash@zash.se>
parents:
2677
diff
changeset
|
110 return sum < quota; |
2dec7cad9218
mod_http_upload: Implement quota support (closes #823)
Kim Alvefur <zash@zash.se>
parents:
2677
diff
changeset
|
111 end |
2dec7cad9218
mod_http_upload: Implement quota support (closes #823)
Kim Alvefur <zash@zash.se>
parents:
2677
diff
changeset
|
112 |
2680
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
113 local function handle_request(origin, stanza, xmlns, filename, filesize, mimetype) |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
114 -- local clients only |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
115 if origin.type ~= "c2s" then |
2207
c45ad4b7aaa3
mod_http_upload: Add additional debug logging
Kim Alvefur <zash@zash.se>
parents:
2193
diff
changeset
|
116 module:log("debug", "Request for upload slot from a %s", origin.type); |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
117 origin.send(st.error_reply(stanza, "cancel", "not-authorized")); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
118 return true; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
119 end |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
120 -- validate |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
121 if not filename or filename:find("/") then |
2207
c45ad4b7aaa3
mod_http_upload: Add additional debug logging
Kim Alvefur <zash@zash.se>
parents:
2193
diff
changeset
|
122 module:log("debug", "Filename %q not allowed", filename or ""); |
1850
e3a0ebe671cc
mod_http_upload: Include failure reason in error response
Kim Alvefur <zash@zash.se>
parents:
1849
diff
changeset
|
123 origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid filename")); |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
124 return true; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
125 end |
2677
6daaa1ad2559
mod_http_upload: Add option for expiry of files after a configurable time (closes #557)
Kim Alvefur <zash@zash.se>
parents:
2667
diff
changeset
|
126 expire(origin.username, origin.host); |
1851
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1850
diff
changeset
|
127 if not filesize then |
2207
c45ad4b7aaa3
mod_http_upload: Add additional debug logging
Kim Alvefur <zash@zash.se>
parents:
2193
diff
changeset
|
128 module:log("debug", "Missing file size"); |
1851
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1850
diff
changeset
|
129 origin.send(st.error_reply(stanza, "modify", "bad-request", "Missing or invalid file size")); |
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1850
diff
changeset
|
130 return true; |
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1850
diff
changeset
|
131 elseif filesize > file_size_limit then |
2208
e654d6e1fb50
mod_http_upload: Log if file size exceeds limit
Kim Alvefur <zash@zash.se>
parents:
2207
diff
changeset
|
132 module:log("debug", "File too large (%d > %d)", filesize, file_size_limit); |
2445
e822900c87d4
mod_http_upload: Correctly attach extended error information
Kim Alvefur <zash@zash.se>
parents:
2444
diff
changeset
|
133 origin.send(st.error_reply(stanza, "modify", "not-acceptable", "File too large") |
2641
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
134 :tag("file-too-large", {xmlns=xmlns}) |
2445
e822900c87d4
mod_http_upload: Correctly attach extended error information
Kim Alvefur <zash@zash.se>
parents:
2444
diff
changeset
|
135 :tag("max-file-size"):text(tostring(file_size_limit))); |
1851
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1850
diff
changeset
|
136 return true; |
2678
2dec7cad9218
mod_http_upload: Implement quota support (closes #823)
Kim Alvefur <zash@zash.se>
parents:
2677
diff
changeset
|
137 elseif not check_quota(origin.username, origin.host, filesize) then |
2dec7cad9218
mod_http_upload: Implement quota support (closes #823)
Kim Alvefur <zash@zash.se>
parents:
2677
diff
changeset
|
138 module:log("debug", "Upload of %dB by %s would exceed quota", filesize, origin.full_jid); |
2dec7cad9218
mod_http_upload: Implement quota support (closes #823)
Kim Alvefur <zash@zash.se>
parents:
2677
diff
changeset
|
139 origin.send(st.error_reply(stanza, "wait", "resource-constraint", "Quota reached")); |
2dec7cad9218
mod_http_upload: Implement quota support (closes #823)
Kim Alvefur <zash@zash.se>
parents:
2677
diff
changeset
|
140 return true; |
1851
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1850
diff
changeset
|
141 end |
2680
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
142 |
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
143 if mime_map then |
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
144 local file_ext = filename:match("%.([^.]+)$"); |
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
145 if (not file_ext and mimetype ~= "application/octet-stream") or (file_ext and mime_map[file_ext] ~= mimetype) then |
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
146 origin.send(st.error_reply(stanza, "modify", "bad-request", "MIME type does not match file extension")); |
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
147 return true; |
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
148 end |
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
149 end |
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
150 |
2683
d0948bd96a7b
mod_http_upload: Add support for limiting file types to upload
Kim Alvefur <zash@zash.se>
parents:
2682
diff
changeset
|
151 if allowed_file_types then |
d0948bd96a7b
mod_http_upload: Add support for limiting file types to upload
Kim Alvefur <zash@zash.se>
parents:
2682
diff
changeset
|
152 if not (allowed_file_types:contains(mimetype) or allowed_file_types:contains(mimetype:gsub("/.*", "/*"))) then |
d0948bd96a7b
mod_http_upload: Add support for limiting file types to upload
Kim Alvefur <zash@zash.se>
parents:
2682
diff
changeset
|
153 origin.send(st.error_reply(stanza, "cancel", "not-allowed", "File type not allowed")); |
d0948bd96a7b
mod_http_upload: Add support for limiting file types to upload
Kim Alvefur <zash@zash.se>
parents:
2682
diff
changeset
|
154 return true; |
d0948bd96a7b
mod_http_upload: Add support for limiting file types to upload
Kim Alvefur <zash@zash.se>
parents:
2682
diff
changeset
|
155 end |
d0948bd96a7b
mod_http_upload: Add support for limiting file types to upload
Kim Alvefur <zash@zash.se>
parents:
2682
diff
changeset
|
156 end |
d0948bd96a7b
mod_http_upload: Add support for limiting file types to upload
Kim Alvefur <zash@zash.se>
parents:
2682
diff
changeset
|
157 |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
158 local reply = st.reply(stanza); |
2641
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
159 reply:tag("slot", { xmlns = xmlns }); |
2468
3bff2848af12
mod_http_upload: Create random directory name when assigning slot
Kim Alvefur <zash@zash.se>
parents:
2467
diff
changeset
|
160 |
2649
abea818eed7b
mod_http_upload: Rename variable to avoid name clash
Kim Alvefur <zash@zash.se>
parents:
2648
diff
changeset
|
161 local random_dir; |
abea818eed7b
mod_http_upload: Rename variable to avoid name clash
Kim Alvefur <zash@zash.se>
parents:
2648
diff
changeset
|
162 repeat random_dir = uuid(); |
abea818eed7b
mod_http_upload: Rename variable to avoid name clash
Kim Alvefur <zash@zash.se>
parents:
2648
diff
changeset
|
163 until lfs.mkdir(join_path(storage_path, random_dir)) |
2650
fef067b57305
mod_http_upload: Fix typo in variable name
Kim Alvefur <zash@zash.se>
parents:
2649
diff
changeset
|
164 or not lfs.attributes(join_path(storage_path, random_dir, filename)) |
2468
3bff2848af12
mod_http_upload: Create random directory name when assigning slot
Kim Alvefur <zash@zash.se>
parents:
2467
diff
changeset
|
165 |
2684
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
166 local key = k(origin.username, origin.host); |
2649
abea818eed7b
mod_http_upload: Rename variable to avoid name clash
Kim Alvefur <zash@zash.se>
parents:
2648
diff
changeset
|
167 local slot = random_dir.."/"..filename; |
2684
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
168 local ok = slot_map:set(key, slot, { |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
169 filename = filename, dir = random_dir, size = filesize, time = os.time() |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
170 }); |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
171 if not ok then |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
172 origin.send(st.error_reply(stanza, "wait", "internal-server-failure")); |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
173 return true; |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
174 end |
2489
9d154c929319
mod_http_upload: Log the directory and filename joined
Kim Alvefur <zash@zash.se>
parents:
2479
diff
changeset
|
175 pending_slots[slot] = origin.full_jid; |
2682
3fd50495c89d
mod_http_upload: Clear unused slots after 15 minutes
Kim Alvefur <zash@zash.se>
parents:
2681
diff
changeset
|
176 |
3fd50495c89d
mod_http_upload: Clear unused slots after 15 minutes
Kim Alvefur <zash@zash.se>
parents:
2681
diff
changeset
|
177 module:add_timer(900, function() |
3fd50495c89d
mod_http_upload: Clear unused slots after 15 minutes
Kim Alvefur <zash@zash.se>
parents:
2681
diff
changeset
|
178 pending_slots[slot] = nil; |
2684
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
179 if not lfs.attributes(join_path(storage_path, slot)) then |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
180 slot_map:set(key, slot, nil); |
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
181 end |
2682
3fd50495c89d
mod_http_upload: Clear unused slots after 15 minutes
Kim Alvefur <zash@zash.se>
parents:
2681
diff
changeset
|
182 end); |
3fd50495c89d
mod_http_upload: Clear unused slots after 15 minutes
Kim Alvefur <zash@zash.se>
parents:
2681
diff
changeset
|
183 |
2286
0a3f526779a1
mod_http_upload: Construct the upload slot URL using the LuaSocket URL library (fixes #717)
Kim Alvefur <zash@zash.se>
parents:
2285
diff
changeset
|
184 local base_url = module:http_url(); |
0a3f526779a1
mod_http_upload: Construct the upload slot URL using the LuaSocket URL library (fixes #717)
Kim Alvefur <zash@zash.se>
parents:
2285
diff
changeset
|
185 local slot_url = url.parse(base_url); |
2288
827f01cbf6ba
mod_http_upload: Handle case of non-existant path
Kim Alvefur <zash@zash.se>
parents:
2287
diff
changeset
|
186 slot_url.path = url.parse_path(slot_url.path or "/"); |
2649
abea818eed7b
mod_http_upload: Rename variable to avoid name clash
Kim Alvefur <zash@zash.se>
parents:
2648
diff
changeset
|
187 t_insert(slot_url.path, random_dir); |
2286
0a3f526779a1
mod_http_upload: Construct the upload slot URL using the LuaSocket URL library (fixes #717)
Kim Alvefur <zash@zash.se>
parents:
2285
diff
changeset
|
188 t_insert(slot_url.path, filename); |
0a3f526779a1
mod_http_upload: Construct the upload slot URL using the LuaSocket URL library (fixes #717)
Kim Alvefur <zash@zash.se>
parents:
2285
diff
changeset
|
189 slot_url.path.is_directory = false; |
0a3f526779a1
mod_http_upload: Construct the upload slot URL using the LuaSocket URL library (fixes #717)
Kim Alvefur <zash@zash.se>
parents:
2285
diff
changeset
|
190 slot_url.path = url.build_path(slot_url.path); |
0a3f526779a1
mod_http_upload: Construct the upload slot URL using the LuaSocket URL library (fixes #717)
Kim Alvefur <zash@zash.se>
parents:
2285
diff
changeset
|
191 slot_url = url.build(slot_url); |
0a3f526779a1
mod_http_upload: Construct the upload slot URL using the LuaSocket URL library (fixes #717)
Kim Alvefur <zash@zash.se>
parents:
2285
diff
changeset
|
192 reply:tag("get"):text(slot_url):up(); |
0a3f526779a1
mod_http_upload: Construct the upload slot URL using the LuaSocket URL library (fixes #717)
Kim Alvefur <zash@zash.se>
parents:
2285
diff
changeset
|
193 reply:tag("put"):text(slot_url):up(); |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
194 origin.send(reply); |
2489
9d154c929319
mod_http_upload: Log the directory and filename joined
Kim Alvefur <zash@zash.se>
parents:
2479
diff
changeset
|
195 origin.log("debug", "Given upload slot %q", slot); |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
196 return true; |
2641
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
197 end |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
198 |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
199 -- hooks |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
200 module:hook("iq/host/"..namespace..":request", function (event) |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
201 local stanza, origin = event.stanza, event.origin; |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
202 local request = stanza.tags[1]; |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
203 local filename = request.attr.filename; |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
204 local filesize = tonumber(request.attr.size); |
2680
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
205 local mimetype = request.attr["content-type"]; |
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
206 return handle_request(origin, stanza, namespace, filename, filesize, mimetype); |
2641
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
207 end); |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
208 |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
209 module:hook("iq/host/"..legacy_namespace..":request", function (event) |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
210 local stanza, origin = event.stanza, event.origin; |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
211 local request = stanza.tags[1]; |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
212 local filename = request:get_child_text("filename"); |
2d83e6c8160b
mod_http_upload: add support for XEP-0363 version 0.3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2607
diff
changeset
|
213 local filesize = tonumber(request:get_child_text("size")); |
2680
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
214 local mimetype = request:get_child_text("content-type"); |
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
215 return handle_request(origin, stanza, legacy_namespace, filename, filesize, mimetype); |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
216 end); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
217 |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
218 -- http service |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
219 local function upload_data(event, path) |
2467
290fef768a81
mod_http_upload: Forget upload slot under some error conditions
Kim Alvefur <zash@zash.se>
parents:
2445
diff
changeset
|
220 local uploader = pending_slots[path]; |
290fef768a81
mod_http_upload: Forget upload slot under some error conditions
Kim Alvefur <zash@zash.se>
parents:
2445
diff
changeset
|
221 if not uploader then |
2191
e47046abf568
mod_http_upload: Add more logging
Kim Alvefur <zash@zash.se>
parents:
2066
diff
changeset
|
222 module:log("warn", "Attempt to upload to unknown slot %q", path); |
2193
40824a38d505
mod_http_upload: Return nil if no upload slot is found (should prevent conflicts between multiple instances on the same path)
Kim Alvefur <zash@zash.se>
parents:
2192
diff
changeset
|
223 return; -- 404 |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
224 end |
2649
abea818eed7b
mod_http_upload: Rename variable to avoid name clash
Kim Alvefur <zash@zash.se>
parents:
2648
diff
changeset
|
225 local random_dir, filename = path:match("^([^/]+)/([^/]+)$"); |
abea818eed7b
mod_http_upload: Rename variable to avoid name clash
Kim Alvefur <zash@zash.se>
parents:
2648
diff
changeset
|
226 if not random_dir then |
2207
c45ad4b7aaa3
mod_http_upload: Add additional debug logging
Kim Alvefur <zash@zash.se>
parents:
2193
diff
changeset
|
227 module:log("warn", "Invalid file path %q", path); |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
228 return 400; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
229 end |
1851
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1850
diff
changeset
|
230 if #event.request.body > file_size_limit then |
2192
bb8f7785aed7
mod_http_upload: Demote some errors to warnings
Kim Alvefur <zash@zash.se>
parents:
2191
diff
changeset
|
231 module:log("warn", "Uploaded file too large %d bytes", #event.request.body); |
1851
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1850
diff
changeset
|
232 return 400; |
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1850
diff
changeset
|
233 end |
2467
290fef768a81
mod_http_upload: Forget upload slot under some error conditions
Kim Alvefur <zash@zash.se>
parents:
2445
diff
changeset
|
234 pending_slots[path] = nil; |
2649
abea818eed7b
mod_http_upload: Rename variable to avoid name clash
Kim Alvefur <zash@zash.se>
parents:
2648
diff
changeset
|
235 local full_filename = join_path(storage_path, random_dir, filename); |
2469
43f7637f0143
mod_http_upload: Make sure that target file does not exist prior to upload
Kim Alvefur <zash@zash.se>
parents:
2468
diff
changeset
|
236 if lfs.attributes(full_filename) then |
43f7637f0143
mod_http_upload: Make sure that target file does not exist prior to upload
Kim Alvefur <zash@zash.se>
parents:
2468
diff
changeset
|
237 module:log("warn", "File %s exists already, not replacing it", full_filename); |
43f7637f0143
mod_http_upload: Make sure that target file does not exist prior to upload
Kim Alvefur <zash@zash.se>
parents:
2468
diff
changeset
|
238 return 409; |
43f7637f0143
mod_http_upload: Make sure that target file does not exist prior to upload
Kim Alvefur <zash@zash.se>
parents:
2468
diff
changeset
|
239 end |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
240 local fh, ferr = io.open(full_filename, "w"); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
241 if not fh then |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
242 module:log("error", "Could not open file %s for upload: %s", full_filename, ferr); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
243 return 500; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
244 end |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
245 local ok, err = fh:write(event.request.body); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
246 if not ok then |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
247 module:log("error", "Could not write to file %s for upload: %s", full_filename, err); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
248 os.remove(full_filename); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
249 return 500; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
250 end |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
251 ok, err = fh:close(); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
252 if not ok then |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
253 module:log("error", "Could not write to file %s for upload: %s", full_filename, err); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
254 os.remove(full_filename); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
255 return 500; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
256 end |
2649
abea818eed7b
mod_http_upload: Rename variable to avoid name clash
Kim Alvefur <zash@zash.se>
parents:
2648
diff
changeset
|
257 module:log("info", "File uploaded by %s to slot %s", uploader, random_dir); |
2607
a7ef9b765891
mod_http_upload: Return 201 on successful PUT (as per XEP-0363 and RFC 2616) (Thanks Flow)
Matthew Wild <mwild1@gmail.com>
parents:
2489
diff
changeset
|
258 return 201; |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
259 end |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
260 |
1912
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
261 -- FIXME Duplicated from net.http.server |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
262 |
2684
e491a15d7621
mod_http_upload: Switch to using a map store
Kim Alvefur <zash@zash.se>
parents:
2683
diff
changeset
|
263 -- luacheck: ignore 431/k |
1912
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
264 local codes = require "net.http.codes"; |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
265 local headerfix = setmetatable({}, { |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
266 __index = function(t, k) |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
267 local v = "\r\n"..k:gsub("_", "-"):gsub("%f[%w].", s_upper)..": "; |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
268 t[k] = v; |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
269 return v; |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
270 end |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
271 }); |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
272 |
1912
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
273 local function send_response_sans_body(response, body) |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
274 if response.finished then return; end |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
275 response.finished = true; |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
276 response.conn._http_open_response = nil; |
2065
624e3fed6f92
mod_http_upload: Trim trailing whitespace
Kim Alvefur <zash@zash.se>
parents:
2053
diff
changeset
|
277 |
1912
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
278 local status_line = "HTTP/"..response.request.httpversion.." "..(response.status or codes[response.status_code]); |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
279 local headers = response.headers; |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
280 body = body or response.body or ""; |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
281 headers.content_length = #body; |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
282 |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
283 local output = { status_line }; |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
284 for k,v in pairs(headers) do |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
285 t_insert(output, headerfix[k]..v); |
1905
43fac0c2c772
mod_http_upload: Fix HEAD requests
Kim Alvefur <zash@zash.se>
parents:
1874
diff
changeset
|
286 end |
1912
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
287 t_insert(output, "\r\n\r\n"); |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
288 -- Here we *don't* add the body to the output |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
289 |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
290 response.conn:write(t_concat(output)); |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
291 if response.on_destroy then |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
292 response:on_destroy(); |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
293 response.on_destroy = nil; |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
294 end |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
295 if response.persistent then |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
296 response:finish_cb(); |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
297 else |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
298 response.conn:close(); |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
299 end |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
300 end |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
301 |
2680
96bf67f1f960
mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client
Kim Alvefur <zash@zash.se>
parents:
2678
diff
changeset
|
302 local serve_uploaded_files = http_files.serve(storage_path); |
1912
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
303 |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
304 local function serve_head(event, path) |
1912
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1906
diff
changeset
|
305 event.response.send = send_response_sans_body; |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
306 return serve_uploaded_files(event, path); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
307 end |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
308 |
1942
ff95d983940c
mod_http_upload: Say Hello to anyone opening the "bare" HTTP URL (helpful to show that module is loaded correctly)
Kim Alvefur <zash@zash.se>
parents:
1914
diff
changeset
|
309 local function serve_hello(event) |
ff95d983940c
mod_http_upload: Say Hello to anyone opening the "bare" HTTP URL (helpful to show that module is loaded correctly)
Kim Alvefur <zash@zash.se>
parents:
1914
diff
changeset
|
310 event.response.headers.content_type = "text/html;charset=utf-8" |
ff95d983940c
mod_http_upload: Say Hello to anyone opening the "bare" HTTP URL (helpful to show that module is loaded correctly)
Kim Alvefur <zash@zash.se>
parents:
1914
diff
changeset
|
311 return "<!DOCTYPE html>\n<h1>Hello from mod_"..module.name.."!</h1>\n"; |
ff95d983940c
mod_http_upload: Say Hello to anyone opening the "bare" HTTP URL (helpful to show that module is loaded correctly)
Kim Alvefur <zash@zash.se>
parents:
1914
diff
changeset
|
312 end |
ff95d983940c
mod_http_upload: Say Hello to anyone opening the "bare" HTTP URL (helpful to show that module is loaded correctly)
Kim Alvefur <zash@zash.se>
parents:
1914
diff
changeset
|
313 |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
314 module:provides("http", { |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
315 route = { |
1942
ff95d983940c
mod_http_upload: Say Hello to anyone opening the "bare" HTTP URL (helpful to show that module is loaded correctly)
Kim Alvefur <zash@zash.se>
parents:
1914
diff
changeset
|
316 ["GET"] = serve_hello; |
ff95d983940c
mod_http_upload: Say Hello to anyone opening the "bare" HTTP URL (helpful to show that module is loaded correctly)
Kim Alvefur <zash@zash.se>
parents:
1914
diff
changeset
|
317 ["GET /"] = serve_hello; |
1772
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
318 ["GET /*"] = serve_uploaded_files; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
319 ["HEAD /*"] = serve_head; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
320 ["PUT /*"] = upload_data; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
321 }; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
322 }); |
1849
5244c9b0b297
mod_http_upload: Log a message with the upload URL and storage path for easy discovery
Kim Alvefur <zash@zash.se>
parents:
1848
diff
changeset
|
323 |
5244c9b0b297
mod_http_upload: Log a message with the upload URL and storage path for easy discovery
Kim Alvefur <zash@zash.se>
parents:
1848
diff
changeset
|
324 module:log("info", "URL: <%s>; Storage path: %s", module:http_url(), storage_path); |