diff --git a/ChangeLog b/ChangeLog index e1698335..a2caca6b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ + v1.15.4 + -------------------------------------------------------------------------------- + * Fixed interaction with mod_reqtimeout. mod-h2 was knocking it out completely, however + it allow configuration of the TLS handshake timeout and that is very useful indeed. + Also, fixed a stupid mistake of mine that made `H2Direct` always `on`, irregardless + of configuration. Found and reported by and + . Thanks! * Switched test suite and test cgis to python3. A regression in cgi.Fieldstorage() makes tests skip chunked uploads at the moment. Sad. * Merged PR by @mkaufmann that avoids multiple field lengths violations to be logged diff --git a/configure.ac b/configure.ac index c738bef8..c2c9ca0d 100644 --- a/configure.ac +++ b/configure.ac @@ -14,7 +14,7 @@ # AC_PREREQ([2.69]) -AC_INIT([mod_http2], [1.15.3], [stefan.eissing@greenbytes.de]) +AC_INIT([mod_http2], [1.15.4], [stefan.eissing@greenbytes.de]) LT_PREREQ([2.2.6]) LT_INIT() diff --git a/mod-h2.xcodeproj/project.pbxproj b/mod-h2.xcodeproj/project.pbxproj index e8501ccb..c936164b 100644 --- a/mod-h2.xcodeproj/project.pbxproj +++ b/mod-h2.xcodeproj/project.pbxproj @@ -63,6 +63,7 @@ B25574A41BEB6EFC0058F97B /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = ""; }; B25574A71BEB6EFC0058F97B /* mod_http2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mod_http2.c; sourceTree = ""; }; B256C4BA1ADD5FF10042C760 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + B26A5B63238BEF0E006F7AF3 /* test_105_timeout.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_105_timeout.py; sourceTree = ""; }; B277B814221310B800A41B44 /* test_500_proxy.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_500_proxy.py; sourceTree = ""; }; B277B8162214576300A41B44 /* test_005_status.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_005_status.py; sourceTree = ""; }; B277B8172214582600A41B44 /* TestHttpdConf.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = TestHttpdConf.py; sourceTree = ""; }; @@ -501,6 +502,7 @@ B297A7BC213D6AAD0096F0D7 /* test_102_require.py */, B297A7BD213D6C830096F0D7 /* test_103_upgrade.py */, B2FDA580222D495E007BD19C /* test_104_padding.py */, + B26A5B63238BEF0E006F7AF3 /* test_105_timeout.py */, B297A7BE213D7A5B0096F0D7 /* test_200_header_invalid.py */, B297A7C0213EA9BF0096F0D7 /* test_201_header_conditional.py */, B297A7C2213EB14B0096F0D7 /* test_202_trailer.py */, diff --git a/mod_http2/h2_config.c b/mod_http2/h2_config.c index fede8cc2..53415024 100644 --- a/mod_http2/h2_config.c +++ b/mod_http2/h2_config.c @@ -269,8 +269,7 @@ static apr_int64_t h2_srv_config_geti64(const h2_config *conf, h2_config_var_t v case H2_CONF_UPGRADE: return H2_CONFIG_GET(conf, &defconf, h2_upgrade); case H2_CONF_DIRECT: - return 1; - /*return H2_CONFIG_GET(conf, &defconf, h2_direct);*/ + return H2_CONFIG_GET(conf, &defconf, h2_direct); case H2_CONF_TLS_WARMUP_SIZE: return H2_CONFIG_GET(conf, &defconf, tls_warmup_size); case H2_CONF_TLS_COOLDOWN_SECS: diff --git a/mod_http2/h2_h2.c b/mod_http2/h2_h2.c index 4ff1d51d..1b69fe35 100644 --- a/mod_http2/h2_h2.c +++ b/mod_http2/h2_h2.c @@ -542,7 +542,7 @@ int h2_allows_h2_upgrade(request_rec *r) * Register various hooks */ static const char* const mod_ssl[] = { "mod_ssl.c", NULL}; -static const char* const mod_reqtimeout[] = { "mod_reqtimeout.c", NULL}; +static const char* const mod_reqtimeout[] = { "mod_ssl.c", "mod_reqtimeout.c", NULL}; void h2_h2_register_hooks(void) { @@ -553,7 +553,7 @@ void h2_h2_register_hooks(void) * a chance to take over before it. */ ap_hook_process_connection(h2_h2_process_conn, - mod_ssl, mod_reqtimeout, APR_HOOK_LAST); + mod_reqtimeout, NULL, APR_HOOK_LAST); /* One last chance to properly say goodbye if we have not done so * already. */ diff --git a/mod_http2/h2_version.h b/mod_http2/h2_version.h index 574d5053..5a52670d 100644 --- a/mod_http2/h2_version.h +++ b/mod_http2/h2_version.h @@ -27,7 +27,7 @@ * @macro * Version number of the http2 module as c string */ -#define MOD_HTTP2_VERSION "1.15.3-git" +#define MOD_HTTP2_VERSION "1.15.4-git" /** * @macro @@ -35,7 +35,7 @@ * release. This is a 24 bit number with 8 bits for major number, 8 bits * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203. */ -#define MOD_HTTP2_VERSION_NUM 0x010f03 +#define MOD_HTTP2_VERSION_NUM 0x010f04 #endif /* mod_h2_h2_version_h */ diff --git a/test/e2e/test_105_timeout.py b/test/e2e/test_105_timeout.py new file mode 100644 index 00000000..257149c2 --- /dev/null +++ b/test/e2e/test_105_timeout.py @@ -0,0 +1,87 @@ +# +# mod-h2 test suite +# check HTTP/2 timeout behaviour +# + +import copy +import re +import sys +import socket +import time +import pytest + +from datetime import datetime +from TestEnv import TestEnv +from TestHttpdConf import HttpdConf + +def setup_module(module): + print("setup_module: %s" % module.__name__) + TestEnv.init() + + +def teardown_module(module): + print("teardown_module: %s" % module.__name__) + assert TestEnv.apache_stop() == 0 + +class TestStore: + + # Check that base servers 'Timeout' setting is observed on SSL handshake + def test_105_01(self): + conf = HttpdConf() + conf.add_line(""" + Timeout 2 + """) + conf.add_vhost_cgi() + conf.install() + assert TestEnv.apache_restart() == 0 + host = 'localhost' + # read with a longer timeout than the server + sock = socket.create_connection((host, int(TestEnv.HTTPS_PORT))) + try: + sock.settimeout(2.5) + buff = sock.recv(1024) + assert buff == b'' + except Exception as ex: + print(f"server did not close in time: {ex}") + assert False + sock.close() + # read with a shorter timeout than the server + sock = socket.create_connection((host, int(TestEnv.HTTPS_PORT))) + try: + sock.settimeout(0.5) + buff = sock.recv(1024) + assert False + except Exception as ex: + print(f"as expected: {ex}") + sock.close() + + # Check that mod_reqtimeout handshake setting takes effect + def test_105_02(self): + conf = HttpdConf() + conf.add_line(""" + Timeout 10 + RequestReadTimeout handshake=2 header=5 body=10 + """) + conf.add_vhost_cgi() + conf.install() + assert TestEnv.apache_restart() == 0 + host = 'localhost' + # read with a longer timeout than the server + sock = socket.create_connection((host, int(TestEnv.HTTPS_PORT))) + try: + sock.settimeout(2.5) + buff = sock.recv(1024) + assert buff == b'' + except Exception as ex: + print(f"server did not close in time: {ex}") + assert False + sock.close() + # read with a shorter timeout than the server + sock = socket.create_connection((host, int(TestEnv.HTTPS_PORT))) + try: + sock.settimeout(0.5) + buff = sock.recv(1024) + assert False + except Exception as ex: + print(f"as expected: {ex}") + sock.close()