summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2021-08-30 17:49:25 +0200
committerDaniel Stenberg <daniel@haxx.se>2021-08-31 10:04:03 +0200
commit8a16e54c0cc71e15ef78d9eaf1f9155a0204202d (patch)
treeb80a5c3e75caae769b2a9c0a5eeaeb32f0c4bcc2 /lib
parentbde355c484a652fece6438e6c5b71830c08c2300 (diff)
downloadcurl-8a16e54c0cc71e15ef78d9eaf1f9155a0204202d.tar.gz
http: ignore content-length if any transfer-encoding is used
Fixes #7643 Closes #7649
Diffstat (limited to 'lib')
-rw-r--r--lib/c-hyper.c5
-rw-r--r--lib/http.c29
-rw-r--r--lib/urldata.h11
3 files changed, 31 insertions, 14 deletions
diff --git a/lib/c-hyper.c b/lib/c-hyper.c
index c43d9e327..26635cdc1 100644
--- a/lib/c-hyper.c
+++ b/lib/c-hyper.c
@@ -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) {
diff --git a/lib/http.c b/lib/http.c
index 65750d17d..d5c36dd54 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -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]) {
diff --git a/lib/urldata.h b/lib/urldata.h
index 1d9911208..6ffd97621 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -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 */