bunkerweb 1.4.0

This commit is contained in:
bunkerity
2022-06-03 17:24:14 +02:00
parent 3a078326c5
commit a9f886804a
5245 changed files with 1432051 additions and 27894 deletions

View File

@@ -0,0 +1,89 @@
local ngx_null = ngx.null
local tostring = tostring
local byte = string.byte
local gsub = string.gsub
local sort = table.sort
local pairs = pairs
local ipairs = ipairs
local concat = table.concat
local ok, new_tab = pcall(require, "table.new")
if not ok then
new_tab = function (narr, nrec) return {} end
end
local _M = {}
local metachars = {
['\t'] = '\\t',
["\\"] = "\\\\",
['"'] = '\\"',
['\r'] = '\\r',
['\n'] = '\\n',
}
local function encode_str(s)
-- XXX we will rewrite this when string.buffer is implemented
-- in LuaJIT 2.1 because string.gsub cannot be JIT compiled.
return gsub(s, '["\\\r\n\t]', metachars)
end
local function is_arr(t)
local exp = 1
for k, _ in pairs(t) do
if k ~= exp then
return nil
end
exp = exp + 1
end
return exp - 1
end
local encode
encode = function (v)
if v == nil or v == ngx_null then
return "null"
end
local typ = type(v)
if typ == 'string' then
return '"' .. encode_str(v) .. '"'
end
if typ == 'number' or typ == 'boolean' then
return tostring(v)
end
if typ == 'table' then
local n = is_arr(v)
if n then
local bits = new_tab(n, 0)
for i, elem in ipairs(v) do
bits[i] = encode(elem)
end
return "[" .. concat(bits, ",") .. "]"
end
local keys = {}
local i = 0
for key, _ in pairs(v) do
i = i + 1
keys[i] = key
end
sort(keys)
local bits = new_tab(0, i)
i = 0
for _, key in ipairs(keys) do
i = i + 1
bits[i] = encode(key) .. ":" .. encode(v[key])
end
return "{" .. concat(bits, ",") .. "}"
end
return '"<' .. typ .. '>"'
end
_M.encode = encode
return _M

650
deps/src/lua-resty-upload/t/sanity.t vendored Normal file
View File

