bugfix: use of ngx.req.socket() could make socket reading hang infinitely when the request did not take a request body at all (that is, when the Content-Length request header is missing). thanks Matthieu Tourne for reporting this issue.
This commit is contained in:
Родитель
40fabb23bb
Коммит
eff99d5dba
|
@ -3032,9 +3032,11 @@ ngx_http_lua_req_socket(lua_State *L)
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->headers_in.content_length_n == 0) {
|
dd("req content length: %d", (int) r->headers_in.content_length_n);
|
||||||
|
|
||||||
|
if (r->headers_in.content_length_n <= 0) {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
lua_pushliteral(L, "request body empty");
|
lua_pushliteral(L, "no body");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -956,6 +956,10 @@ after
|
||||||
}
|
}
|
||||||
--- request
|
--- request
|
||||||
POST /lua
|
POST /lua
|
||||||
|
|
||||||
|
--- more_headers
|
||||||
|
Content-Length: 1024
|
||||||
|
|
||||||
--- stap2 eval: $::StapScript
|
--- stap2 eval: $::StapScript
|
||||||
--- stap eval
|
--- stap eval
|
||||||
<<'_EOC_' . $::GCScript;
|
<<'_EOC_' . $::GCScript;
|
||||||
|
|
|
@ -165,6 +165,7 @@ terminate 3: ok
|
||||||
delete thread 3
|
delete thread 3
|
||||||
free request
|
free request
|
||||||
|
|
||||||
|
--- wait: 0.1
|
||||||
--- response_body
|
--- response_body
|
||||||
before
|
before
|
||||||
hello in thread
|
hello in thread
|
||||||
|
@ -937,6 +938,10 @@ after
|
||||||
}
|
}
|
||||||
--- request
|
--- request
|
||||||
POST /lua
|
POST /lua
|
||||||
|
|
||||||
|
--- more_headers
|
||||||
|
Content-Length: 1024
|
||||||
|
|
||||||
--- stap2 eval: $::StapScript
|
--- stap2 eval: $::StapScript
|
||||||
--- stap eval
|
--- stap eval
|
||||||
<<'_EOC_' . $::GCScript;
|
<<'_EOC_' . $::GCScript;
|
||||||
|
|
|
@ -1323,7 +1323,9 @@ this exposed a memory leak in receiveuntil
|
||||||
';
|
';
|
||||||
}
|
}
|
||||||
--- request
|
--- request
|
||||||
GET /t
|
POST /t
|
||||||
|
|
||||||
|
--- more_headers: Content-Length: 1024
|
||||||
--- response_body
|
--- response_body
|
||||||
ok
|
ok
|
||||||
--- no_error_log
|
--- no_error_log
|
||||||
|
|
|
@ -666,3 +666,89 @@ hello world
|
||||||
[alert]
|
[alert]
|
||||||
--- skip_nginx: 4: <1.3.9
|
--- skip_nginx: 4: <1.3.9
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
=== TEST 11: downstream cosocket for GET requests (w/o request bodies)
|
||||||
|
--- config
|
||||||
|
#resolver 8.8.8.8;
|
||||||
|
location = /t {
|
||||||
|
content_by_lua '
|
||||||
|
local sock, err = ngx.req.socket()
|
||||||
|
|
||||||
|
if not sock then
|
||||||
|
ngx.say("failed to get socket: ", err)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
while true do
|
||||||
|
local data, err, partial = sock:receive(4096)
|
||||||
|
|
||||||
|
ngx.log(ngx.INFO, "Received data")
|
||||||
|
|
||||||
|
if err then
|
||||||
|
ngx.say("err: ", err)
|
||||||
|
if partial then
|
||||||
|
ngx.print(partial)
|
||||||
|
end
|
||||||
|
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
if data then
|
||||||
|
ngx.print(data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
';
|
||||||
|
}
|
||||||
|
|
||||||
|
--- request
|
||||||
|
GET /t
|
||||||
|
--- response_body
|
||||||
|
failed to get socket: no body
|
||||||
|
--- no_error_log
|
||||||
|
[error]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
=== TEST 12: downstream cosocket for POST requests with 0 size bodies
|
||||||
|
--- config
|
||||||
|
#resolver 8.8.8.8;
|
||||||
|
location = /t {
|
||||||
|
content_by_lua '
|
||||||
|
local sock, err = ngx.req.socket()
|
||||||
|
|
||||||
|
if not sock then
|
||||||
|
ngx.say("failed to get socket: ", err)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
while true do
|
||||||
|
local data, err, partial = sock:receive(4096)
|
||||||
|
|
||||||
|
ngx.log(ngx.INFO, "Received data")
|
||||||
|
|
||||||
|
if err then
|
||||||
|
ngx.say("err: ", err)
|
||||||
|
if partial then
|
||||||
|
ngx.print(partial)
|
||||||
|
end
|
||||||
|
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
if data then
|
||||||
|
ngx.print(data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
';
|
||||||
|
}
|
||||||
|
|
||||||
|
--- request
|
||||||
|
POST /t
|
||||||
|
--- more_headers
|
||||||
|
Content-Length: 0
|
||||||
|
--- response_body
|
||||||
|
failed to get socket: no body
|
||||||
|
--- no_error_log
|
||||||
|
[error]
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,8 @@ __DATA__
|
||||||
';
|
';
|
||||||
}
|
}
|
||||||
--- request
|
--- request
|
||||||
GET /t
|
POST /t
|
||||||
|
--- more_headers: Content-Length: 1024
|
||||||
--- response_body_like: 500 Internal Server Error
|
--- response_body_like: 500 Internal Server Error
|
||||||
--- error_code: 500
|
--- error_code: 500
|
||||||
--- error_log
|
--- error_log
|
||||||
|
@ -45,7 +46,8 @@ bad argument #1 to 'receive' (table expected, got string)
|
||||||
';
|
';
|
||||||
}
|
}
|
||||||
--- request
|
--- request
|
||||||
GET /t
|
POST /t
|
||||||
|
--- more_headers: Content-Length: 1024
|
||||||
--- response_body_like: 500 Internal Server Error
|
--- response_body_like: 500 Internal Server Error
|
||||||
--- error_code: 500
|
--- error_code: 500
|
||||||
--- error_log
|
--- error_log
|
||||||
|
|
|
@ -906,6 +906,9 @@ after
|
||||||
}
|
}
|
||||||
--- request
|
--- request
|
||||||
POST /lua
|
POST /lua
|
||||||
|
--- more_headers
|
||||||
|
Content-Length: 1024
|
||||||
|
|
||||||
--- stap2 eval: $::StapScript
|
--- stap2 eval: $::StapScript
|
||||||
--- stap eval
|
--- stap eval
|
||||||
<<'_EOC_' . $::GCScript;
|
<<'_EOC_' . $::GCScript;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче