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) {