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:
agentzh (Yichun Zhang) 2013-03-04 17:29:00 -08:00
Родитель 40fabb23bb
Коммит eff99d5dba
7 изменённых файлов: 109 добавлений и 5 удалений

Просмотреть файл

@ -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;