Mercurial > hg > nginx
changeset 7929:bfad703459b4
Stream: added half-close support.
The "proxy_half_close" directive enables handling of TCP half close. If
enabled, connection to proxied server is kept open until both read ends get
EOF. Write end shutdown is properly transmitted via proxy.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Wed, 22 Sep 2021 10:20:00 +0300 |
parents | 97cf8284fd19 |
children | ae7c767aa491 |
files | src/stream/ngx_stream_proxy_module.c src/stream/ngx_stream_upstream.h |
diffstat | 2 files changed, 37 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/stream/ngx_stream_proxy_module.c Fri Sep 10 12:59:22 2021 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Wed Sep 22 10:20:00 2021 +0300 @@ -31,6 +31,7 @@ ngx_uint_t next_upstream_tries; ngx_flag_t next_upstream; ngx_flag_t proxy_protocol; + ngx_flag_t half_close; ngx_stream_upstream_local_t *local; ngx_flag_t socket_keepalive; @@ -245,6 +246,13 @@ offsetof(ngx_stream_proxy_srv_conf_t, proxy_protocol), NULL }, + { ngx_string("proxy_half_close"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_proxy_srv_conf_t, half_close), + NULL }, + #if (NGX_STREAM_SSL) { ngx_string("proxy_ssl"), @@ -1755,6 +1763,24 @@ } if (dst) { + + if (dst->type == SOCK_STREAM && pscf->half_close + && src->read->eof && !u->half_closed && !dst->buffered) + { + if (ngx_shutdown_socket(dst->fd, NGX_WRITE_SHUTDOWN) == -1) { + ngx_connection_error(c, ngx_socket_errno, + ngx_shutdown_socket_n " failed"); + + ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); + return; + } + + u->half_closed = 1; + ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, + "stream proxy %s socket shutdown", + from_upstream ? "client" : "upstream"); + } + if (ngx_handle_write_event(dst->write, 0) != NGX_OK) { ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); return; @@ -1833,6 +1859,13 @@ return NGX_DECLINED; } + if (pscf->half_close) { + /* avoid closing live connections until both read ends get EOF */ + if (!(c->read->eof && pc->read->eof && !c->buffered && !pc->buffered)) { + return NGX_DECLINED; + } + } + handler = c->log->handler; c->log->handler = NULL; @@ -2052,6 +2085,7 @@ conf->proxy_protocol = NGX_CONF_UNSET; conf->local = NGX_CONF_UNSET_PTR; conf->socket_keepalive = NGX_CONF_UNSET; + conf->half_close = NGX_CONF_UNSET; #if (NGX_STREAM_SSL) conf->ssl_enable = NGX_CONF_UNSET; @@ -2110,6 +2144,8 @@ ngx_conf_merge_value(conf->socket_keepalive, prev->socket_keepalive, 0); + ngx_conf_merge_value(conf->half_close, prev->half_close, 0); + #if (NGX_STREAM_SSL) ngx_conf_merge_value(conf->ssl_enable, prev->ssl_enable, 0);