Openresty使用lua-resty-upload模块上传并保存文件

OpenResty 是一个基于 Nginx 与Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。这里将用到 lua-resty-upload 模块来处理上传超大的文件的请求。

Openresty上传文件

lua-resty-upload

lua-resty-upload 模块实现基于 rfc1867 的 http协议文件上传、要求客户端提交的表单enctype=”multipart/form-data”,method=”POST”。

前端

1
2
3
4
5
<form action="upfile" method="post" enctype="multipart/form-data">
        <label for="testFileName">select file: </label>
        <input type="file" name="testFileName"/>
        <input type="submit" name="upload" value="Upload" />
    </form>

后端处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
local upload = require "resty.upload"
local cjson = require "cjson"

local chunk_size = 4096 -- should be set to 4096 or 8192

local filename
local file = nil

function get_filename(res)
    local filename = ngx.re.match(res,'(.+)filename="(.+)"(.*)')
    if filename then
        return filename[2]
    end
end

function existsFile(path)
    x = io.open(path)
    if x == nil then
        io.close()
        return false
    else
        x:close()
        return true
    end
end

local form, err = upload:new(chunk_size)
if not form then
    ngx.log(ngx.ERR, "failed to new upload: ", err)
    ngx.exit(500)
end

form:set_timeout(1000) -- 1 sec

local osfilepath = "/tmp/"
local i=0

while true do
    local typ, res, err = form:read()
    if not typ then
        ngx.say("failed to read: ", err)
        return
    end

    ngx.say("read: ", cjson.encode({typ, res}))

    if typ == "header" then
        if res[1] ~= "Content-Type" then
            filename = get_filename(res[2])
            if filename then
                i=i+1
                filepath = osfilepath  .. filename
                file = io.open(filepath,"w+")
                if not file then
                    ngx.say("failed to open file: ", filepath)
                    return
                end
            end
        end
    elseif typ == "body" then
        ngx.say("body begin")
        if file then
            file:write(res)
            ngx.say("write ok: ", res)
        end
    elseif typ == "part_end" then
        ngx.say("part_end")
        if file then
            file:close()
            file = nil
            ngx.say("file upload success")
        end
    elseif typ == "eof" then
        break
    end
end

local typ, res, err = form:read()
ngx.say("read: ", cjson.encode({typ, res}))

if i==0 then
    ngx.say("please upload at least one file!")
    return
end

python 测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import requests #pip install requests if you don't have it already

url = 'http://www.test.com/lua/upload'
files = {'file':open('55e82a49e35383de7dcaa8b325da148f.jpg')} 
#files = {'file':open('hello.txt')} 
#'file' => name of html input field
r = requests.post(url, files=files)

#print r
#print dir(r)
print '=============== content ==================='
#print r.content
'''
print '=============== text ==================='
print r.text
print '=============== json ==================='
print r.json
print '=============== raw ==================='
print r.raw
'''
print '=============== url ==================='
print r.url

本文网址: https://pylist.com/topic/49.html 转摘请注明来源

Suggested Topics

Mac 极速安装Lua 简洁环境

Lua 的环境有两种: LuaLuaJIT,为了速度,选择 LuaJIT,实行效率提升几十倍。LuaJIT 对应的是 Lua5.1 的语法。...

Android webview input file 上传图片

webview 载入的网页里的 input file 点击后无法弹出窗口,是系统为了安全问题屏蔽了,可以通过重写`setWebChromeClient` 实现系统调用。...

Leave a Comment