Skip to content

Commit

Permalink
Stream: added half-close support.
Browse files Browse the repository at this point in the history
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.

--HG--
branch : nginx
  • Loading branch information
vlhomutov committed Sep 22, 2021
1 parent 0daf7c3 commit 21d4038
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/stream/ngx_stream_proxy_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ typedef struct {
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;

Expand Down Expand Up @@ -245,6 +246,13 @@ static ngx_command_t ngx_stream_proxy_commands[] = {
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"),
Expand Down Expand Up @@ -1755,6 +1763,24 @@ ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream,
}

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;
Expand Down Expand Up @@ -1833,6 +1859,13 @@ ngx_stream_proxy_test_finalize(ngx_stream_session_t *s,
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;

Expand Down Expand Up @@ -2052,6 +2085,7 @@ ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf)
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;
Expand Down Expand Up @@ -2110,6 +2144,8 @@ ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
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);
Expand Down
1 change: 1 addition & 0 deletions src/stream/ngx_stream_upstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ typedef struct {
ngx_stream_upstream_state_t *state;
unsigned connected:1;
unsigned proxy_protocol:1;
unsigned half_closed:1;
} ngx_stream_upstream_t;


Expand Down

0 comments on commit 21d4038

Please sign in to comment.