From: Daniel Stenberg Date: Fri, 19 Apr 2024 08:27:04 +0000 (+0200) Subject: http: reject HTTP major version switch mid connection X-Git-Tag: curl-8_8_0~185 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a032e97f2b1070497c0f8c8972bc892e70686838;p=thirdparty%2Fcurl.git 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 --- diff --git a/lib/http.c b/lib/http.c index dbec52158f..9470d2ec62 100644 --- a/lib/http.c +++ b/lib/http.c @@ -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", diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index 1acf48109f..97e0167080 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -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 \ diff --git a/tests/data/test471 b/tests/data/test471 new file mode 100644 index 0000000000..69ecb5e210 --- /dev/null +++ b/tests/data/test471 @@ -0,0 +1,74 @@ + + + +HTTP +HTTP GET +globbing +{} list + + +# +# Server-side + + +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- + + +HTTP/2 200 OK +Content-Type: text/html +Funny-head: swsclose +Connection: close + +crap data + + + +# +# Client-side + + +http/2 +http + + +http + + +Reject HTTP/1.1 to HTTP/2 switch on the same connection + + +"http://%HOSTIP:%HTTPPORT/{%TESTNUMBER,%TESTNUMBER0001}" -o "%LOGDIR/dumpit#1.dump" + + + +# +# Verify data after the test has been "shot" + + +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: */* + + +# curl: (1) Version mismatch (from HTTP/1 to HTTP/2) + +1 + + +