Skip to content

Commit 175ec6e

Browse files
committed
add request args parse
1 parent c3c34d9 commit 175ec6e

File tree

2 files changed

+172
-0
lines changed

2 files changed

+172
-0
lines changed

vanilla/v/libs/reqargs.lua

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
-- parse request body to args, this lib come from bungle
2+
-- @since 2016-03-12 6:45
3+
-- @author idevz <zhoujing00k@gmail.com>
4+
-- @see https://github.com/bungle/lua-resty-reqargs
5+
-- version $Id$
6+
7+
-- perf
8+
local upload = require "resty.upload"
9+
local json_decode = require "cjson.safe".decode
10+
local os_tmpname = os.tmpname
11+
local tconcat = table.concat
12+
local type = type
13+
local s_find = string.find
14+
local io_open = io.open
15+
local s_sub = string.sub
16+
local ngx = ngx
17+
local ngx_req = ngx.req
18+
local ngx_var = ngx.var
19+
local req_read_body = ngx_req.read_body
20+
local req_get_body_data = ngx_req.get_body_data
21+
local req_get_post_args = ngx_req.get_post_args
22+
local req_get_uri_args = ngx_req.get_uri_args
23+
24+
local function rightmost(s, sep)
25+
local p = 1
26+
local i = s_find(s, sep, 1, true)
27+
while i do
28+
p = i + 1
29+
i = s_find(s, sep, p, true)
30+
end
31+
if p > 1 then
32+
s = s_sub(s, p)
33+
end
34+
return s
35+
end
36+
37+
local function basename(s)
38+
return rightmost(rightmost(s, "\\"), "/")
39+
end
40+
41+
local function kv(r, s)
42+
if s == "formdata" then return end
43+
local e = s_find(s, "=", 1, true)
44+
if e then
45+
r[s_sub(s, 2, e - 1)] = s_sub(s, e + 2, #s - 1)
46+
else
47+
r[#r+1] = s
48+
end
49+
end
50+
51+
local function parse(s)
52+
if not s then return nil end
53+
local r = {}
54+
local i = 1
55+
local b = s_find(s, ";", 1, true)
56+
while b do
57+
local p = s_sub(s, i, b - 1)
58+
kv(r, p)
59+
i = b + 1
60+
b = s_find(s, ";", i, true)
61+
end
62+
local p = s_sub(s, i)
63+
if p ~= "" then kv(r, p) end
64+
return r
65+
end
66+
67+
local ReqArgs = {}
68+
69+
function ReqArgs:getRequestData(options)
70+
local GET = req_get_uri_args()
71+
local POST = {}
72+
local FILE = {}
73+
local content_type = ngx_var.content_type
74+
if content_type == nil then return GET, POST, FILE end
75+
if s_sub(content_type, 1, 19) == "multipart/form-data" then
76+
local chunk_size = options.chunk_size or 8192
77+
local form, err = upload:new(chunk_size)
78+
if not form then return nil, err end
79+
local header, post_data, file_info, out_put_file
80+
form:set_timeout(options.timeout or 1000)
81+
while true do
82+
local res_type, res, err = form:read()
83+
if not res_type then return nil, err end
84+
if res_type == "header" then
85+
if not header then header = {} end
86+
if type(res) == "table" then
87+
local k, v = res[1], parse(res[2])
88+
if v then header[k] = v end
89+
end
90+
elseif res_type == "body" then
91+
if header then
92+
local header_data = header["Content-Disposition"]
93+
if header_data then
94+
if header_data.filename then
95+
file_info = {
96+
name = header_data.name,
97+
type = header["Content-Type"] and header["Content-Type"][1],
98+
file = basename(header_data.filename),
99+
temp = os_tmpname()
100+
}
101+
out_put_file, err = io_open(file_info.temp, "w+")
102+
if not out_put_file then return nil, err end
103+
out_put_file:setvbuf("full", chunk)
104+
else
105+
post_data = { name = header_data.name, data = { n = 1 } }
106+
end
107+
end
108+
h = nil
109+
end
110+
if out_put_file then
111+
local ok, err = out_put_file:write(res)
112+
if not ok then return nil, err end
113+
elseif post_data then
114+
local n = post_data.data.n
115+
post_data.data[n] = res
116+
post_data.data.n = n + 1
117+
end
118+
elseif res_type == "part_end" then
119+
if out_put_file then
120+
file_info.size = out_put_file:seek()
121+
out_put_file:close()
122+
out_put_file = nil
123+
end
124+
local c, d
125+
if file_info then
126+
c, d, file_info = FILE, file_info, nil
127+
elseif post_data then
128+
c, d, post_data = POST, post_data, nil
129+
end
130+
if c then
131+
local n = d.name
132+
local s = d.data and tconcat(d.data) or d
133+
if n then
134+
local z = c[n]
135+
if z then
136+
if z.n then
137+
z.n = z.n + 1
138+
z[z.n] = s
139+
else
140+
z = { z, s }
141+
z.n = 2
142+
end
143+
else
144+
c[n] = s
145+
end
146+
else
147+
c[c.n+1] = s
148+
c.n = c.n + 1
149+
end
150+
end
151+
elseif res_type == "eof" then
152+
break
153+
end
154+
end
155+
local t, r, e = form:read()
156+
if not t then return nil, e end
157+
elseif s_sub(content_type, 1, 16) == "application/json" then
158+
req_read_body()
159+
POST = json_decode(req_get_body_data()) or {}
160+
else
161+
req_read_body()
162+
POST = req_get_post_args()
163+
end
164+
return GET, POST, FILE
165+
end
166+
167+
return ReqArgs

vanilla/v/request.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
-- Request moudle
2+
-- @since 2015-08-17 10:54
3+
-- @author idevz <zhoujing00k@gmail.com>
4+
-- version $Id$
5+
16
-- perf
27
local error = error
38
local pairs = pairs

0 commit comments

Comments
 (0)