# let the hecho.py CGI echo chars < 0x20 in field name # for almost all such characters, the stream returns a 500 # or in httpd >= 2.5.0 gets aborted with a h2 error # cr is handled special def test_h2_200_01(self, env):
url = env.mkurl("https", "cgi", "/hecho.py") for x in range(1, 32):
data = f'name=x%{x:02x}x&value=yz'
r = env.curl_post_data(url, data) if x in [13]: assert 0 == r.exit_code, f'unexpected exit code for char 0x{x:02}' assert 200 == r.response["status"], f'unexpected status for char 0x{x:02}' elif x in [10] or env.httpd_is_at_least('2.5.0'): assert 0 == r.exit_code, f'unexpected exit code for char 0x{x:02}' assert 500 == r.response["status"], f'unexpected status for char 0x{x:02}' else: assert 0 != r.exit_code, f'unexpected exit code for char 0x{x:02}' #
env.httpd_error_log.ignore_recent(
lognos = [ "AH02429"# Response header name contains invalid characters
],
matches = [
r'.*malformed header from script \'hecho.py\': Bad header: x.*'
]
)
# let the hecho.py CGI echo chars < 0x20 in field value # for almost all such characters, the stream returns a 500 # or in httpd >= 2.5.0 gets aborted with a h2 error # cr and lf are handled special def test_h2_200_02(self, env):
url = env.mkurl("https", "cgi", "/hecho.py") for x in range(1, 32): if 9 != x:
r = env.curl_post_data(url, "name=x&value=y%%%02x" % x) if x in [10, 13]: assert 0 == r.exit_code, "unexpected exit code for char 0x%02x" % x assert 200 == r.response["status"], "unexpected status for char 0x%02x" % x elif env.httpd_is_at_least('2.5.0'): assert 0 == r.exit_code, f'unexpected exit code for char 0x{x:02}' assert 500 == r.response["status"], f'unexpected status for char 0x{x:02}' else: assert 0 != r.exit_code, "unexpected exit code for char 0x%02x" % x #
env.httpd_error_log.ignore_recent(
lognos = [ "AH02430"# Response header value contains invalid characters
]
)
# let the hecho.py CGI echo 0x10 and 0x7f in field name and value def test_h2_200_03(self, env):
url = env.mkurl("https", "cgi", "/hecho.py") for h in ["10", "7f"]:
r = env.curl_post_data(url, "name=x%%%s&value=yz" % h) if env.httpd_is_at_least('2.5.0'): assert 0 == r.exit_code, f"unexpected exit code for char 0x{h:02}" assert 500 == r.response["status"], f"unexpected exit code for char 0x{h:02}" else: assert 0 != r.exit_code
r = env.curl_post_data(url, "name=x&value=y%%%sz" % h) if env.httpd_is_at_least('2.5.0'): assert 0 == r.exit_code, f"unexpected exit code for char 0x{h:02}" assert 500 == r.response["status"], f"unexpected exit code for char 0x{h:02}" else: assert 0 != r.exit_code #
env.httpd_error_log.ignore_recent(
lognos = [ "AH02429", # Response header name contains invalid characters "AH02430"# Response header value contains invalid characters
]
)
# test header field lengths check, LimitRequestLine def test_h2_200_10(self, env):
conf = H2Conf(env)
conf.add("""
LimitRequestLine 1024 """)
conf.add_vhost_cgi()
conf.install() assert env.apache_restart() == 0
val = 200*"1234567890"
url = env.mkurl("https", "cgi", f'/?{val[:1022]}')
r = env.curl_get(url) assert r.response["status"] == 200
url = env.mkurl("https", "cgi", f'/?{val[:1023]}')
r = env.curl_get(url) # URI too long assert 414 == r.response["status"]
# test header field lengths check, LimitRequestFieldSize (default 8190) def test_h2_200_11(self, env):
conf = H2Conf(env)
conf.add("""
LimitRequestFieldSize 1024 """)
conf.add_vhost_cgi()
conf.install() assert env.apache_restart() == 0
url = env.mkurl("https", "cgi", "/")
val = 200*"1234567890" # two fields, concatenated with ', ' # LimitRequestFieldSize, one more char -> 400 in HTTP/1.1
r = env.curl_get(url, options=[ '-H', f'x: {val[:500]}', '-H', f'x: {val[:519]}'
]) assert r.exit_code == 0, f'{r}' assert r.response["status"] == 200, f'{r}'
r = env.curl_get(url, options=[ '--http1.1', '-H', f'x: {val[:500]}', '-H', f'x: {val[:523]}'
]) assert 400 == r.response["status"]
r = env.curl_get(url, options=[ '-H', f'x: {val[:500]}', '-H', f'x: {val[:520]}'
]) assert 431 == r.response["status"]
# test header field count, LimitRequestFields (default 100) # see #201: several headers with same name are merged and counted def test_h2_200_12(self, env):
url = env.mkurl("https", "cgi", "/")
opt = [] # curl sends 3 headers itself (user-agent, accept, and our AP-Test-Name) for i in range(97):
opt += ["-H", "x: 1"]
r = env.curl_get(url, options=opt) assert r.response["status"] == 200
r = env.curl_get(url, options=(opt + ["-H", "y: 2"])) assert r.response["status"] == 431
# test header field count, LimitRequestFields (default 100) # different header names count each def test_h2_200_13(self, env):
url = env.mkurl("https", "cgi", "/")
opt = [] # curl sends 3 headers itself (user-agent, accept, and our AP-Test-Name) for i in range(97):
opt += ["-H", f"x{i}: 1"]
r = env.curl_get(url, options=opt) assert r.response["status"] == 200
r = env.curl_get(url, options=(opt + ["-H", "y: 2"])) assert 431 == r.response["status"]
# test "LimitRequestFields 0" setting, see #200 def test_h2_200_14(self, env):
conf = H2Conf(env)
conf.add("""
LimitRequestFields 20 """)
conf.add_vhost_cgi()
conf.install() assert env.apache_restart() == 0
url = env.mkurl("https", "cgi", "/")
opt = [] for i in range(21):
opt += ["-H", "x{0}: 1".format(i)]
r = env.curl_get(url, options=opt) assert 431 == r.response["status"]
conf = H2Conf(env)
conf.add("""
LimitRequestFields 0 """)
conf.add_vhost_cgi()
conf.install() assert env.apache_restart() == 0
url = env.mkurl("https", "cgi", "/")
opt = [] for i in range(100):
opt += ["-H", "x{0}: 1".format(i)]
r = env.curl_get(url, options=opt) assert r.response["status"] == 200
# the uri limits def test_h2_200_15(self, env):
conf = H2Conf(env)
conf.add("""
LimitRequestLine 48 """)
conf.add_vhost_cgi()
conf.install() assert env.apache_restart() == 0
url = env.mkurl("https", "cgi", "/")
r = env.curl_get(url) assert r.response["status"] == 200
url = env.mkurl("https", "cgi", "/" + (48*"x"))
r = env.curl_get(url) assert 414 == r.response["status"] # nghttp sends the :method: header first (so far) # trigger a too long request line on it # the stream will RST and we get no response
url = env.mkurl("https", "cgi", "/")
opt = ["-H:method: {0}".format(100*"x")]
r = env.nghttp().get(url, options=opt) assert r.exit_code == 0, r assertnot r.response
# invalid chars in method def test_h2_200_16(self, env): ifnot env.h2load_is_at_least('1.45.0'):
pytest.skip(f'nhttp2 version too old')
conf = H2Conf(env)
conf.add_vhost_cgi()
conf.install() assert env.apache_restart() == 0
url = env.mkurl("https", "cgi", "/hello.py")
opt = ["-H:method: GET /hello.py"]
r = env.nghttp().get(url, options=opt) assert r.exit_code == 0, r assert r.response isNone
url = env.mkurl("https", "cgi", "/proxy/hello.py")
r = env.nghttp().get(url, options=opt) assert r.exit_code == 0, r assert r.response isNone
# test few failed headers, should def test_h2_200_17(self, env):
url = env.mkurl("https", "cgi", "/")
# test few failed headers, should give response def test_h2_200_17(self, env):
conf = H2Conf(env)
conf.add("""
LimitRequestFieldSize 20
LogLevel http2:debug """)
conf.add_vhost_cgi()
conf.install() assert env.apache_restart() == 0
re_emitted = re.compile(r'.* (AH03401: .* shutdown,|'
r'AH03066: .* FRAME\[GOAWAY.*) remote.emitted=1')
url = env.mkurl("https", "cgi", "/")
opt = [] for i in range(10):
opt += ["-H", f"x{i}: 012345678901234567890123456789"]
r = env.curl_get(url, options=opt) assert r.response assert r.response["status"] == 431 assert env.httpd_error_log.scan_recent(re_emitted)
# test too many failed headers, should give RST def test_h2_200_18(self, env):
conf = H2Conf(env)
conf.add("""
LimitRequestFieldSize 20
LogLevel http2:debug """)
conf.add_vhost_cgi()
conf.install() assert env.apache_restart() == 0
re_emitted = re.compile(r'.* (AH03401: .* shutdown,|'
r'AH03066: .* FRAME\[GOAWAY.*) remote.emitted=1')
url = env.mkurl("https", "cgi", "/")
opt = [] for i in range(100):
opt += ["-H", f"x{i}: 012345678901234567890123456789"]
r = env.curl_get(url, options=opt) assert r.response isNone assert env.httpd_error_log.scan_recent(re_emitted)
# test header 10 invalid headers, should trigger stream RST def test_h2_200_19(self, env):
url = env.mkurl("https", "cgi", "/")
opt = []
invalid = '\x7f' for i in range(10):
opt += ["-H", f"x{i}: {invalid}"]
r = env.curl_get(url, options=opt) assert r.response isNone
¤ Dauer der Verarbeitung: 0.28 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.