Mercurial > hg > nginx
comparison src/http/ngx_http_request_body.c @ 9238:392e8e2fd22a
Request body: explicit handling of NGX_AGAIN.
Request body reading indirectly uses the "do { c->recv() } while
(c->read->ready)" form, which is not really correct, as for example
with SSL c->read->ready may be still set when c->recv() returns NGX_AGAIN
due to SSL_ERROR_WANT_WRITE (see 7351:2b5528023f6b), and therefore this
form might be an infinite loop.
Added explicit NGX_AGAIN handling for the sake of correctness.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sat, 30 Mar 2024 05:06:59 +0300 |
parents | 9aff230f10d1 |
children | b2e16e8639c8 |
comparison
equal
deleted
inserted
replaced
9237:41db21d1ca7c | 9238:392e8e2fd22a |
---|---|
305 ngx_http_core_loc_conf_t *clcf; | 305 ngx_http_core_loc_conf_t *clcf; |
306 | 306 |
307 c = r->connection; | 307 c = r->connection; |
308 rb = r->request_body; | 308 rb = r->request_body; |
309 flush = 1; | 309 flush = 1; |
310 n = NGX_AGAIN; | |
310 | 311 |
311 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | 312 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
312 "http read client request body"); | 313 "http read client request body"); |
313 | 314 |
314 for ( ;; ) { | 315 for ( ;; ) { |
430 | 431 |
431 if (rb->rest == 0 && rb->last_saved) { | 432 if (rb->rest == 0 && rb->last_saved) { |
432 break; | 433 break; |
433 } | 434 } |
434 | 435 |
435 if (!c->read->ready || rb->rest == 0) { | 436 if (n == NGX_AGAIN || !c->read->ready || rb->rest == 0) { |
436 | 437 |
437 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 438 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
438 ngx_add_timer(c->read, clcf->client_body_timeout); | 439 ngx_add_timer(c->read, clcf->client_body_timeout); |
439 | 440 |
440 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { | 441 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { |