author | Kim Alvefur <zash@zash.se> |
Sat, 20 Aug 2016 21:59:39 +0200 | |
changeset 2289 | f1923bf329a3 |
parent 2235 | 131075a3bf0d |
child 2290 | 0a3f526779a1 |
permissions | -rw-r--r-- |
1776
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 |
-- |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
3 |
-- Copyright (C) 2015 Kim Alvefur |
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. |
2069
624e3fed6f92
mod_http_upload: Trim trailing whitespace
Kim Alvefur <zash@zash.se>
parents:
2057
diff
changeset
|
6 |
-- |
1776
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"; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
13 |
local uuid = require"util.uuid".generate; |
1970
3b748666ff97
mod_http_upload: URL-encode filename in case it contains characters that need escaping (thanks Thilo)
Kim Alvefur <zash@zash.se>
parents:
1946
diff
changeset
|
14 |
local urlencode = require"util.http".urlencode; |
2070
cb74e4ab13f0
mod_http_upload: Advertise maximum file size in disco#info (Per XEP-0363 v0.2)
Kim Alvefur <zash@zash.se>
parents:
2069
diff
changeset
|
15 |
local dataform = require "util.dataforms".new; |
1916
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1910
diff
changeset
|
16 |
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:
1910
diff
changeset
|
17 |
local t_insert = table.insert; |
1918
b01d60dfa405
mod_http_upload: Add missing local of string.upper (Thanks Thilo)
Kim Alvefur <zash@zash.se>
parents:
1916
diff
changeset
|
18 |
local s_upper = string.upper; |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
19 |
|
1819
abacf6698d97
mod_http_upload: Include join_path function, should make it work with 0.9.x
Kim Alvefur <zash@zash.se>
parents:
1809
diff
changeset
|
20 |
local function join_path(a, b) |
1821
1971ff719e72
mod_http_upload: Fix typo (thanks mo)
Kim Alvefur <zash@zash.se>
parents:
1819
diff
changeset
|
21 |
return a .. package.config:sub(1,1) .. b; |
1819
abacf6698d97
mod_http_upload: Include join_path function, should make it work with 0.9.x
Kim Alvefur <zash@zash.se>
parents:
1809
diff
changeset
|
22 |
end |
abacf6698d97
mod_http_upload: Include join_path function, should make it work with 0.9.x
Kim Alvefur <zash@zash.se>
parents:
1809
diff
changeset
|
23 |
|
1855
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1854
diff
changeset
|
24 |
-- config |
2057
40056a27f394
mod_http_upload: Lower default size limit to 1MB
Kim Alvefur <zash@zash.se>
parents:
1971
diff
changeset
|
25 |
local file_size_limit = module:get_option_number(module.name .. "_file_size_limit", 1024 * 1024); -- 1 MB |
1855
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1854
diff
changeset
|
26 |
|
2289
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:
2235
diff
changeset
|
27 |
--- 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:
2235
diff
changeset
|
28 |
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:
2235
diff
changeset
|
29 |
if file_size_limit > parser_body_limit then |
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:
2235
diff
changeset
|
30 |
module:log("warn", "%s_file_size_limit exceeds HTTP parser limit on body size, capping file size to %d B", module.name, 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:
2235
diff
changeset
|
31 |
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:
2235
diff
changeset
|
32 |
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:
2235
diff
changeset
|
33 |
|
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
34 |
-- depends |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
35 |
module:depends("http"); |
1809
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:
1776
diff
changeset
|
36 |
module:depends("disco"); |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
37 |
|
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
38 |
-- namespace |
1878
8ef500508c59
mod_http_upload.lua: use official namespace from XEP-0363
Michael Töglhofer <michael@toeglhofer.net>
parents:
1855
diff
changeset
|
39 |
local xmlns_http_upload = "urn:xmpp:http:upload"; |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
40 |
|
2235
131075a3bf0d
mod_http_upload: Add disco identity
Matthew Wild <mwild1@gmail.com>
parents:
2212
diff
changeset
|
41 |
module:add_identity("store", "file", module:get_option_string("name", "HTTP File Upload")) |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
42 |
module:add_feature(xmlns_http_upload); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
43 |
|
2070
cb74e4ab13f0
mod_http_upload: Advertise maximum file size in disco#info (Per XEP-0363 v0.2)
Kim Alvefur <zash@zash.se>
parents:
2069
diff
changeset
|
44 |
module:add_extension(dataform { |
cb74e4ab13f0
mod_http_upload: Advertise maximum file size in disco#info (Per XEP-0363 v0.2)
Kim Alvefur <zash@zash.se>
parents:
2069
diff
changeset
|
45 |
{ name = "FORM_TYPE", type = "hidden", value = xmlns_http_upload }, |
cb74e4ab13f0
mod_http_upload: Advertise maximum file size in disco#info (Per XEP-0363 v0.2)
Kim Alvefur <zash@zash.se>
parents:
2069
diff
changeset
|
46 |
{ 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:
2069
diff
changeset
|
47 |
}: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:
2069
diff
changeset
|
48 |
|
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
49 |
-- state |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
50 |
local pending_slots = module:shared("upload_slots"); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
51 |
|
1971
2ce2b194d501
mod_http_upload: Make file system path configurable
Kim Alvefur <zash@zash.se>
parents:
1970
diff
changeset
|
52 |
local storage_path = module:get_option_string(module.name .. "_path", join_path(prosody.paths.data, module.name)); |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
53 |
lfs.mkdir(storage_path); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
54 |
|
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
55 |
-- hooks |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
56 |
module:hook("iq/host/"..xmlns_http_upload..":request", function (event) |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
57 |
local stanza, origin = event.stanza, event.origin; |
1852
e5243fa16210
mod_http_upload: Cache first-level child <request> in local variable
Kim Alvefur <zash@zash.se>
parents:
1821
diff
changeset
|
58 |
local request = stanza.tags[1]; |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
59 |
-- local clients only |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
60 |
if origin.type ~= "c2s" then |
2211
c45ad4b7aaa3
mod_http_upload: Add additional debug logging
Kim Alvefur <zash@zash.se>
parents:
2197
diff
changeset
|
61 |
module:log("debug", "Request for upload slot from a %s", origin.type); |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
62 |
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
|
63 |
return true; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
64 |
end |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
65 |
-- validate |
1852
e5243fa16210
mod_http_upload: Cache first-level child <request> in local variable
Kim Alvefur <zash@zash.se>
parents:
1821
diff
changeset
|
66 |
local filename = request:get_child_text("filename"); |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
67 |
if not filename or filename:find("/") then |
2211
c45ad4b7aaa3
mod_http_upload: Add additional debug logging
Kim Alvefur <zash@zash.se>
parents:
2197
diff
changeset
|
68 |
module:log("debug", "Filename %q not allowed", filename or ""); |
1854
e3a0ebe671cc
mod_http_upload: Include failure reason in error response
Kim Alvefur <zash@zash.se>
parents:
1853
diff
changeset
|
69 |
origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid filename")); |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
70 |
return true; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
71 |
end |
1855
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1854
diff
changeset
|
72 |
local filesize = tonumber(request:get_child_text("size")); |
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1854
diff
changeset
|
73 |
if not filesize then |
2211
c45ad4b7aaa3
mod_http_upload: Add additional debug logging
Kim Alvefur <zash@zash.se>
parents:
2197
diff
changeset
|
74 |
module:log("debug", "Missing file size"); |
1855
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1854
diff
changeset
|
75 |
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:
1854
diff
changeset
|
76 |
return true; |
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1854
diff
changeset
|
77 |
elseif filesize > file_size_limit then |
2212
e654d6e1fb50
mod_http_upload: Log if file size exceeds limit
Kim Alvefur <zash@zash.se>
parents:
2211
diff
changeset
|
78 |
module:log("debug", "File too large (%d > %d)", filesize, file_size_limit); |
1855
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1854
diff
changeset
|
79 |
origin.send(st.error_reply(stanza, "modify", "not-acceptable", "File too large", |
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1854
diff
changeset
|
80 |
st.stanza("file-too-large", {xmlns=xmlns_http_upload}) |
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1854
diff
changeset
|
81 |
:tag("max-size"):text(tostring(file_size_limit)))); |
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1854
diff
changeset
|
82 |
return true; |
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1854
diff
changeset
|
83 |
end |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
84 |
local reply = st.reply(stanza); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
85 |
reply:tag("slot", { xmlns = xmlns_http_upload }); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
86 |
local random = uuid(); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
87 |
pending_slots[random.."/"..filename] = origin.full_jid; |
1970
3b748666ff97
mod_http_upload: URL-encode filename in case it contains characters that need escaping (thanks Thilo)
Kim Alvefur <zash@zash.se>
parents:
1946
diff
changeset
|
88 |
local url = module:http_url() .. "/" .. random .. "/" .. urlencode(filename); |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
89 |
reply:tag("get"):text(url):up(); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
90 |
reply:tag("put"):text(url):up(); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
91 |
origin.send(reply); |
2211
c45ad4b7aaa3
mod_http_upload: Add additional debug logging
Kim Alvefur <zash@zash.se>
parents:
2197
diff
changeset
|
92 |
origin.log("debug", "Given upload slot %q", random); |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
93 |
return true; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
94 |
end); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
95 |
|
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
96 |
-- http service |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
97 |
local function upload_data(event, path) |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
98 |
if not pending_slots[path] then |
2195
e47046abf568
mod_http_upload: Add more logging
Kim Alvefur <zash@zash.se>
parents:
2070
diff
changeset
|
99 |
module:log("warn", "Attempt to upload to unknown slot %q", path); |
2197
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:
2196
diff
changeset
|
100 |
return; -- 404 |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
101 |
end |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
102 |
local random, filename = path:match("^([^/]+)/([^/]+)$"); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
103 |
if not random then |
2211
c45ad4b7aaa3
mod_http_upload: Add additional debug logging
Kim Alvefur <zash@zash.se>
parents:
2197
diff
changeset
|
104 |
module:log("warn", "Invalid file path %q", path); |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
105 |
return 400; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
106 |
end |
1855
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1854
diff
changeset
|
107 |
if #event.request.body > file_size_limit then |
2196
bb8f7785aed7
mod_http_upload: Demote some errors to warnings
Kim Alvefur <zash@zash.se>
parents:
2195
diff
changeset
|
108 |
module:log("warn", "Uploaded file too large %d bytes", #event.request.body); |
1855
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1854
diff
changeset
|
109 |
return 400; |
03c5639882a7
mod_http_upload: Add support for a file size limit
Kim Alvefur <zash@zash.se>
parents:
1854
diff
changeset
|
110 |
end |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
111 |
local dirname = join_path(storage_path, random); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
112 |
if not lfs.mkdir(dirname) then |
2196
bb8f7785aed7
mod_http_upload: Demote some errors to warnings
Kim Alvefur <zash@zash.se>
parents:
2195
diff
changeset
|
113 |
module:log("warn", "Could not create directory %s for upload", dirname); |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
114 |
return 500; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
115 |
end |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
116 |
local full_filename = join_path(dirname, filename); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
117 |
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
|
118 |
if not fh then |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
119 |
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
|
120 |
return 500; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
121 |
end |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
122 |
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
|
123 |
if not ok then |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
124 |
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
|
125 |
os.remove(full_filename); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
126 |
return 500; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
127 |
end |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
128 |
ok, err = fh:close(); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
129 |
if not ok then |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
130 |
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
|
131 |
os.remove(full_filename); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
132 |
return 500; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
133 |
end |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
134 |
module:log("info", "File uploaded by %s to slot %s", pending_slots[path], random); |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
135 |
pending_slots[path] = nil; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
136 |
return 200; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
137 |
end |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
138 |
|
1916
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1910
diff
changeset
|
139 |
-- 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:
1910
diff
changeset
|
140 |
|
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1910
diff
changeset
|
141 |
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:
1910
diff
changeset
|
142 |
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:
1910
diff
changeset
|
143 |
__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:
1910
diff
changeset
|
144 |
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:
1910
diff
changeset
|
145 |
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:
1910
diff
changeset
|
146 |
return v; |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1910
diff
changeset
|
147 |
end |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1910
diff
changeset
|
148 |
}); |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
149 |
|
1916
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1910
diff
changeset
|
150 |
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:
1910
diff
changeset
|
151 |
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:
1910
diff
changeset
|
152 |
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:
1910
diff
changeset
|
153 |
response.conn._http_open_response = nil; |
2069
624e3fed6f92
mod_http_upload: Trim trailing whitespace
Kim Alvefur <zash@zash.se>
parents:
2057
diff
changeset
|
154 |
|
1916
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1910
diff
changeset
|
155 |
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:
1910
diff
changeset
|
156 |
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:
1910
diff
changeset
|
157 |
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:
1910
diff
changeset
|
158 |
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:
1910
diff
changeset
|
159 |
|
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1910
diff
changeset
|
160 |
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:
1910
diff
changeset
|
161 |
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:
1910
diff
changeset
|
162 |
t_insert(output, headerfix[k]..v); |
1909
43fac0c2c772
mod_http_upload: Fix HEAD requests
Kim Alvefur <zash@zash.se>
parents:
1878
diff
changeset
|
163 |
end |
1916
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1910
diff
changeset
|
164 |
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:
1910
diff
changeset
|
165 |
-- 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:
1910
diff
changeset
|
166 |
|
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1910
diff
changeset
|
167 |
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:
1910
diff
changeset
|
168 |
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:
1910
diff
changeset
|
169 |
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:
1910
diff
changeset
|
170 |
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:
1910
diff
changeset
|
171 |
end |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1910
diff
changeset
|
172 |
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:
1910
diff
changeset
|
173 |
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:
1910
diff
changeset
|
174 |
else |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1910
diff
changeset
|
175 |
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:
1910
diff
changeset
|
176 |
end |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
177 |
end |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
178 |
|
1916
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1910
diff
changeset
|
179 |
local serve_uploaded_files = module:depends("http_files").serve(storage_path); |
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1910
diff
changeset
|
180 |
|
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
181 |
local function serve_head(event, path) |
1916
24c22cbb86e4
mod_http_upload: Duplicate code from net.http.server in order send proper HEAD responses
Kim Alvefur <zash@zash.se>
parents:
1910
diff
changeset
|
182 |
event.response.send = send_response_sans_body; |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
183 |
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
|
184 |
end |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
185 |
|
1946
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:
1918
diff
changeset
|
186 |
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:
1918
diff
changeset
|
187 |
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:
1918
diff
changeset
|
188 |
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:
1918
diff
changeset
|
189 |
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:
1918
diff
changeset
|
190 |
|
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
191 |
module:provides("http", { |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
192 |
route = { |
1946
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:
1918
diff
changeset
|
193 |
["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:
1918
diff
changeset
|
194 |
["GET /"] = serve_hello; |
1776
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
195 |
["GET /*"] = serve_uploaded_files; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
196 |
["HEAD /*"] = serve_head; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
197 |
["PUT /*"] = upload_data; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
198 |
}; |
45f7e3c2557f
mod_http_upload: Implementation of Conversations HTTP upload file transfer mode
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
199 |
}); |
1853
5244c9b0b297
mod_http_upload: Log a message with the upload URL and storage path for easy discovery
Kim Alvefur <zash@zash.se>
parents:
1852
diff
changeset
|
200 |
|
5244c9b0b297
mod_http_upload: Log a message with the upload URL and storage path for easy discovery
Kim Alvefur <zash@zash.se>
parents:
1852
diff
changeset
|
201 |
module:log("info", "URL: <%s>; Storage path: %s", module:http_url(), storage_path); |