comparison src/http/ngx_http_upstream.c @ 7538:08ed570ad93c

Upstream: fixed EOF handling in unbuffered and upgraded modes. With level-triggered event methods it is important to specify the NGX_CLOSE_EVENT flag to ngx_handle_read_event(), otherwise the event won't be removed, resulting in CPU hog. Reported by Patrick Wollgast.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 18 Jul 2019 18:27:52 +0300
parents 319242d2ddc9
children 3c8082c3f98a
comparison
equal deleted inserted replaced
7537:01e26357916a 7538:08ed570ad93c
3332 ngx_uint_t from_upstream, ngx_uint_t do_write) 3332 ngx_uint_t from_upstream, ngx_uint_t do_write)
3333 { 3333 {
3334 size_t size; 3334 size_t size;
3335 ssize_t n; 3335 ssize_t n;
3336 ngx_buf_t *b; 3336 ngx_buf_t *b;
3337 ngx_uint_t flags;
3337 ngx_connection_t *c, *downstream, *upstream, *dst, *src; 3338 ngx_connection_t *c, *downstream, *upstream, *dst, *src;
3338 ngx_http_upstream_t *u; 3339 ngx_http_upstream_t *u;
3339 ngx_http_core_loc_conf_t *clcf; 3340 ngx_http_core_loc_conf_t *clcf;
3340 3341
3341 c = r->connection; 3342 c = r->connection;
3470 3471
3471 } else if (upstream->write->timer_set) { 3472 } else if (upstream->write->timer_set) {
3472 ngx_del_timer(upstream->write); 3473 ngx_del_timer(upstream->write);
3473 } 3474 }
3474 3475
3475 if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) { 3476 if (upstream->read->eof || upstream->read->error) {
3477 flags = NGX_CLOSE_EVENT;
3478
3479 } else {
3480 flags = 0;
3481 }
3482
3483 if (ngx_handle_read_event(upstream->read, flags) != NGX_OK) {
3476 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); 3484 ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
3477 return; 3485 return;
3478 } 3486 }
3479 3487
3480 if (upstream->read->active && !upstream->read->ready) { 3488 if (upstream->read->active && !upstream->read->ready) {
3489 { 3497 {
3490 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); 3498 ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
3491 return; 3499 return;
3492 } 3500 }
3493 3501
3494 if (ngx_handle_read_event(downstream->read, 0) != NGX_OK) { 3502 if (downstream->read->eof || downstream->read->error) {
3503 flags = NGX_CLOSE_EVENT;
3504
3505 } else {
3506 flags = 0;
3507 }
3508
3509 if (ngx_handle_read_event(downstream->read, flags) != NGX_OK) {
3495 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); 3510 ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
3496 return; 3511 return;
3497 } 3512 }
3498 3513
3499 if (downstream->write->active && !downstream->write->ready) { 3514 if (downstream->write->active && !downstream->write->ready) {
3561 { 3576 {
3562 size_t size; 3577 size_t size;
3563 ssize_t n; 3578 ssize_t n;
3564 ngx_buf_t *b; 3579 ngx_buf_t *b;
3565 ngx_int_t rc; 3580 ngx_int_t rc;
3581 ngx_uint_t flags;
3566 ngx_connection_t *downstream, *upstream; 3582 ngx_connection_t *downstream, *upstream;
3567 ngx_http_upstream_t *u; 3583 ngx_http_upstream_t *u;
3568 ngx_http_core_loc_conf_t *clcf; 3584 ngx_http_core_loc_conf_t *clcf;
3569 3585
3570 u = r->upstream; 3586 u = r->upstream;
3664 3680
3665 } else if (downstream->write->timer_set) { 3681 } else if (downstream->write->timer_set) {
3666 ngx_del_timer(downstream->write); 3682 ngx_del_timer(downstream->write);
3667 } 3683 }
3668 3684
3669 if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) { 3685 if (upstream->read->eof || upstream->read->error) {
3686 flags = NGX_CLOSE_EVENT;
3687
3688 } else {
3689 flags = 0;
3690 }
3691
3692 if (ngx_handle_read_event(upstream->read, flags) != NGX_OK) {
3670 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); 3693 ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
3671 return; 3694 return;
3672 } 3695 }
3673 3696
3674 if (upstream->read->active && !upstream->read->ready) { 3697 if (upstream->read->active && !upstream->read->ready) {