http: reject HTTP major version switch mid connection

A connection that has seen an HTTP major version now refuses any other
major HTTP version in future responses. Previously, a HTTP/1.x
connection would just silently accept HTTP/2 or HTTP/3 in the status
lines as long as it had support for those built-in. It would then just
lead to confusion and badness.

Indirectly Spotted by CodeSonar which identified a duplicate assignment
in this function.

Add test 471 to verify

Closes #13421
This commit is contained in:
Daniel Stenberg 2024-04-19 10:27:04 +02:00
parent 123d3ef5db
commit a032e97f2b
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
3 changed files with 82 additions and 5 deletions

View File

@ -3202,10 +3202,13 @@ CURLcode Curl_http_statusline(struct Curl_easy *data,
#ifdef USE_HTTP3
case 30:
#endif
/* TODO: we should verify that responses do not switch major
* HTTP version of the connection. Now, it seems we might accept
* a HTTP/2 response on a HTTP/1.1 connection, which is wrong. */
conn->httpversion = (unsigned char)k->httpversion;
/* no major version switch mid-connection */
if(conn->httpversion &&
(k->httpversion/10 != conn->httpversion/10)) {
failf(data, "Version mismatch (from HTTP/%u to HTTP/%u)",
conn->httpversion/10, k->httpversion/10);
return CURLE_UNSUPPORTED_PROTOCOL;
}
break;
default:
failf(data, "Unsupported HTTP version (%u.%d) in response",

View File

@ -73,7 +73,7 @@ test426 test427 test428 test429 test430 test431 test432 test433 test434 \
test435 test436 test437 test438 test439 test440 test441 test442 test443 \
test444 test445 test446 test447 test448 test449 test450 test451 test452 \
test453 test454 test455 test456 test457 test458 test459 test460 test461 \
test462 test463 test467 test468 test469 test470 \
test462 test463 test467 test468 test469 test470 test471 \
\
test490 test491 test492 test493 test494 test495 test496 test497 test498 \
test499 test500 test501 test502 test503 test504 test505 test506 test507 \

74
tests/data/test471 Normal file
View File

@ -0,0 +1,74 @@
<testcase>
<info>
<keywords>
HTTP
HTTP GET
globbing
{} list
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Tue, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6
Content-Type: text/html
Funny-head: yesyes
-foo-
</data>
<data1>
HTTP/2 200 OK
Content-Type: text/html
Funny-head: swsclose
Connection: close
crap data
</data1>
</reply>
#
# Client-side
<client>
<features>
http/2
http
</features>
<server>
http
</server>
<name>
Reject HTTP/1.1 to HTTP/2 switch on the same connection
</name>
<command option="no-output">
"http://%HOSTIP:%HTTPPORT/{%TESTNUMBER,%TESTNUMBER0001}" -o "%LOGDIR/dumpit#1.dump"
</command>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol>
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
GET /%TESTNUMBER0001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
# curl: (1) Version mismatch (from HTTP/1 to HTTP/2)
<errorcode>
1
</errorcode>
</verify>
</testcase>