From e21720da69f2a505bcd1405cc7e8b52d5649df55 Mon Sep 17 00:00:00 2001 From: Thijs Schreijer Date: Sat, 29 Aug 2026 19:59:33 +0200 Subject: fix(receive): a receive 0 should immediately return, not block The fix is slightly more complex because reading from a closed socket should still return a closed-error. fixes: #427 fixes: https://github.com/ledgetech/lua-resty-http/pull/313 --- test/test_receive_zero.lua | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 test/test_receive_zero.lua (limited to 'test/test_receive_zero.lua') diff --git a/test/test_receive_zero.lua b/test/test_receive_zero.lua new file mode 100644 index 0000000..2259910 --- /dev/null +++ b/test/test_receive_zero.lua @@ -0,0 +1,36 @@ +-- a TCP receive(0) must never block: requesting zero bytes is trivially +-- satisfied without touching the transport layer, POSIX recv(fd, buf, 0, 0) +-- returns immediately regardless of whether data is available. +local socket = require "socket" + +local host, port = "127.0.0.1", "5464" + +local server = assert(socket.bind(host, port)) +local client = assert(socket.connect(host, port)) +local peer = assert(server:accept()) + +client:settimeout(2) + +-- no data has been sent by the peer: the read buffer is empty, so if +-- receive(0) touches the network it will block until the timeout expires +local t0 = socket.gettime() +local data, err = client:receive(0) +local elapsed = socket.gettime() - t0 + +assert(data == "", "receive(0) on empty buffer returned " .. tostring(data)) +assert(err == nil, "receive(0) on empty buffer returned error " .. tostring(err)) +assert(elapsed < 1, "receive(0) on empty buffer blocked for " .. elapsed .. "s") + +-- receive(0) must also not consume any bytes when data *is* available +assert(peer:send("hello")) +data, err = client:receive(0) +assert(data == "", "receive(0) with data pending returned " .. tostring(data)) +assert(err == nil, "receive(0) with data pending returned error " .. tostring(err)) +data = assert(client:receive(5)) +assert(data == "hello", "receive(0) consumed bytes meant for receive(5)") + +client:close() +peer:close() +server:close() + +print("done!") -- cgit v1.2.3-55-g6feb