OpenResty保存上传文件并返回uuid
今天前端给我提了个测试环境用的语音静态服务器的需求:
- mp3 文件的上传和下载
- 上传成功后返回唯一的文件标识符 (文件 id )
上传和下载用 Nginx 都比较简单,问题是返回唯一的文件 id 这里。看来要想快速搞定,只能用上 OpenResty 了。
文件的上传有个 resty.upload 模块,网上也有大量的代码示例,我直接参考了这篇博客。
uuid 的实现,使用了 resty.jit-uuid,这个模块并没有集成到 OpenResty 中,可以直接从 github 上下载 jit-uuid.lua 文件,放到 OpenResty 的安装目录下的 lualib/resty 目录里。
具体的业务脚本如下:
-- myupload.lua
local uuid = require "resty.jit-uuid"
local upload = require "resty.upload"
local chunk_size = 4096
local form, err = upload:new(chunk_size)
if not form then
ngx.log(ngx.ERR, "failed to new upload: ", err)
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
form:set_timeout(1000)
local saveRootPath = "/data/web/upload/"
local UUID = uuid()
local fileName = saveRootPath .. UUID .. ".mp3"
local fileToSave = io.open(fileName, "w+")
if not fileToSave then
ngx.log(ngx.ERR, "failed to open ", fileName)
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
local ret_save = false
while true do
local typ, res, err = form:read()
if not typ then
ngx.say("failed to read: ", err)
return
end
if typ == "body" then
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
;
end
end
if ret_save then
ngx.say(UUID)
end
配置文件:
location /upload {
content_by_lua_file lua/myupload.lua;
}
location / {
limit_rate 300k;
root /data/web;
if ($request_uri ~* "^/download/([0-9a-z-]+\.mp3$)") {
set $filename $1;
rewrite ^ /upload/$filename break;
}
}
完成!!
当然了,这只是简单的测试环境的配置,如果真的要线上使用,上传类型的语音服务,还是用第三方服务比较靠谱!