Mercurial > hg > nginx-quic
comparison src/http/v2/ngx_http_v2.c @ 7354:1812f1d79d84
Fixed socket leak with "return 444" in error_page (ticket #274).
Socket leak was observed in the following configuration:
error_page 400 = /close;
location = /close {
return 444;
}
The problem is that "return 444" triggers termination of the request,
and due to error_page termination thinks that it needs to use a posted
request to clear stack. But at the early request processing where 400
errors are generated there are no ngx_http_run_posted_requests() calls,
so the request is only terminated after an external event.
Variants of the problem include "error_page 497" instead (ticket #695)
and various other errors generated during early request processing
(405, 414, 421, 494, 495, 496, 501, 505).
The same problem can be also triggered with "return 499" and "return 408"
as both codes trigger ngx_http_terminate_request(), much like "return 444".
To fix this, the patch adds ngx_http_run_posted_requests() calls to
ngx_http_process_request_line() and ngx_http_process_request_headers()
functions, and to ngx_http_v2_run_request() and ngx_http_v2_push_stream()
functions in HTTP/2.
Since the ngx_http_process_request() function is now only called via
other functions which call ngx_http_run_posted_requests(), the call
there is no longer needed and was removed.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Fri, 21 Sep 2018 15:59:30 +0300 |
parents | fbb683496705 |
children | d4448892a294 |
comparison
equal
deleted
inserted
replaced
7353:87d2ea860f38 | 7354:1812f1d79d84 |
---|---|
2671 | 2671 |
2672 error: | 2672 error: |
2673 | 2673 |
2674 if (rc == NGX_ABORT) { | 2674 if (rc == NGX_ABORT) { |
2675 /* header handler has already finalized request */ | 2675 /* header handler has already finalized request */ |
2676 ngx_http_run_posted_requests(fc); | |
2676 return NULL; | 2677 return NULL; |
2677 } | 2678 } |
2678 | 2679 |
2679 if (rc == NGX_DECLINED) { | 2680 if (rc == NGX_DECLINED) { |
2680 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); | 2681 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); |
2682 ngx_http_run_posted_requests(fc); | |
2681 return NULL; | 2683 return NULL; |
2682 } | 2684 } |
2683 | 2685 |
2684 close: | 2686 close: |
2685 | 2687 |
3740 | 3742 |
3741 | 3743 |
3742 static void | 3744 static void |
3743 ngx_http_v2_run_request(ngx_http_request_t *r) | 3745 ngx_http_v2_run_request(ngx_http_request_t *r) |
3744 { | 3746 { |
3747 ngx_connection_t *fc; | |
3748 | |
3749 fc = r->connection; | |
3750 | |
3745 if (ngx_http_v2_construct_request_line(r) != NGX_OK) { | 3751 if (ngx_http_v2_construct_request_line(r) != NGX_OK) { |
3746 return; | 3752 goto failed; |
3747 } | 3753 } |
3748 | 3754 |
3749 if (ngx_http_v2_construct_cookie_header(r) != NGX_OK) { | 3755 if (ngx_http_v2_construct_cookie_header(r) != NGX_OK) { |
3750 return; | 3756 goto failed; |
3751 } | 3757 } |
3752 | 3758 |
3753 r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE; | 3759 r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE; |
3754 | 3760 |
3755 if (ngx_http_process_request_header(r) != NGX_OK) { | 3761 if (ngx_http_process_request_header(r) != NGX_OK) { |
3756 return; | 3762 goto failed; |
3757 } | 3763 } |
3758 | 3764 |
3759 if (r->headers_in.content_length_n > 0 && r->stream->in_closed) { | 3765 if (r->headers_in.content_length_n > 0 && r->stream->in_closed) { |
3760 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, | 3766 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, |
3761 "client prematurely closed stream"); | 3767 "client prematurely closed stream"); |
3762 | 3768 |
3763 r->stream->skip_data = 1; | 3769 r->stream->skip_data = 1; |
3764 | 3770 |
3765 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); | 3771 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); |
3766 return; | 3772 goto failed; |
3767 } | 3773 } |
3768 | 3774 |
3769 if (r->headers_in.content_length_n == -1 && !r->stream->in_closed) { | 3775 if (r->headers_in.content_length_n == -1 && !r->stream->in_closed) { |
3770 r->headers_in.chunked = 1; | 3776 r->headers_in.chunked = 1; |
3771 } | 3777 } |
3772 | 3778 |
3773 ngx_http_process_request(r); | 3779 ngx_http_process_request(r); |
3780 | |
3781 failed: | |
3782 | |
3783 ngx_http_run_posted_requests(fc); | |
3774 } | 3784 } |
3775 | 3785 |
3776 | 3786 |
3777 static void | 3787 static void |
3778 ngx_http_v2_run_request_handler(ngx_event_t *ev) | 3788 ngx_http_v2_run_request_handler(ngx_event_t *ev) |