pytest: test very long urls

test_02_36 tests h1/h2/h3 with urls longer than 1/16/32/64K.

Protocols behave the same until the size exceed 64k when h2 frame limits
bite and h3 exhibits a different http status.

Failed attempt to reproduce #18121
Closes #18129
This commit is contained in:
Stefan Eissing 2025-08-01 11:01:55 +02:00 committed by Daniel Stenberg
parent 30daac9f2f
commit 7f5ad2028d
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
2 changed files with 37 additions and 0 deletions

View file

@ -1024,6 +1024,7 @@ static CURLcode h3_open_stream(struct Curl_cfilter *cf,
stream3_id = quiche_h3_send_request(ctx->h3c, ctx->qconn, nva, nheader,
stream->send_closed);
CURL_TRC_CF(data, cf, "quiche_send_request() -> %" FMT_PRIu64, stream3_id);
if(stream3_id < 0) {
if(QUICHE_H3_ERR_STREAM_BLOCKED == stream3_id) {
/* quiche seems to report this error if the connection window is

View file

@ -751,3 +751,39 @@ class TestDownload:
'-P', f'{pause_offset}', '-V', proto, url
])
r.check_exit_code(0)
# download with looong urls
@pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3'])
@pytest.mark.parametrize("url_junk", [1024, 16*1024, 32*1024, 64*1024])
def test_02_36_looong_urls(self, env: Env, httpd, nghttpx, proto, url_junk):
if proto == 'h3' and not env.have_h3():
pytest.skip("h3 not supported")
if proto == 'h3' and env.curl_uses_lib('quiche'):
pytest.skip("quiche fails from 16k onwards")
curl = CurlClient(env=env)
# url is longer than 'url_len'
url = f'https://{env.authority_for(env.domain1, proto)}/data.json?{"x"*(url_junk)}'
r = curl.http_download(urls=[url], alpn_proto=proto)
if url_junk <= 1024:
r.check_exit_code(0)
r.check_response(http_status=200)
elif url_junk <= 16*1024:
r.check_exit_code(0)
# server replies with 414, Request URL too long
r.check_response(http_status=414)
elif url_junk <= 32*1024:
r.check_exit_code(0)
# server replies with 414, Request URL too long
r.check_response(http_status=414)
else:
# with urls larger than 64k, behaviour differs
if proto == 'http/1.1':
r.check_exit_code(0)
r.check_response(http_status=414)
elif proto == 'h2':
# h2 is unable to send such large headers (frame limits)
r.check_exit_code(55)
elif proto == 'h3':
r.check_exit_code(0)
# nghttpx reports 431 Request Header Field too Large
r.check_response(http_status=431)