| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- -- =========================================
- -- 文件上传接口
- -- =========================================
- local upload = require "resty.upload"
- local cjson = require "cjson.safe"
- ngx.header.content_type = "application/json; charset=utf-8"
- local upload_dir = "/opt/oss/upload/"
- local max_size = 20 * 1024 * 1024 -- 20MB
- -- 工具函数
- local function now_ms()
- return tostring(math.floor(ngx.now() * 1000))
- end
- local function get_ym()
- return os.date("%Y%m")
- end
- local function safe_suffix(name)
- -- 获取文件后缀,例如 .png
- return name:match("^.+(%..+)$") or ""
- end
- local form, err = upload:new(4096)
- if not form then
- ngx.say(cjson.encode({ code = 500, msg = "创建上传对象失败: " .. (err or ""), data = {} }))
- return
- end
- form:set_timeout(10000)
- local file, filename, filesize = nil, nil, 0
- while true do
- local typ, res, err = form:read()
- if not typ then
- ngx.say(cjson.encode({ code = 500, msg = "读取上传内容失败: " .. (err or ""), data = {} }))
- return
- end
- if typ == "header" then
- local name, value = res[1], res[2]
- if name == "Content-Disposition" then
- local orig_name = value:match('filename="(.-)"')
- if orig_name then
- local suffix = safe_suffix(orig_name)
- local newname = get_ym() .. "_" .. now_ms() .. suffix
- local fullpath = upload_dir .. newname
- -- 判断文件是否存在
- local f = io.open(fullpath, "r")
- if f then
- f:close()
- ngx.say(cjson.encode({code = 429, msg = "当前访问人数较多,请稍后重试", data = {}}))
- return
- end
- -- 打开文件写入
- file, err = io.open(fullpath, "w+")
- if not file then
- ngx.say(cjson.encode({ code = 500, msg = "无法创建文件: " .. (err or ""), data = {} }))
- return
- end
- filename = newname
- end
- end
- elseif typ == "body" then
- if file then
- filesize = filesize + #res
- if filesize > max_size then
- file:close()
- os.remove(upload_dir .. filename)
- ngx.say(cjson.encode({ code = 413, msg = "文件过大(限制20MB)", data = {} }))
- return
- end
- file:write(res)
- end
- elseif typ == "part_end" then
- if file then
- file:close()
- file = nil
- end
- elseif typ == "eof" then
- break
- end
- end
- ngx.say(cjson.encode({
- code = 200,
- msg = "上传成功",
- data = {
- filename = filename,
- url = "/oss/upload/" .. filename,
- size = filesize
- }
- }))
|