nginx+lua图片上传

原创
2017/12/15 18:49
阅读数 1.6K

base64图片上传:


--==========================================
-- 图片base64上传
--==========================================
local cjson = require "cjson"

local resty_md5 = require "resty.md5"
local str = require "resty.string" 

function rjson(path,code,msg)
     local res = {uploadPath=path,code=code,msg=msg}
     ngx.say(cjson.encode(res))
     --os.exit()
end
 
-- 字符串 split 分割
string.split = function(s, p)
    local rt= {}
    string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end )
    return rt
end
 
-- 支持字符串前后 trim
string.trim = function(s)
    return (s:gsub("^%s*(.-)%s*$", "%1"))
end
 
-- 文件保存的根路径
local imagePath = '/uploadImage/'
local saveRootPath = "/home/ubuntu"..imagePath 
-- 保存的文件对象
local fileToSave
 
--文件是否成功保存
local ret_save = false

function fileExists(path)
        local file = io.open(path,"rb")
        if file then file:close() end
        return file ~= nil

end

function createFilePath(yearPath,mouthPath,datePath)
  local yp = saveRootPath..yearPath
  if not fileExists(yp) then
        os.execute("mkdir -p "..yp)
  end
  local mp = yp..'/'..mouthPath
  if not fileExists(mp) then
        os.execute("mkdir -p "..mp)
  end
  local dp = mp..'/'..datePath
  if not fileExists(dp) then
        os.execute("mkdir -p "..dp);
  end
  if not fileExists(dp) then
    return  false;
  else
   return dp..'/'
  end
  return nil;
end

function split( str,reps )
    local resultStrList = {}
    string.gsub(str,'[^'..reps..']+',function ( w )
        table.insert(resultStrList,w)
    end)
    return resultStrList
end

local year = os.date('%Y')
local mouth = os.date("%m")
local date = os.date("%d")
local savePath = createFilePath(year,mouth,date);

ngx.req.read_body()
local fheader = ngx.req.get_headers()['content-type'];
if fheader == 'application/x-www-form-urlencoded' then
    local args,err = ngx.req.get_post_args();
   if not args then
    ngx.say(err)
    rjson("",2,"base64不存在")
    return 
   end
   local base64Data = args['img']
   if not base64Data then
       rjson("",2,"img不存在")
       return 
   end
    local imgData = split(base64Data,',');--切割base64字符串
    local imgTypeList =  split(imgData[1],"/")[2]
    local imgType = split(imgTypeList,";")[1]   --文件后缀
    local newImg = ngx.decode_base64(imgData[2])
    local ffname =  ngx.md5(os.time())..'.'..imgType;
    --开始写入文件
     local base64fileToSave = io.open(savePath..ffname, "w+")
     if base64fileToSave then
            base64fileToSave:write(newImg)
            base64fileToSave:close()
            base64fileToSave = nil
        local lp = imagePath..year.."/"..mouth.."/"..date.."/"..ffname
         rjson(lp,1,'上传成功');
         return 
     end
    rjson("",2,"上传失败");
 return 
else
  rjson("",2,"没问文件上传")
end

 


--==========================================
-- 文件上传
--==========================================
 
local upload = require "resty.upload"
local cjson = require "cjson"

local resty_md5 = require "resty.md5"
local str = require "resty.string" 
local chunk_size = 4096

function rjson(path,code,msg)
     local res = {uploadPath=path,code=code,msg=msg}
     ngx.say(cjson.encode(res))
     --os.exit()
end
 
-- 字符串 split 分割
string.split = function(s, p)
    local rt= {}
    string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end )
    return rt
end
 
-- 支持字符串前后 trim
string.trim = function(s)
    return (s:gsub("^%s*(.-)%s*$", "%1"))
end
 
-- 文件保存的根路径
local imagePath = '/uploadImage/'
local saveRootPath = "/home/ubuntu"..imagePath 
-- 保存的文件对象
local fileToSave
 
--文件是否成功保存
local ret_save = false

function fileExists(path)
        local file = io.open(path,"rb")
        if file then file:close() end
        return file ~= nil

end

function createFilePath(yearPath,mouthPath,datePath)
  local yp = saveRootPath..yearPath
  if not fileExists(yp) then
        os.execute("mkdir -p "..yp)
  end
  local mp = yp..'/'..mouthPath
  if not fileExists(mp) then
        os.execute("mkdir -p "..mp)
  end
  local dp = mp..'/'..datePath
  if not fileExists(dp) then
        os.execute("mkdir -p "..dp);
  end
  if not fileExists(dp) then
    return  false;
  else
   return dp..'/'
  end
  return nil;
end

function split( str,reps )
    local resultStrList = {}
    string.gsub(str,'[^'..reps..']+',function ( w )
        table.insert(resultStrList,w)
    end)
    return resultStrList
end

local year = os.date('%Y')
local mouth = os.date("%m")
local date = os.date("%d")
local savePath = createFilePath(year,mouth,date);

----文件上传
local form, err = upload:new(chunk_size)
--声明header头部 multipart/form-data
if not form then
    ngx.log(ngx.ERR, "failed to new upload: ", err)
    --ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
     rjson("",2,"上传文件不存在")
    return
end

form:set_timeout(1000)
while true do
    local typ, res, err = form:read()
    if not typ then
        rjosn("",2,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, "=")
                    local filename = string.sub(kvfile[2], 2, -2)
            local name = split(filename,'.')
            local md5 = resty_md5:new()
            local fname = md5:update(os.time()..filename) 
            local digest = md5:final()
            local fname = str.to_hex(digest).."."..name[2]
            local spath = savePath..fname
            imageUrl = imagePath..year.."/"..mouth.."/"..date.."/"..fname
                    if filename then
                        fileToSave = io.open(spath, "w+")
            
                        if not fileToSave then
                            --ngx.say("failed to open file ", filename)
                rjson("",2,"failed to open file")
                            return
                        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
   --local res = { uploadPath=imageUrl,status=1,msg="上传成功"}
    --ngx.say(cjson.encode(res))
   rjson(imageUrl,1,"上传成功")
end
 

 


 

展开阅读全文
打赏
0
2 收藏
分享
加载中
更多评论
打赏
0 评论
2 收藏
0
分享
返回顶部
顶部