Skip to content

Commit

Permalink
Fixing h2c negotiation via "Upgrade" header to be declined if a Trans…
Browse files Browse the repository at this point in the history
…fer-Encoding" is part of the request. Refs #243

- mod_h2 does not perform Upagrde to h2c on a HTTP/1.1 request when the request has a body.
- The check for this was incomplete, looking only at Content-Length, but not Transfer-Encoding
  • Loading branch information
icing committed Jan 29, 2023
1 parent a248f93 commit 99395e4
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 3 deletions.
5 changes: 3 additions & 2 deletions mod_http2/h2_switch.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,10 @@ static int h2_protocol_propose(conn_rec *c, request_rec *r,
/* We also allow switching only for requests that have no body.
*/
p = apr_table_get(r->headers_in, "Content-Length");
if (p && strcmp(p, "0")) {
if ((p && strcmp(p, "0"))
|| (!p && apr_table_get(r->headers_in, "Transfer-Encoding"))) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03087)
"upgrade with content-length: %s, declined", p);
"upgrade with body declined");
return DECLINED;
}
}
Expand Down
16 changes: 15 additions & 1 deletion test/modules/http2/test_103_upgrade.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,21 @@ def test_h2_103_24(self, env):
url = env.mkurl("http", "test1b", "/006.html")
r = env.nghttp().get(url, options=["-u"])
assert r.response["status"] == 200
r = env.curl_get(url, options=["--http2", "-v", "--trace-time"])
r = env.curl_get(url, options=["--http2"])
assert 0 == r.exit_code
assert r.response
assert r.response["protocol"] == "HTTP/2", f'{r}'

# try ugrade to h2c with a request body, should be denied
def test_h2_103_25(self, env):
url = env.mkurl("http", "test1b", "/006.html")
r = env.curl_get(url, options=["--http2", "--data-binary", "0123456789"])
assert 0 == r.exit_code
assert r.response
assert r.response["protocol"] == "HTTP/1.1", f'{r}'
r = env.curl_get(url, options=[
"--http2", "--data-binary", "0123456789", "-H", "Transfer-Encoding: chunked"
])
assert 0 == r.exit_code
assert r.response
assert r.response["protocol"] == "HTTP/1.1", f'{r}'

0 comments on commit 99395e4

Please sign in to comment.