-
Notifications
You must be signed in to change notification settings - Fork 1
/
http_util.lua
110 lines (91 loc) · 2.2 KB
/
http_util.lua
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
local socket_url = require("socket.url")
local http_util = {}
---@param t table
---@return string
function http_util.encode_query_string(t)
local i = 0
local buf = {}
for k, v in pairs(t) do
if v ~= false then
buf[i + 1] = socket_url.escape(k)
if v == true then
buf[i + 2] = "&"
i = i + 2
else
buf[i + 2] = "="
buf[i + 3] = socket_url.escape(v)
buf[i + 4] = "&"
i = i + 4
end
end
end
buf[i] = nil
return table.concat(buf)
end
---@param s string
---@return table
function http_util.decode_query_string(s)
local query = {}
if not s then
return query
end
s = s .. "&"
for kv in s:gmatch("([^&]+)&") do
local k, v = kv:match("^(.-)=(.*)$")
if k then
query[socket_url.unescape(k)] = socket_url.unescape(v)
else
query[socket_url.unescape(kv)] = true
end
end
return query
end
local boundary = "------------------------d67fe448c18233b3"
---@param files table
---@return string
---@return table
function http_util.multipart_form_data(files)
local body = {}
for _, file in ipairs(files) do
table.insert(body, "--" .. boundary)
table.insert(body, ("Content-Disposition: form-data; name=%q; filename=%q"):format(
file.name, file.filename or file.name
))
table.insert(body, "Content-Type: application/octet-stream")
table.insert(body, "")
table.insert(body, file[1])
end
table.insert(body, "--" .. boundary .. "--")
table.insert(body, "")
body = table.concat(body, "\r\n")
local headers = {
["Content-Length"] = #body,
["Content-Type"] = "multipart/form-data; boundary=" .. boundary,
}
return body, headers
end
function http_util.parse_multipart_form_data(body, boundary)
local parts = {}
for part in body:gmatch("%-%-" .. boundary .. "\r?\n(.-)%-%-" .. boundary) do
table.insert(parts, part)
end
return parts
end
-- https://www.rfc-editor.org/rfc/rfc2183.html
---@param s string
---@return table
function http_util.parse_content_disposition(s)
local cd = {}
s = s:match("^%s*(.-)%s*$")
local dtype, params = s:match("^(.-)(;.+)$")
if not dtype then
cd.type = s
return cd
end
for k, v in params:gmatch(";%s*([^;]-)=([^;]+)%s*") do
v = socket_url.unescape(v:match("^\"(.+)\"") or v)
cd[k] = v
end
return cd
end
return http_util