感谢大神的回答,对我们这些初学者您就是及时雨,向您学习。
我把代码做了些改动
1、重新生成了文件名,重复文件的几率很小应该,就一个人进行测试,应该不重复
2、限制了上传的文件格式,只允许上传png和jpg格式的文件
3、将重新生成的文件名以json串的格式返回给客户端
然后进行测试,问题同样发生
从代码执行上来看,是上传成功的,只是从最终的结果看,上传了之后是有问题的
4. 不应使用 0 超时保护,此时其实会使用 ngx_lua 默认的 60 秒超时设置。
这个应该如何做是合理的?
![]()
下面是改动后的代码,感觉代码还是比较简单,不明白为什么,
![]()
,继续测试中,如有遇到解决过同样问题的同学,那就太幸运了!
![]()
---------------------------------------------------------------------------------------
package.path = '/usr/local/share/lua/5.1/?.lua;/home/mddapp/bin/openresty/lualib/resty/?.lua;'
package.cpath = '/usr/local/lib/lua/5.1/?.so;'
local upload = require "upload"
--定义过程中使用的变量
local chunk_size = 4096
local form = upload:new(chunk_size)
local file
local filelen=0
form:set_timeout(0) -- 1 sec
local filename
local oldfilename
--获取扩展名
function getExtension(str)
return str:match(".+%.(%w+)$")
end
--获取文件名
function get_filename(res)
local oldfilename = ngx.re.match(res,'(.+)filename="(.+)"(.*)')
if oldfilename then
return oldfilename[2]
end
end
--生成新的文件名
--YYMMDDHHmmSS+RRR+RRR格式
function gen_new_file()
math.randomseed(tostring(os.time()):reverse():sub(1, 6))
filename = string.format("%s%03d%03d",os.date("%Y%m%d%H%M%S", os.time()),math.random(999),math.random(999));
return filename
end
--指定文件保存的地址
local osfilepath = "/home/server/bin/openresty/nginx/html/pictmp/"
--开始解析请求,接收文件
--文件上传完毕,返回新生成的文件的名字
local i=0
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
if res[1] ~= "Content-Type" then
oldfilename = get_filename(res[2])
if not oldfilename then
--ngx.say("Error to get OldFileName")
return
end
fileExtNormal = getExtension(oldfilename)
if not fileExtNormal then
ngx.say("{\"Code\": 10,\"Msg\":\"无法获取扩展名\",\"Response\":null}")
return
end
fileExt = string.lower(fileExtNormal)
--限制上传文件格式为jpg或者png
if fileExt == "jpg" then
elseif fileExt == "png" then
else
ngx.say("{\"Code\": 11,\"Msg\":\"不支持的扩展名\",\"Response\":null}")
return
end
--生成新的文件名
filename = gen_new_file()
if filename then
i=i+1
filepath = osfilepath .. filename.."."..fileExt
file = io.open(filepath,"w+")
if not file then
ngx.say("{\"Code\": 12,\"Msg\":\"保存文件失败\",\"Response\":null}")
return
end
else
end
end
elseif typ == "body" then
if file then
filelen= filelen + tonumber(string.len(res))
file:write(res)
else
end
elseif typ == "part_end" then
if file then
file:close()
file = nil
ngx.say("{\"Code\": 0,\"Msg\":\"success\",\"Response\":\"",filename,".",fileExt,"\"}")
end
elseif typ == "eof" then
break
else
end
end
if i==0 then
ngx.say("{\"Code\": 13,\"Msg\":\"缺少文件\",\"Response\":null}")
return
end
------------------ 原始邮件 ------------------
发件人: "agentzh"<age...@gmail.com>;
发送时间: 2015年2月26日(星期四) 下午3:11
收件人: "openresty"<openresty@googlegroups.com>;
主题: Re: [openresty] nginx+lua照片上传的问题
Hello!
2015-02-25 22:38 GMT-08:00 泡泡龙:
> 在网上找到大神写的这个文件上传的代码,作为照片上传的服务端使用,在过程中发现有的照片上传上来的内容有错乱,比如图片大小不一致,图片的内容有错误等情况。
>
你给出的这段代码有多个明显的问题,比如:
1. 多个并发连接同时上传同名文件时会产生文件写冲突(所以不该使用客户端提供的文件名,同时这也有安全隐患);
2. 当客户端在上传过程中出错,你应当自动删除写了一半的文件。
3. 当出错时应该自己记录 nginx 错误日志,以便排查问题。
4. 不应使用 0 超时保护,此时其实会使用 ngx_lua 默认的 60 秒超时设置。
或许还有其他问题,但抱歉我没有时间帮你仔细测试这段 Lua 代码的正确性。
Regards,
-agentzh
--