Skip to content

Commit

Permalink
Upstream: fixed EOF handling in unbuffered and upgraded modes.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mdounin committed Jul 18, 2019
1 parent 36dfa02 commit 20c8c4f
Showing 1 changed file with 26 additions and 3 deletions.
29 changes: 26 additions & 3 deletions src/http/ngx_http_upstream.c
Original file line number Diff line number Diff line change
Expand Up @@ -3334,6 +3334,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
size_t size;
ssize_t n;
ngx_buf_t *b;
ngx_uint_t flags;
ngx_connection_t *c, *downstream, *upstream, *dst, *src;
ngx_http_upstream_t *u;
ngx_http_core_loc_conf_t *clcf;
Expand Down Expand Up @@ -3472,7 +3473,14 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
ngx_del_timer(upstream->write);
}

if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) {
if (upstream->read->eof || upstream->read->error) {
flags = NGX_CLOSE_EVENT;

} else {
flags = 0;
}

if (ngx_handle_read_event(upstream->read, flags) != NGX_OK) {
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
return;
}
Expand All @@ -3491,7 +3499,14 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
return;
}

if (ngx_handle_read_event(downstream->read, 0) != NGX_OK) {
if (downstream->read->eof || downstream->read->error) {
flags = NGX_CLOSE_EVENT;

} else {
flags = 0;
}

if (ngx_handle_read_event(downstream->read, flags) != NGX_OK) {
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
return;
}
Expand Down Expand Up @@ -3563,6 +3578,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
ssize_t n;
ngx_buf_t *b;
ngx_int_t rc;
ngx_uint_t flags;
ngx_connection_t *downstream, *upstream;
ngx_http_upstream_t *u;
ngx_http_core_loc_conf_t *clcf;
Expand Down Expand Up @@ -3666,7 +3682,14 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
ngx_del_timer(downstream->write);
}

if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) {
if (upstream->read->eof || upstream->read->error) {
flags = NGX_CLOSE_EVENT;

} else {
flags = 0;
}

if (ngx_handle_read_event(upstream->read, flags) != NGX_OK) {
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
return;
}
Expand Down

0 comments on commit 20c8c4f

Please sign in to comment.