diff --git a/doc/admin-guide/files/records.config.en.rst b/doc/admin-guide/files/records.config.en.rst index 435b2566098..b12fcc9ad07 100644 --- a/doc/admin-guide/files/records.config.en.rst +++ b/doc/admin-guide/files/records.config.en.rst @@ -3845,6 +3845,13 @@ Sockets exception being if you run Traffic Server with a protocol plugin, and would like for it to not support HTTP requests at all. +.. ts:cv:: CONFIG proxy.config.http.allow_half_open INT 1 + :reloadable: + :overridable: + + Turn on or off support for connection half open for client side. Default is on, so + after client sends FIN, the connection is still there. + .. ts:cv:: CONFIG proxy.config.http.wait_for_cache INT 0 Accepting inbound connections and starting the cache are independent diff --git a/doc/developer-guide/api/functions/TSHttpOverridableConfig.en.rst b/doc/developer-guide/api/functions/TSHttpOverridableConfig.en.rst index 17e2a61a7ac..aa352b4bbb1 100644 --- a/doc/developer-guide/api/functions/TSHttpOverridableConfig.en.rst +++ b/doc/developer-guide/api/functions/TSHttpOverridableConfig.en.rst @@ -170,6 +170,7 @@ TSOverridableConfigKey Value Configuratio :c:macro:`TS_CONFIG_HTTP_PARENT_CONNECT_ATTEMPT_TIMEOUT` :ts:cv:`proxy.config.http.parent_proxy.connect_attempts_timeout` :c:macro:`TS_CONFIG_HTTP_NORMALIZE_AE` :ts:cv:`proxy.config.http.normalize_ae` :c:macro:`TS_CONFIG_HTTP_ALLOW_MULTI_RANGE` :ts:cv:`proxy.config.http.allow_multi_range` +:c:macro:`TS_CONFIG_HTTP_ALLOW_HALF_OPEN` :ts:cv:`proxy.config.http.allow_half_open` ================================================================== ==================================================================== Examples diff --git a/lib/ts/apidefs.h.in b/lib/ts/apidefs.h.in index a0358126b5b..c30c5d04ba0 100644 --- a/lib/ts/apidefs.h.in +++ b/lib/ts/apidefs.h.in @@ -769,6 +769,7 @@ typedef enum { TS_CONFIG_HTTP_INSERT_FORWARDED, TS_CONFIG_HTTP_ALLOW_MULTI_RANGE, TS_CONFIG_HTTP_REQUEST_BUFFER_ENABLED, + TS_CONFIG_HTTP_ALLOW_HALF_OPEN, TS_CONFIG_LAST_ENTRY } TSOverridableConfigKey; diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc index a340fe2b83e..18d113c10d2 100644 --- a/mgmt/RecordsConfig.cc +++ b/mgmt/RecordsConfig.cc @@ -317,6 +317,8 @@ static const RecordElement RecordsConfig[] = // # basics # // ########## // # + {RECT_CONFIG, "proxy.config.http.allow_half_open", RECD_INT, "1", RECU_DYNAMIC, RR_NULL, RECC_INT, "[0-1]", RECA_NULL} + , {RECT_CONFIG, "proxy.config.http.enabled", RECD_INT, "1", RECU_RESTART_TM, RR_NULL, RECC_INT, "[0-1]", RECA_NULL} , {RECT_CONFIG, "proxy.config.http.server_ports", RECD_STRING, "8080 8080:ipv6", RECU_RESTART_TM, RR_NULL, RECC_NULL, nullptr, RECA_NULL} diff --git a/plugins/experimental/ts_lua/ts_lua_http_config.c b/plugins/experimental/ts_lua/ts_lua_http_config.c index c4b75931985..4090e8f2189 100644 --- a/plugins/experimental/ts_lua/ts_lua_http_config.c +++ b/plugins/experimental/ts_lua/ts_lua_http_config.c @@ -134,6 +134,7 @@ typedef enum { TS_LUA_CONFIG_HTTP_PARENT_CONNECT_ATTEMPT_TIMEOUT = TS_CONFIG_HTTP_PARENT_CONNECT_ATTEMPT_TIMEOUT, TS_LUA_CONFIG_HTTP_ALLOW_MULTI_RANGE = TS_CONFIG_HTTP_ALLOW_MULTI_RANGE, TS_LUA_CONFIG_HTTP_REQUEST_BUFFER_ENABLED = TS_CONFIG_HTTP_REQUEST_BUFFER_ENABLED, + TS_LUA_CONFIG_HTTP_ALLOW_HALF_OPEN = TS_CONFIG_HTTP_ALLOW_HALF_OPEN, TS_LUA_CONFIG_LAST_ENTRY = TS_CONFIG_LAST_ENTRY, } TSLuaOverridableConfigKey; @@ -260,6 +261,7 @@ ts_lua_var_item ts_lua_http_config_vars[] = { TS_LUA_MAKE_VAR_ITEM(TS_LUA_CONFIG_HTTP_PARENT_CONNECT_ATTEMPT_TIMEOUT), TS_LUA_MAKE_VAR_ITEM(TS_LUA_CONFIG_HTTP_ALLOW_MULTI_RANGE), TS_LUA_MAKE_VAR_ITEM(TS_LUA_CONFIG_HTTP_REQUEST_BUFFER_ENABLED), + TS_LUA_MAKE_VAR_ITEM(TS_LUA_CONFIG_HTTP_ALLOW_HALF_OPEN), TS_LUA_MAKE_VAR_ITEM(TS_LUA_CONFIG_LAST_ENTRY), }; diff --git a/proxy/InkAPI.cc b/proxy/InkAPI.cc index 77c7b038e7d..1bfef7ae50b 100644 --- a/proxy/InkAPI.cc +++ b/proxy/InkAPI.cc @@ -8223,6 +8223,9 @@ _conf_to_memberp(TSOverridableConfigKey conf, OverridableHttpConfigParams *overr case TS_CONFIG_HTTP_ALLOW_MULTI_RANGE: ret = _memberp_to_generic(&overridableHttpConfig->allow_multi_range, typep); break; + case TS_CONFIG_HTTP_ALLOW_HALF_OPEN: + ret = _memberp_to_generic(&overridableHttpConfig->allow_half_open, typep); + break; // This helps avoiding compiler warnings, yet detect unhandled enum members. case TS_CONFIG_NULL: case TS_CONFIG_LAST_ENTRY: @@ -8471,6 +8474,8 @@ TSHttpTxnConfigFind(const char *name, int length, TSOverridableConfigKey *conf, if (!strncmp(name, "proxy.config.ssl.client.cert.path", length)) { cnf = TS_CONFIG_SSL_CERT_FILEPATH; typ = TS_RECORDDATATYPE_STRING; + } else if (!strncmp(name, "proxy.config.http.allow_half_open", length)) { + cnf = TS_CONFIG_HTTP_ALLOW_HALF_OPEN; } break; diff --git a/proxy/InkAPITest.cc b/proxy/InkAPITest.cc index 8bcdae8c5df..ee37e121780 100644 --- a/proxy/InkAPITest.cc +++ b/proxy/InkAPITest.cc @@ -7606,7 +7606,8 @@ const char *SDK_Overridable_Configs[TS_CONFIG_LAST_ENTRY] = {"proxy.config.url_r "proxy.config.http.normalize_ae", "proxy.config.http.insert_forwarded", "proxy.config.http.allow_multi_range", - "proxy.config.http.request_buffer_enabled"}; + "proxy.config.http.request_buffer_enabled", + "proxy.config.http.allow_half_open"}; REGRESSION_TEST(SDK_API_OVERRIDABLE_CONFIGS)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus) { diff --git a/proxy/http/Http1ClientTransaction.cc b/proxy/http/Http1ClientTransaction.cc index 9c662c63ac6..b0cd96a86dd 100644 --- a/proxy/http/Http1ClientTransaction.cc +++ b/proxy/http/Http1ClientTransaction.cc @@ -67,3 +67,9 @@ Http1ClientTransaction::transaction_done() static_cast(parent)->release_transaction(); } } + +bool +Http1ClientTransaction::allow_half_open() const +{ + return current_reader ? current_reader->t_state.txn_conf->allow_half_open > 0 : true; +} diff --git a/proxy/http/Http1ClientTransaction.h b/proxy/http/Http1ClientTransaction.h index fb23bc7a5b2..9730a30fb7b 100644 --- a/proxy/http/Http1ClientTransaction.h +++ b/proxy/http/Http1ClientTransaction.h @@ -88,11 +88,7 @@ class Http1ClientTransaction : public ProxyClientTransaction return false; } - bool - allow_half_open() const override - { - return true; - } + bool allow_half_open() const override; void set_parent(ProxyClientSession *new_parent) override; diff --git a/proxy/http/HttpConfig.cc b/proxy/http/HttpConfig.cc index 65990efca21..1f14efb1ebb 100644 --- a/proxy/http/HttpConfig.cc +++ b/proxy/http/HttpConfig.cc @@ -1067,6 +1067,8 @@ HttpConfig::startup() HttpEstablishStaticConfigLongLong(c.oride.cache_max_stale_age, "proxy.config.http.cache.max_stale_age"); HttpEstablishStaticConfigByte(c.oride.srv_enabled, "proxy.config.srv_enabled"); + HttpEstablishStaticConfigByte(c.oride.allow_half_open, "proxy.config.http.allow_half_open"); + HttpEstablishStaticConfigStringAlloc(c.oride.cache_vary_default_text, "proxy.config.http.cache.vary_default_text"); HttpEstablishStaticConfigStringAlloc(c.oride.cache_vary_default_images, "proxy.config.http.cache.vary_default_images"); HttpEstablishStaticConfigStringAlloc(c.oride.cache_vary_default_other, "proxy.config.http.cache.vary_default_other"); @@ -1353,6 +1355,8 @@ HttpConfig::reconfigure() params->oride.srv_enabled = m_master.oride.srv_enabled; + params->oride.allow_half_open = m_master.oride.allow_half_open; + // open read failure retries params->oride.max_cache_open_read_retries = m_master.oride.max_cache_open_read_retries; params->oride.cache_open_read_retry_time = m_master.oride.cache_open_read_retry_time; diff --git a/proxy/http/HttpConfig.h b/proxy/http/HttpConfig.h index 8a22a4396f9..ffc90e22a94 100644 --- a/proxy/http/HttpConfig.h +++ b/proxy/http/HttpConfig.h @@ -451,6 +451,7 @@ struct OverridableHttpConfigParams { cache_open_write_fail_action(0), post_check_content_length_enabled(1), request_buffer_enabled(0), + allow_half_open(1), ssl_client_verify_server(0), redirect_use_orig_cache_key(0), number_of_redirections(0), @@ -630,6 +631,11 @@ struct OverridableHttpConfigParams { //////////////////////////////////////////////// MgmtByte request_buffer_enabled; + ///////////////////////////////////////////////// + // Keep connection open after client sends FIN // + ///////////////////////////////////////////////// + MgmtByte allow_half_open; + ///////////////////////////// // server verification mode// /////////////////////////////