@@ -0,0 +1,650 @@
# vim:set ft= ts=4 sw=4 et:
use Test::Nginx::Socket::Lua;
use Cwd qw(cwd);
repeat_each(2);
plan tests => repeat_each() * (3 * blocks());
my $pwd = cwd();
our $HttpConfig = qq{
lua_package_path "$pwd/lib/?.lua;$pwd/t/lib/?.lua;;";
lua_package_cpath "/usr/local/openresty-debug/lualib/?.so;/usr/local/openresty/lualib/?.so;;";
};
$ENV{TEST_NGINX_RESOLVER} = '8.8.8.8';
no_long_string();
#no_diff();
run_tests();
__DATA__
=== TEST 1: basic
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua '
local upload = require "resty.upload"
local ljson = require "ljson"
local form = upload:new(5)
form:set_timeout(1000) -- 1 sec
while true do
local typ, res, err = form:read()
if not typ then
ngx.say("failed to read: ", err)
return
end
ngx.say("read: ", ljson.encode({typ, res}))
if typ == "eof" then
break
end
end
local typ, res, err = form:read()
ngx.say("read: ", ljson.encode({typ, res}))
';
}
--- more_headers
Content-Type: multipart/form-data; boundary=---------------------------820127721219505131303151179
--- request eval
qq{POST /t\n-----------------------------820127721219505131303151179\r
Content-Disposition: form-data; name="file1"; filename="a.txt"\r
Content-Type: text/plain\r
\r
Hello, world\r\n-----------------------------820127721219505131303151179\r
Content-Disposition: form-data; name="test"\r
\r
value\r
\r\n-----------------------------820127721219505131303151179--\r
}
--- response_body
read: ["header",["Content-Disposition","form-data; name=\"file1\"; filename=\"a.txt\"","Content-Disposition: form-data; name=\"file1\"; filename=\"a.txt\""]]
read: ["header",["Content-Type","text/plain","Content-Type: text/plain"]]
read: ["body","Hello"]
read: ["body",", wor"]
read: ["body","ld"]
read: ["part_end"]
read: ["header",["Content-Disposition","form-data; name=\"test\"","Content-Disposition: form-data; name=\"test\""]]
read: ["body","value"]
read: ["body","\r\n"]
read: ["part_end"]
read: ["eof"]
read: ["eof"]
--- no_error_log
[error]
=== TEST 2: in-part header line too long
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua '
local upload = require "resty.upload"
local ljson = require "ljson"
local form = upload:new(5)
form:set_timeout(1000) -- 1 sec
while true do
local typ, res, err = form:read()
if not typ then
ngx.say("failed to read: ", err)
return
end
ngx.say("read: ", ljson.encode({typ, res}))
if typ == "eof" then
break
end
end
local typ, res, err = form:read()
ngx.say("read: ", ljson.encode({typ, res}))
';
}
--- more_headers
Content-Type: multipart/form-data; boundary=---------------------------820127721219505131303151179
--- request eval
qq{POST /t\n-----------------------------820127721219505131303151179\r
Content-Disposition: form-data; name="file1"; filename="a.txt"\r
Content-Type: text/plain\r
} . ("Hello, world" x 64) . qq{\r\n-----------------------------820127721219505131303151179\r
Content-Disposition: form-data; name="test"\r
\r
value\r
\r\n-----------------------------820127721219505131303151179--\r
}
--- response_body
read: ["header",["Content-Disposition","form-data; name=\"file1\"; filename=\"a.txt\"","Content-Disposition: form-data; name=\"file1\"; filename=\"a.txt\""]]
read: ["header",["Content-Type","text/plain","Content-Type: text/plain"]]
failed to read: line too long: Hello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, wo...
--- no_error_log
[error]
=== TEST 3: terminate line too long
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua '
local upload = require "resty.upload"
local ljson = require "ljson"
local form = upload:new(5)
form:set_timeout(1000) -- 1 sec
while true do
local typ, res, err = form:read()
if not typ then
ngx.say("failed to read: ", err)
return
end
ngx.say("read: ", ljson.encode({typ, res}))
if typ == "eof" then
break
end
end
local typ, res, err = form:read()
ngx.say("read: ", ljson.encode({typ, res}))
';
}
--- more_headers
Content-Type: multipart/form-data; boundary=---------------------------820127721219505131303151179
--- request eval
qq{POST /t\n-----------------------------820127721219505131303151179\r
Content-Disposition: form-data; name="file1"; filename="a.txt"\r
Content-Type: text/plain\r
\r
Hello, world\r\n-----------------------------820127721219505131303151179\r
Content-Disposition: form-data; name="test"\r
\r
value\r
\r\n-----------------------------820127721219505131303151179} . ("a" x 1024) . qq{--\r
}
--- response_body
read: ["header",["Content-Disposition","form-data; name=\"file1\"; filename=\"a.txt\"","Content-Disposition: form-data; name=\"file1\"; filename=\"a.txt\""]]
read: ["header",["Content-Type","text/plain","Content-Type: text/plain"]]
read: ["body","Hello"]
read: ["body",", wor"]
read: ["body","ld"]
read: ["part_end"]
read: ["header",["Content-Disposition","form-data; name=\"test\"","Content-Disposition: form-data; name=\"test\""]]
read: ["body","value"]
read: ["body","\r\n"]
failed to read: line too long: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
--- no_error_log
[error]
=== TEST 4: example from RFC 1521
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua '
local upload = require "resty.upload"
local ljson = require "ljson"
local form = upload:new(20)
form:set_timeout(1000) -- 1 sec
while true do
local typ, res, err = form:read()
if not typ then
ngx.say("failed to read: ", err)
return
end
ngx.say("read: ", ljson.encode({typ, res}))
if typ == "eof" then
break
end
end
local typ, res, err = form:read()
ngx.say("read: ", ljson.encode({typ, res}))
';
}
--- more_headers
content-TYPE: multipart/form-data; boundary="simple boundary"
--- request eval
qq{POST /t
This is the preamble. It is to be ignored, though it
is a handy place for mail composers to include an
explanatory note to non-MIME conformant readers.
--simple boundary\r
\r
This is implicitly typed plain ASCII text.
It does NOT end with a linebreak.\r
--simple boundary\r
Content-type: text/plain; charset=us-ascii\r
\r
This is explicitly typed plain ASCII text.
It DOES end with a linebreak.
\r
--simple boundary--\r
This is the epilogue. It is also to be ignored.
}
--- response_body
read: ["body","This is implicitly t"]
read: ["body","yped plain ASCII tex"]
read: ["body","t.\nIt does NOT end w"]
read: ["body","ith a linebreak."]
read: ["part_end"]
read: ["header",["Content-type","text/plain; charset=us-ascii","Content-type: text/plain; charset=us-ascii"]]
read: ["body","This is explicitly t"]
read: ["body","yped plain ASCII tex"]
read: ["body","t.\nIt DOES end with "]
read: ["body","a linebreak.\n"]
read: ["part_end"]
read: ["eof"]
read: ["eof"]
--- no_error_log
[error]
=== TEST 5: example from RFC 1521, no double quotes for the boundary value in the Content-Type response header
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua '
local upload = require "resty.upload"
local ljson = require "ljson"
local form = upload:new(20)
form:set_timeout(1000) -- 1 sec
while true do
local typ, res, err = form:read()
if not typ then
ngx.say("failed to read: ", err)
return
end
ngx.say("read: ", ljson.encode({typ, res}))
if typ == "eof" then
break
end
end
local typ, res, err = form:read()
ngx.say("read: ", ljson.encode({typ, res}))
';
}
--- more_headers
Content-Type: multipart/form-data; boundary=simple boundary
--- request eval
qq{POST /t
This is the preamble. It is to be ignored, though it
is a handy place for mail composers to include an
explanatory note to non-MIME conformant readers.
--simple boundary\r
\r
This is implicitly typed plain ASCII text.
It does NOT end with a linebreak.\r
--simple boundary\r
Content-type: text/plain; charset=us-ascii\r
\r
This is explicitly typed plain ASCII text.
It DOES end with a linebreak.
\r
--simple boundary--\r
This is the epilogue. It is also to be ignored.
}
--- response_body
read: ["body","This is implicitly t"]
read: ["body","yped plain ASCII tex"]
read: ["body","t.\nIt does NOT end w"]
read: ["body","ith a linebreak."]
read: ["part_end"]
read: ["header",["Content-type","text/plain; charset=us-ascii","Content-type: text/plain; charset=us-ascii"]]
read: ["body","This is explicitly t"]
read: ["body","yped plain ASCII tex"]
read: ["body","t.\nIt DOES end with "]
read: ["body","a linebreak.\n"]
read: ["part_end"]
read: ["eof"]
read: ["eof"]
--- no_error_log
[error]
=== TEST 6: example from RFC 1521, using the default chunk size
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua '
local upload = require "resty.upload"
local ljson = require "ljson"
local form = upload:new()
form:set_timeout(1000) -- 1 sec
while true do
local typ, res, err = form:read()
if not typ then
ngx.say("failed to read: ", err)
return
end
ngx.say("read: ", ljson.encode({typ, res}))
if typ == "eof" then
break
end
end
local typ, res, err = form:read()
ngx.say("read: ", ljson.encode({typ, res}))
';
}
--- more_headers
Content-Type: multipart/form-data; boundary=simple boundary
--- request eval
qq{POST /t
This is the preamble. It is to be ignored, though it
is a handy place for mail composers to include an
explanatory note to non-MIME conformant readers.
--simple boundary\r
\r
This is implicitly typed plain ASCII text.
It does NOT end with a linebreak.\r
--simple boundary\r
Content-type: text/plain; charset=us-ascii\r
\r
This is explicitly typed plain ASCII text.
It DOES end with a linebreak.
\r
--simple boundary--\r
This is the epilogue. It is also to be ignored.
}
--- response_body
read: ["body","This is implicitly typed plain ASCII text.\nIt does NOT end with a linebreak."]
read: ["part_end"]
read: ["header",["Content-type","text/plain; charset=us-ascii","Content-type: text/plain; charset=us-ascii"]]
read: ["body","This is explicitly typed plain ASCII text.\nIt DOES end with a linebreak.\n"]
read: ["part_end"]
read: ["eof"]
read: ["eof"]
--- no_error_log
[error]
=== TEST 7: github issue #2: cannot parse boundary - no space before parameter (w/o quotes)
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua '
local upload = require "resty.upload"
local ljson = require "ljson"
local form, err = upload:new(5)
if not form then
ngx.say("cannot get form: ", err)
return
end
form:set_timeout(1000) -- 1 sec
while true do
local typ, res, err = form:read()
if not typ then
ngx.say("failed to read: ", err)
return
end
ngx.say("read: ", ljson.encode({typ, res}))
if typ == "eof" then
break
end
end
local typ, res, err = form:read()
ngx.say("read: ", ljson.encode({typ, res}))
';
}
--- more_headers
Content-Type: multipart/form-data;boundary=---------------------------820127721219505131303151179
--- request eval
qq{POST /t\n-----------------------------820127721219505131303151179\r
Content-Disposition: form-data; name="file1"; filename="a.txt"\r
Content-Type: text/plain\r
\r
Hello, world\r\n-----------------------------820127721219505131303151179\r
Content-Disposition: form-data; name="test"\r
\r
value\r
\r\n-----------------------------820127721219505131303151179--\r
}
--- response_body
read: ["header",["Content-Disposition","form-data; name=\"file1\"; filename=\"a.txt\"","Content-Disposition: form-data; name=\"file1\"; filename=\"a.txt\""]]
read: ["header",["Content-Type","text/plain","Content-Type: text/plain"]]
read: ["body","Hello"]
read: ["body",", wor"]
read: ["body","ld"]
read: ["part_end"]
read: ["header",["Content-Disposition","form-data; name=\"test\"","Content-Disposition: form-data; name=\"test\""]]
read: ["body","value"]
read: ["body","\r\n"]
read: ["part_end"]
read: ["eof"]
read: ["eof"]
--- no_error_log
[error]
=== TEST 8: github issue #2: cannot parse boundary - no space before parameter (with quotes)
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua '
local upload = require "resty.upload"
local ljson = require "ljson"
local form, err = upload:new(5)
if not form then
ngx.say("cannot get form: ", err)
return
end
form:set_timeout(1000) -- 1 sec
while true do
local typ, res, err = form:read()
if not typ then
ngx.say("failed to read: ", err)
return
end
ngx.say("read: ", ljson.encode({typ, res}))
if typ == "eof" then
break
end
end
local typ, res, err = form:read()
ngx.say("read: ", ljson.encode({typ, res}))
';
}
--- more_headers
Content-Type: multipart/form-data;boundary="---------------------------820127721219505131303151179"
--- request eval
qq{POST /t\n-----------------------------820127721219505131303151179\r
Content-Disposition: form-data; name="file1"; filename="a.txt"\r
Content-Type: text/plain\r
\r
Hello, world\r\n-----------------------------820127721219505131303151179\r
Content-Disposition: form-data; name="test"\r
\r
value\r
\r\n-----------------------------820127721219505131303151179--\r
}
--- response_body
read: ["header",["Content-Disposition","form-data; name=\"file1\"; filename=\"a.txt\"","Content-Disposition: form-data; name=\"file1\"; filename=\"a.txt\""]]
read: ["header",["Content-Type","text/plain","Content-Type: text/plain"]]
read: ["body","Hello"]
read: ["body",", wor"]
read: ["body","ld"]
read: ["part_end"]
read: ["header",["Content-Disposition","form-data; name=\"test\"","Content-Disposition: form-data; name=\"test\""]]
read: ["body","value"]
read: ["body","\r\n"]
read: ["part_end"]
read: ["eof"]
read: ["eof"]
--- no_error_log
[error]
=== TEST 9: multiple Content-Type headers
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua '
local upload = require "resty.upload"
local ljson = require "ljson"
local form = upload:new(5)
form:set_timeout(1000) -- 1 sec
while true do
local typ, res, err = form:read()
if not typ then
ngx.say("failed to read: ", err)
return
end
ngx.say("read: ", ljson.encode({typ, res}))
if typ == "eof" then
break
end
end
local typ, res, err = form:read()
ngx.say("read: ", ljson.encode({typ, res}))
';
}
--- more_headers
Content-Type: multipart/form-data; boundary=---------------------------820127721219505131303151179
Content-Type: multipart/form-data; boundary=---------------------------820127721219505131303151179
--- request eval
qq{POST /t\n-----------------------------820127721219505131303151179\r
Content-Disposition: form-data; name="file1"; filename="a.txt"\r
Content-Type: text/plain\r
\r
Hello, world\r\n-----------------------------820127721219505131303151179\r
Content-Disposition: form-data; name="test"\r
\r
value\r
\r\n-----------------------------820127721219505131303151179--\r
}
--- response_body
read: ["header",["Content-Disposition","form-data; name=\"file1\"; filename=\"a.txt\"","Content-Disposition: form-data; name=\"file1\"; filename=\"a.txt\""]]
read: ["header",["Content-Type","text/plain","Content-Type: text/plain"]]
read: ["body","Hello"]
read: ["body",", wor"]
read: ["body","ld"]
read: ["part_end"]
read: ["header",["Content-Disposition","form-data; name=\"test\"","Content-Disposition: form-data; name=\"test\""]]
read: ["body","value"]
read: ["body","\r\n"]
read: ["part_end"]
read: ["eof"]
read: ["eof"]
--- no_error_log
[error]
=== TEST 10: long in-part header line
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua '
local upload = require "resty.upload"
local ljson = require "ljson"
local form = upload:new(5, 1024) -- max_line_size = 1024
form:set_timeout(1000) -- 1 sec
while true do
local typ, res, err = form:read()
if not typ then
ngx.say("failed to read: ", err)
return
end
ngx.say("read: ", ljson.encode({typ, res}))
if typ == "eof" then
break
end
end
local typ, res, err = form:read()
ngx.say("read: ", ljson.encode({typ, res}))
';
}
--- more_headers
Content-Type: multipart/form-data; boundary=---------------------------820127721219505131303151179
--- request eval
qq{POST /t\n-----------------------------820127721219505131303151179\r
Content-Disposition: form-data; name="file1"; filename="a.txt"\r
Content-Type: text/plain\r
} . ("Hello, world" x 64) . qq{\r\n-----------------------------820127721219505131303151179\r
Content-Disposition: form-data; name="test"\r
\r
value\r
\r\n-----------------------------820127721219505131303151179--\r
}
--- response_body
read: ["header",["Content-Disposition","form-data; name=\"file1\"; filename=\"a.txt\"","Content-Disposition: form-data; name=\"file1\"; filename=\"a.txt\""]]
read: ["header",["Content-Type","text/plain","Content-Type: text/plain"]]
read: ["header","Hello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, world"]
read: ["header","-----------------------------820127721219505131303151179"]
read: ["header",["Content-Disposition","form-data; name=\"test\"","Content-Disposition: form-data; name=\"test\""]]
read: ["body","value"]
read: ["body","\r\n"]
read: ["part_end"]
read: ["eof"]
read: ["eof"]
--- no_error_log
[error]

40
deps/src/lua-resty-upload/t/version.t vendored Normal file
View File

@@ -0,0 +1,40 @@
# vim:set ft= ts=4 sw=4 et:
use Test::Nginx::Socket::Lua;
use Cwd qw(cwd);
repeat_each(2);
plan tests => repeat_each() * (3 * blocks());
my $pwd = cwd();
our $HttpConfig = qq{
lua_package_path "$pwd/lib/?.lua;;";
};
$ENV{TEST_NGINX_RESOLVER} = '8.8.8.8';
no_long_string();
#no_diff();
run_tests();
__DATA__
=== TEST 1: basic
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua '
local upload = require "resty.upload"
ngx.say(upload._VERSION)
';
}
--- request
GET /t
--- response_body_like chop
^\d+\.\d+$
--- no_error_log
[error]