On Thu, May 17, 2012 at 9:04 AM, Matthieu Tourne
<matthie...@gmail.com> wrote:
> Hi,
>
> I think I might have found another bug with POSTs and receiveuntil()
>
> I attached the failing test for you
>
Well, I think it is the test case itself that has bugs. To quote the
documentation for the receiveuntil method:
"The iterator function behaves differently (i.e., like a real
iterator) when it is called with a size argument. That is, it will
read that size of data at earch invocation and will return nil at the
last invocation (either sees the boundary pattern or meets an error).
For the last successful invocation of the iterator function, the err
return value will be nil too. The iterator function will automatically
reset after its last successful invocation that returns nil data and
nil error."
The test will pass if it's modified like this:
=== TEST 8: urlencoded
--- http_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua';"
--- config
location /t {
content_by_lua '
local test = require "test"
test.go()
ngx.say("done")
';
}
--- user_files
>>> test.lua
module("test", package.seeall)
function go()
local sock, err = ngx.req.socket()
if sock then
ngx.say("got the request socket")
else
ngx.say("failed to get the request socket: ", err)
return
end
local read2value, err = sock:receiveuntil("=")
if not read2value then
return nil, err
end
local read2key, err = sock:receiveuntil("&")
if not read2key then
return nil, err
end
while true do
local data, err, part = read2value(8192)
if data then
ngx.say("received key: ", data)
else
if err then
ngx.say("failed to receive: ", err, " [", part, "]")
break
end
end
local data, err, part = read2key(8192)
if data then
ngx.say("received value: ", data)
else
if err then
ngx.say("failed to receive: ", err, " [", part, "]")
break
end
end
end
end
--- request
POST /t
toto=foo&foo=toto
--- response_body
got the request socket
received key: toto
received value: foo
received key: foo
failed to receive: closed [toto]
done
--- no_error_log
[error]
That is, when the "data" returned is nil, it could be an indication
for the end of the current reading pass, so you must check "err" too.
Regards,
-agentzh