exchange openresty upload image module
This commit is contained in:
@@ -2,14 +2,14 @@
|
||||
|
||||
- 配置openresty
|
||||
|
||||
```nginx
|
||||
```nginx configuration
|
||||
# 配置文件路径
|
||||
# /usr/local/openresty/nginx/conf/nginx.conf
|
||||
# http contex 中添加lua脚本的路径
|
||||
lua_package_path "/usr/local/openresty/resty_funcs/?.lua;;";
|
||||
```
|
||||
|
||||
```nginx
|
||||
```nginx configuration
|
||||
# 子域名配置文件路径
|
||||
# /usr/local/openresty/nginx/conf.d/music-room.conf
|
||||
|
||||
|
||||
+158
-79
@@ -1,79 +1,110 @@
|
||||
-- Require lua modules
|
||||
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();
|
||||
|
||||
|
||||
if not form then
|
||||
ngx.log(ngx.ERR, "failed to new upload: ", err)
|
||||
ngx.exit(500)
|
||||
end
|
||||
|
||||
form:set_timeout(1000) -- 1 sec
|
||||
|
||||
-- String split
|
||||
-- Functions : 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
|
||||
-- Functions : 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
|
||||
-- Init
|
||||
---- Upload init
|
||||
local chunk_size = 5 -- should be set to 4096 or 8192
|
||||
-- for real-world settings
|
||||
|
||||
local fileToSave
|
||||
local form, error = upload:new(chunk_size)
|
||||
|
||||
if not form then
|
||||
ngx.log(ngx.ERR, "Fail to create new form: ", error)
|
||||
ngx.exit(500)
|
||||
end
|
||||
|
||||
---- Redis init
|
||||
------ Connect to redis
|
||||
local redis_task_database = redis:new()
|
||||
|
||||
redis_task_database:set_timeouts(1000, 1000, 1000)
|
||||
|
||||
local ok, error = redis_task_database:connect("127.0.0.1", 6379)
|
||||
if not ok then
|
||||
ngx.log(ngx.ERR, "Fail to connect redis: ", error)
|
||||
ngx.exit(500)
|
||||
end
|
||||
---------------------------------------------------------------------------------------
|
||||
|
||||
-- Save upload images
|
||||
---- Upload file save path config in nginx.conf
|
||||
local save_upload_file_path = ngx.var.store_dir
|
||||
local file_to_save
|
||||
local ret_save = false
|
||||
local upload_image_filename
|
||||
local save_image_filename
|
||||
|
||||
local upload_image_table = {}
|
||||
local data_table = {}
|
||||
local upload_image_index = 1
|
||||
|
||||
form:set_timeout(1000) -- 1 sec
|
||||
|
||||
---- Read image file from http packet and save it
|
||||
while true do
|
||||
local typ, res, err = form:read()
|
||||
if not typ then
|
||||
ngx.log(ngx.ERR, "failed to read: ", err)
|
||||
return
|
||||
|
||||
local http_type, result, error = form:read()
|
||||
|
||||
if not http_type then
|
||||
ngx.log(ngx.ERR, "Failed to read form: ", error)
|
||||
ngx.exit(500)
|
||||
end
|
||||
if typ == "header" then
|
||||
-- 开始读取 http header
|
||||
-- 解析出本次上传的文件名
|
||||
local key = res[1]
|
||||
local value = res[2]
|
||||
|
||||
if http_type == "header" then
|
||||
-- Start to read http header
|
||||
|
||||
local key = result[1]
|
||||
local value = result[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.log(ngx.INFO,"Upload origin image is ", upload_image_filename)
|
||||
-- Analyze this time upload image filename , use ; as interval
|
||||
-- Like: form-data; name="testFileName"; filename="testfile.txt"
|
||||
local key_value_list = string.split(value, ';')
|
||||
|
||||
for _, key_value in ipairs(key_value_list) do
|
||||
|
||||
local segment = string.trim(key_value)
|
||||
|
||||
if segment:find("filename") then
|
||||
|
||||
local key_value_file = string.split(segment, "=")
|
||||
upload_image_filename = string.sub(key_value_file[2], 2, -2)
|
||||
|
||||
ngx.log(ngx.INFO, "Upload origin filename: ", upload_image_filename)
|
||||
|
||||
-- Save upload file
|
||||
if upload_image_filename then
|
||||
-- Save file name with generate uuid
|
||||
save_image_filename = uuid:generate()
|
||||
save_image_filename = uuid:generate() -- Generate save filename uuid
|
||||
save_image_filename = save_image_filename .. '.' .. upload_image_filename:match(".+%.(%w+)$")
|
||||
fileToSave = io.open(saveRootPath .. save_image_filename, "w+")
|
||||
if not fileToSave then
|
||||
ngx.log(ngx.ERR, " Error: Failed to open file ", save_image_filename)
|
||||
return
|
||||
else
|
||||
ngx.log(ngx.INFO, "Open file ok ", save_image_filename)
|
||||
file_to_save = io.open(save_upload_file_path .. save_image_filename, "w+")
|
||||
|
||||
upload_image_table[upload_image_index] = saveRootPath .. save_image_filename .. " "
|
||||
if not file_to_save then
|
||||
ngx.log(ngx.ERR , "Fail open file: ", save_image_filename)
|
||||
ngx.exit(500)
|
||||
else
|
||||
ngx.log(ngx.INFO, "Success open file: ", save_image_filename)
|
||||
|
||||
-- Save all upload files as a table
|
||||
data_table[upload_image_index] = save_image_filename
|
||||
upload_image_table[upload_image_index] = save_upload_file_path .. save_image_filename .. " "
|
||||
ngx.log(ngx.INFO, "Insert upload image table "..upload_image_index.." with "..upload_image_table[upload_image_index])
|
||||
|
||||
upload_image_index = upload_image_index + 1
|
||||
@@ -83,58 +114,106 @@ while true do
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif typ == "body" then
|
||||
-- 开始读取 http body
|
||||
if fileToSave then
|
||||
fileToSave:write(res)
|
||||
|
||||
elseif http_type == "body" then
|
||||
|
||||
-- Start to read http body
|
||||
if file_to_save then
|
||||
file_to_save:write(result)
|
||||
end
|
||||
elseif typ == "part_end" then
|
||||
-- 文件写结束,关闭文件
|
||||
if fileToSave then
|
||||
fileToSave:close()
|
||||
fileToSave = nil
|
||||
|
||||
elseif http_type == "part_end" then
|
||||
|
||||
-- Write to save file finish
|
||||
if file_to_save then
|
||||
file_to_save:close()
|
||||
file_to_save = nil
|
||||
end
|
||||
|
||||
ret_save = true
|
||||
elseif typ == "eof" then
|
||||
-- 文件读取结束
|
||||
|
||||
elseif http_type == "eof" then
|
||||
-- Read file end
|
||||
break
|
||||
else
|
||||
ngx.log(ngx.INFO, "do other things")
|
||||
ngx.log(ngx.INFO, "Maybe do other things")
|
||||
end
|
||||
end
|
||||
if ret_save then
|
||||
ngx.log(ngx.INFO, "Show all upload files\n")
|
||||
---------------------------------------------------------------------------------------
|
||||
|
||||
-- Show all upload files
|
||||
-- Show all input and may output files
|
||||
if ret_save then
|
||||
ngx.log(ngx.INFO, "Show all upload save files\n")
|
||||
|
||||
---- Show all upload save files
|
||||
upload_image_index = upload_image_index -1
|
||||
for i = 1, upload_image_index do
|
||||
ngx.log(ngx.INFO, "Save upload file is : " .. upload_image_table[i])
|
||||
end
|
||||
---------------------------------------------------------------------------------------
|
||||
|
||||
image_append_coroutine = coroutine.create(
|
||||
function ()
|
||||
-- Append images
|
||||
-- ngx.log(ngx.INFO,"Upload image number is : " , upload_image_index )
|
||||
local append_images_path
|
||||
append_images_path = table.concat(upload_image_table)
|
||||
ngx.log(ngx.INFO, "Input images list : " , append_images_path)
|
||||
-- Communicate with front end
|
||||
---- Generate task uuid
|
||||
local task_uuid = uuid.generate();
|
||||
---------------------------------------------------------------------------------------
|
||||
|
||||
-- local append_output_image = saveRootPath .. uuid.generate()..".jpg ";
|
||||
local append_output_image = saveRootPath .. output_image_filename_uuid..".jpg ";
|
||||
ngx.log(ngx.INFO, "Output image is : "..append_output_image)
|
||||
-- Construct {key: task_id | value: [images] } in json
|
||||
-- Example:
|
||||
-- {"task_id":"488a8e6c556a-4271-adec--071e843c9856","data:"[\"2109aac0-556a-4271-adec-9eac494f622f.jpg\",\"488a8e6c-01e6-4cb3-af88-a1d90e04e6b8.jpg\",\"c3f76317-592f-4117-ab0d-071e843c9856.jpg\"]"}
|
||||
local task_table = {}
|
||||
task_table["task_id"] = task_uuid
|
||||
task_table["data"] = data_table
|
||||
|
||||
-- Debug
|
||||
ngx.log(ngx.INFO, '/usr/local/ImageMagick/bin/magick convert -append '..append_images_path..' '..append_output_image)
|
||||
local task_jason = cjson.encode(task_table)
|
||||
ngx.log(ngx.INFO , task_jason) -- Response to front end
|
||||
---------------------------------------------------------------------------------------
|
||||
|
||||
local call_imagemagick_cmd = io.popen('/usr/local/ImageMagick/bin/magick convert -append '..append_images_path..' '..append_output_image)
|
||||
local imagemagick_cmd_replay = call_imagemagick_cmd:read("*all")
|
||||
ngx.log(ngx.INFO, imagemagick_cmd_replay)
|
||||
-- Redis control
|
||||
---- Set json to redis
|
||||
ok, error = redis_task_database:set(task_uuid, task_jason)
|
||||
if not ok then
|
||||
ngx.log(ngx.ERR , "Failed to set task json: ", error)
|
||||
ngx.exit(500)
|
||||
end
|
||||
ngx.log(ngx.INFO , "Set redis task json result: ", ok)
|
||||
|
||||
---- Get data from redis
|
||||
local result, error = redis_task_database:get(task_uuid)
|
||||
if not result then
|
||||
ngx.log(ngx.ERR , "Failed to get task json: ", error)
|
||||
ngx.exit(500)
|
||||
end
|
||||
|
||||
end
|
||||
if result == ngx.null then
|
||||
ngx.log(ngx.ERR , "Not found task id")
|
||||
ngx.exit(500)
|
||||
end
|
||||
|
||||
ngx.log(ngx.INFO, "Get redis task id: " .. task_uuid .. " | value :" .. result)
|
||||
---------------------------------------------------------------------------------------
|
||||
|
||||
-- Create task
|
||||
local result = ngx.location.capture(
|
||||
'/mock_task_server',
|
||||
{
|
||||
method = ngx.HTTP_POST,
|
||||
body = ngx.encode_args({task = task_jason})
|
||||
}
|
||||
)
|
||||
ngx.say(result.body)
|
||||
|
||||
-- Response task ID to front end
|
||||
ngx.say(task_uuid)
|
||||
|
||||
-- Mock a image append request from task from task server
|
||||
local result = ngx.location.capture(
|
||||
'/image_append',
|
||||
{
|
||||
method = ngx.HTTP_POST,
|
||||
body = ngx.encode_args({task = task_jason})
|
||||
}
|
||||
)
|
||||
ngx.say(result.body)
|
||||
|
||||
coroutine.resume(image_append_coroutine)
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user