-
Notifications
You must be signed in to change notification settings - Fork 3
/
upload.lua
138 lines (113 loc) · 3.15 KB
/
upload.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
local upload = require("resty.upload")
local uuid = require("app.libs.uuid.uuid")
local sfind = string.find
local match = string.match
local ngx_var = ngx.var
local function getextension(filename)
return filename:match(".+%.(%w+)$")
end
local function _multipart_formdata(config)
local form, err = upload:new(config.chunk_size)
if not form then
ngx.log(ngx.ERR, "failed to new upload: ", err)
ngx.exit(500)
end
form:set_timeout(config.recieve_timeout)
local unique_name = uuid()
local success, msg = false, ""
local file, origin_filename, filename, path, extname, err
while true do
local typ, res, err = form:read()
if not typ then
success = false
msg = "failed to read"
ngx.log(ngx.ERR, "failed to read: ", err)
return success, msg
end
if typ == "header" then
if res[1] == "Content-Disposition" then
key = match(res[2], "name=\"(.-)\"")
origin_filename = match(res[2], "filename=\"(.-)\"")
elseif res[1] == "Content-Type" then
filetype = res[2]
end
if origin_filename and filetype then
if not extname then
extname = getextension(origin_filename)
end
if extname ~= "png" and extname ~= "jpg" and extname ~= "jpeg" and extname ~= "bmp" and extname ~= "gif" then
success = false
msg = "not allowed upload file type"
ngx.log(ngx.ERR, "not allowed upload file type:", origin_filename)
return success, msg
end
filename = unique_name .. "." .. extname
path = config.dir.. "/" .. filename
file, err = io.open(path, "w+")
if err then
success = false
msg = "open file error"
ngx.log(ngx.ERR, "open file error:", err)
return success, msg
end
end
elseif typ == "body" then
if file then
file:write(res)
success = true
else
success = false
msg = "upload file error"
ngx.log(ngx.ERR, "upload file error, path:", path)
return success, msg
end
elseif typ == "part_end" then
file:close()
file = nil
elseif typ == "eof" then
break
else
-- do nothing
end
end
return success, msg, origin_filename, extname, path, filename
end
-- to optimize
local function uploader(config)
return function(req, res, next)
if ngx_var.request_method == "POST" then
local get_headers = ngx.req.get_headers()
local header = get_headers['Content-Type']
if header then
local is_multipart = sfind(header, "multipart")
if is_multipart and is_multipart>0 then
config = config or {}
config.dir = config.dir or "/tmp"
config.chunk_size = config.chunk_size or 4096
config.recieve_timeout = config.recieve_timeout or 20000 -- 20s
local success, msg, origin_filename, extname, path, filename = _multipart_formdata(config)
if success then
req.file = req.file or {}
req.file.success = true
req.file.origin_filename = origin_filename
req.file.extname = extname
req.file.path = path
req.file.filename = filename
else
req.file = req.file or {}
req.file.success = false
req.file.msg = msg
end
next()
else
next()
end
else
next()
end
else
next()
end
end
end
return uploader