aboutsummaryrefslogtreecommitdiff
path: root/test/maxsize_tp.lua
diff options
context:
space:
mode:
authorCaleb Maclennan <caleb@alerque.com>2026-08-31 11:04:37 +0300
committerGitHub <noreply@github.com>2026-08-31 11:04:37 +0300
commit01162f05408ac4206be15842ef91048c63c23869 (patch)
tree2b7c8a2916cf8083b557a897c7d258e00a9c4fa3 /test/maxsize_tp.lua
parent5afe174eeffc7f3e3b9ef80b5871237620c68415 (diff)
parentc84e79f6d1ae735bfa191694ec6a62eb8231166d (diff)
downloadluasocket-01162f05408ac4206be15842ef91048c63c23869.tar.gz
luasocket-01162f05408ac4206be15842ef91048c63c23869.tar.bz2
luasocket-01162f05408ac4206be15842ef91048c63c23869.zip
Merge pull request #467 from lunarmodules/fix/http-size-protect
Fix/http size protect
Diffstat (limited to 'test/maxsize_tp.lua')
-rw-r--r--test/maxsize_tp.lua90
1 files changed, 90 insertions, 0 deletions
diff --git a/test/maxsize_tp.lua b/test/maxsize_tp.lua
new file mode 100644
index 0000000..57ce9bc
--- /dev/null
+++ b/test/maxsize_tp.lua
@@ -0,0 +1,90 @@
1-- Exercises the maxsize caps added to socket.tp's line-based receive()
2-- calls (see PLAN-RECEIVE-MAXSIZE.md). socket.tp is the shared control
3-- channel underneath both socket.ftp and socket.smtp, so this covers both.
4-- Self-contained: uses a single process with a real TCP loopback
5-- connection, so it needs no paired server script.
6local socket = require "socket"
7local tp = require "socket.tp"
8
9local host = "127.0.0.1"
10
11-- connects `open_fn(host, port)` to a freshly bound loopback listener and
12-- returns the client-side object it produced plus the server-side raw
13-- socket accepted for that connection.
14local function new_pair(open_fn)
15 local server = assert(socket.bind(host, 0))
16 local ip, port = server:getsockname()
17 local client = assert(open_fn(ip, port))
18 local srv = assert(server:accept())
19 server:close()
20 return client, srv
21end
22
23local failures = 0
24
25local function check(ok, msg)
26 if ok then
27 print("PASS: " .. msg)
28 else
29 failures = failures + 1
30 print("FAIL: " .. msg)
31 end
32end
33
34local function tp_open(ip, port)
35 return tp.connect(ip, port, 5)
36end
37
38do -- sanity: normal single-line reply still parses
39 tp.MAXLINE, tp.MAXREPLY = 8192, 65536
40 local c, srv = new_pair(tp_open)
41 srv:send("230 logged in\r\n")
42 local code, reply = c:check("2..")
43 check(code == 230 and reply == "230 logged in",
44 "tp: normal single-line reply parses")
45 c:close(); srv:close()
46end
47
48do -- sanity: normal multiline reply still parses
49 tp.MAXLINE, tp.MAXREPLY = 8192, 65536
50 local c, srv = new_pair(tp_open)
51 srv:send("214-first line\r\n214-second line\r\n214 done\r\n")
52 local code, reply = c:check("2..")
53 check(code == 214 and reply == "214-first line\n214-second line\n214 done",
54 "tp: normal multiline reply parses")
55 c:close(); srv:close()
56end
57
58do -- a single reply line over MAXLINE is rejected
59 tp.MAXLINE, tp.MAXREPLY = 8, 65536
60 local c, srv = new_pair(tp_open)
61 srv:send("230 this line is way over the line cap\r\n")
62 local code, err = c:check("2..")
63 check(code == nil and err == "oversized",
64 "tp: single line over MAXLINE -> oversized")
65 c:close(); srv:close()
66end
67
68do -- each line individually fits MAXLINE, but the reply total exceeds MAXREPLY
69 tp.MAXLINE, tp.MAXREPLY = 16, 20
70 local c, srv = new_pair(tp_open)
71 -- first line: 14 payload bytes, under both MAXLINE(16) and MAXREPLY(20)
72 srv:send("123-aaaaaaaaaa\r\n")
73 -- second line: another 14 payload bytes, individually under MAXLINE(16),
74 -- but only 6 bytes remain in the MAXREPLY(20) budget
75 srv:send("123-bbbbbbbbbb\r\n")
76 local code, err = c:check("2..")
77 check(code == nil and err == "oversized",
78 "tp: multiline reply over MAXREPLY -> oversized (no single line over MAXLINE)")
79 c:close(); srv:close()
80end
81
82tp.MAXLINE, tp.MAXREPLY = 8192, 65536
83
84if failures == 0 then
85 print("All tp maxsize tests passed")
86 os.exit(0)
87else
88 print(failures .. " tp maxsize test(s) failed")
89 os.exit(1)
90end