Files
resty_functions/file_upload/upload_image.lua
T

235 lines
6.9 KiB
Lua
Raw Normal View History

2021-07-20 21:44:28 +08:00
local upload = require "upload"
local uuid = require "uuid"
local redis = require "redis"
local cjson = require "cjson"
local chunk_size = 5 -- should be set to 4096 or 8192
-- for real-world settings
local form, err = upload:new(chunk_size)
local output_image_filename_uuid = uuid.generate();
-- set default task status
data_table = {}
data_table["status"] = "InProgress"
data_table["data"] = "null"
response_table = {}
response_table['r'] = "true"
response_table['d'] = data_table
response_table['e'] = "null"
local responseData = cjson.encode(response_table)
ngx.say(responseData)
local red = redis:new()
red:set_timeouts(1000, 1000, 1000)
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ok, err = red:set(output_image_filename_uuid, responseData)
if not ok then
ngx.say("failed to set uuid: ", err)
return
end
ngx.say("set result: ", ok)
local res, err = red:get(output_image_filename_uuid)
if not res then
ngx.say("failed to get uuid: ", err)
return
end
if res == ngx.null then
ngx.say("uuid not found.")
return
end
ngx.say("get uuid: " .. output_image_filename_uuid .. " | value :" .. res)
if not form then
ngx.log(ngx.ERR, "failed to new upload: ", err)
ngx.say("failed to new upload: ", err)
ngx.exit(500)
end
form:set_timeout(1000) -- 1 sec
-- String split
string.split = function(s, p)
local rt= {}
string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end )
return rt
end
-- Get file trim
string.trim = function(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
-- Upload file save path config in nginx.conf
local saveRootPath = ngx.var.store_dir
local fileToSave
local ret_save = false
local upload_image_filename
local save_image_filename
local upload_image_table = {}
local upload_image_index = 1
while true do
local typ, res, err = form:read()
if not typ then
ngx.say("failed to read: ", err)
return
end
if typ == "header" then
-- 开始读取 http header
-- 解析出本次上传的文件名
local key = res[1]
local value = res[2]
if key == "Content-Disposition" then
-- 解析出本次上传的文件名
-- form-data; name="testFileName"; filename="testfile.txt"
local kvlist = string.split(value, ';')
for _, kv in ipairs(kvlist) do
local seg = string.trim(kv)
if seg:find("filename") then
local kvfile = string.split(seg, "=")
upload_image_filename = string.sub(kvfile[2], 2, -2)
ngx.say(" -->> POST : Upload origin image is ", upload_image_filename)
ngx.say("\n")
if upload_image_filename then
-- Save file name with generate uuid
save_image_filename = uuid:generate()
save_image_filename = save_image_filename .. '.' .. upload_image_filename:match(".+%.(%w+)$")
fileToSave = io.open(saveRootPath .. save_image_filename, "w+")
if not fileToSave then
ngx.say(" Error: Failed to open file ", save_image_filename)
return
else
ngx.say("Open file ok ", save_image_filename)
ngx.say("\n")
upload_image_table[upload_image_index] = saveRootPath .. save_image_filename .. " "
ngx.say("Insert upload image table "..upload_image_index.." with "..upload_image_table[upload_image_index])
ngx.say("\n")
upload_image_index = upload_image_index + 1
end
break
end
end
end
end
elseif typ == "body" then
-- 开始读取 http body
if fileToSave then
fileToSave:write(res)
end
elseif typ == "part_end" then
-- 文件写结束,关闭文件
if fileToSave then
fileToSave:close()
fileToSave = nil
end
ret_save = true
elseif typ == "eof" then
-- 文件读取结束
break
else
ngx.log(ngx.INFO, "do other things")
end
end
if ret_save then
ngx.say("Show all upload files\n")
-- Show all upload files
upload_image_index = upload_image_index -1
for i = 1, upload_image_index do
ngx.say("Save upload file is : " .. upload_image_table[i])
ngx.say("\n")
end
image_append_coroutine = coroutine.create(
function ()
-- Append images
-- ngx.say("Upload image number is : " , upload_image_index )
local append_images_path
append_images_path = table.concat(upload_image_table)
ngx.say("Input images list : " , append_images_path)
ngx.say("\n")
-- local append_output_image = saveRootPath .. uuid.generate()..".jpg ";
local append_output_image = saveRootPath .. output_image_filename_uuid..".jpg ";
ngx.say("Output image is : "..append_output_image)
ngx.say("\n")
-- Debug
ngx.say('convert -append '..append_images_path..' '..append_output_image)
ngx.say("\n")
local call_imagemagick_cmd = io.popen('convert -append '..append_images_path..' '..append_output_image)
local imagemagick_cmd_replay = call_imagemagick_cmd:read("*all")
ngx.say(imagemagick_cmd_replay)
-- set default task status
data_table = {}
data_table["status"] = "Done"
data_table["data"] = output_image_filename_uuid
response_table = {}
response_table['r'] = "true"
response_table['d'] = data_table
response_table['e'] = "null"
local responseData = cjson.encode(response_table)
ngx.say(responseData)
local red = redis:new()
red:set_timeouts(1000, 1000, 1000)
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ok, err = red:set(output_image_filename_uuid, responseData)
if not ok then
ngx.say("failed to set uuid: ", err)
return
end
ngx.say("set result: ", ok)
local res, err = red:get(output_image_filename_uuid)
if not res then
ngx.say("failed to get uuid: ", err)
return
end
if res == ngx.null then
ngx.say("uuid not found.")
return
end
ngx.say("uuid: ", res)
end
)
coroutine.resume(image_append_coroutine)
end