http: ignore content-length if any transfer-encoding is used

Fixes #7643
Closes #7649
This commit is contained in:
Daniel Stenberg 2021-08-30 17:49:25 +02:00
parent bde355c484
commit 8a16e54c0c
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
10 changed files with 80 additions and 71 deletions

View file

@ -400,6 +400,11 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
/* end of transfer */
*done = TRUE;
infof(data, "hyperstream is done!");
if(!k->bodywrites) {
/* hyper doesn't always call the body write callback */
bool stilldone;
result = Curl_http_firstwrite(data, data->conn, &stilldone);
}
break;
}
else if(t != HYPER_TASK_RESPONSE) {

View file

@ -2903,6 +2903,20 @@ CURLcode Curl_http_firstwrite(struct Curl_easy *data,
{
struct SingleRequest *k = &data->req;
DEBUGASSERT(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP));
if(data->req.ignore_cl) {
k->size = k->maxdownload = -1;
}
else if(k->size != -1) {
/* We wait until after all headers have been received to set this so that
we know for sure Content-Length is valid. */
if(data->set.max_filesize &&
k->size > data->set.max_filesize) {
failf(data, "Maximum file size exceeded");
return CURLE_FILESIZE_EXCEEDED;
}
Curl_pgrsSetDownloadSize(data, k->size);
}
if(data->req.newurl) {
if(conn->bits.close) {
/* Abort after the headers if "follow Location" is set
@ -3403,17 +3417,8 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
NULL, 10, &contentlength);
if(offt == CURL_OFFT_OK) {
if(data->set.max_filesize &&
contentlength > data->set.max_filesize) {
failf(data, "Maximum file size exceeded");
return CURLE_FILESIZE_EXCEEDED;
}
k->size = contentlength;
k->maxdownload = k->size;
/* we set the progress download size already at this point
just to make it easier for apps/callbacks to extract this
info as soon as possible */
Curl_pgrsSetDownloadSize(data, k->size);
}
else if(offt == CURL_OFFT_FLOW) {
/* out of range */
@ -3504,6 +3509,12 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
TRUE);
if(result)
return result;
if(!k->chunk) {
/* if this isn't chunked, only close can signal the end of this transfer
as Content-Length is said not to be trusted for transfer-encoding! */
connclose(conn, "HTTP/1.1 transfer-encoding without chunks");
k->ignore_cl = TRUE;
}
}
else if(!k->http_bodyless && checkprefix("Content-Encoding:", headp) &&
data->set.str[STRING_ENCODING]) {

View file

@ -704,14 +704,15 @@ struct SingleRequest {
#ifndef CURL_DISABLE_DOH
struct dohdata *doh; /* DoH specific data for this request */
#endif
BIT(header); /* incoming data has HTTP header */
BIT(header); /* incoming data has HTTP header */
BIT(content_range); /* set TRUE if Content-Range: was found */
BIT(upload_done); /* set to TRUE when doing chunked transfer-encoding
upload and we're uploading the last chunk */
BIT(ignorebody); /* we read a response-body but we ignore it! */
BIT(upload_done); /* set to TRUE when doing chunked transfer-encoding
upload and we're uploading the last chunk */
BIT(ignorebody); /* we read a response-body but we ignore it! */
BIT(http_bodyless); /* HTTP response status code is between 100 and 199,
204 or 304 */
BIT(chunk); /* if set, this is a chunked transfer-encoding */
BIT(chunk); /* if set, this is a chunked transfer-encoding */
BIT(ignore_cl); /* ignore content-length */
BIT(upload_chunky); /* set TRUE if we are doing chunked transfer-encoding
on upload */
BIT(getheader); /* TRUE if header parsing is wanted */