ZBLOG

openresty将multipart/form-data上传的文件写入磁盘,有现成的库吗

在 OpenResty 中处理 multipart/form-data 上传文件并写入磁盘,可以通过以下两种方式实现:


1. 使用现成的 Lua 库:lua-resty-upload

这是 OpenResty 官方推荐的库,用于解析上传的文件流。虽然它不直接提供文件保存功能,但可以结合 Lua 的文件操作 API 实现。

示例代码

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)
    return ngx.exit(500)
end

-- 指定保存路径
local file_path = "/tmp/uploaded_file.txt"
local file, err = io.open(file_path, "w+")
if not file then
    ngx.log(ngx.ERR, "failed to open file: ", err)
    return ngx.exit(500)
end

-- 逐块读取并写入文件
while true do
    local typ, res, err = form:read()
    if not typ then
        ngx.log(ngx.ERR, "failed to read: ", err)
        break
    end

    if typ == "body" then
        -- 写入文件块
        file:write(res)
    elseif typ == "part_end" then
        -- 单个文件部分结束
        file:close()
        break
    end

    -- 其他类型(如 header)忽略处理
end

ngx.say("File saved to: ", file_path)

2. 使用第三方增强库:lua-resty-multipart

如果需要更高级的功能(如自动文件名处理、内存优化),可以使用社区维护的 lua-resty-multipart

安装

通过 opm 安装:

opm get Kong/lua-resty-multipart

示例代码

local multipart = require "resty.multipart"
local filename = "uploaded_file.txt"
local path = "/tmp/" .. filename

-- 解析请求体
local mp_data, err = multipart(ngx.req.get_body_data(), ngx.req.get_headers()["Content-Type"])
if not mp_data then
    ngx.log(ngx.ERR, "parse failed: ", err)
    return ngx.exit(400)
end

-- 获取文件数据并保存到磁盘  
for part in mp_data:parts() do  
    if part.filename then  
        local file_content = part.data  
        local fh, err = io.open(path, "wb")  
        if fh then  
            fh:write(file_content)  
            fh:close()  
            ngx.say("File saved as ", path)  
        else  
            ngx.log(ngx.ERR, "Failed to save file:", err)  
        end  
        break --假设只处理第一个文件 
     end 
end 

关键注意事项

  1. 性能与安全

    • 大文件需分块处理(避免内存爆炸)。
    • 检查文件名和路径合法性,防止目录遍历攻击(如 ../)。
    • 限制上传文件大小(通过 client_max_body_size)。
  2. OpenResty配置: “`nginx.confhttp { server {

       location /upload {
           content_by_lua_file /path/to/your_upload_script.lua;
           client_max_body_size100M; #允许最大100MB上传 
      } 
    

    } } “`

  3. 替代方案

如果需要进一步优化或扩展功能,可以基于上述库封装自己的逻辑。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=23255

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?