summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/c-hyper.c16
-rw-r--r--lib/http.c68
-rw-r--r--lib/http.h2
3 files changed, 41 insertions, 45 deletions
diff --git a/lib/c-hyper.c b/lib/c-hyper.c
index bc3f82135..7ce958adb 100644
--- a/lib/c-hyper.c
+++ b/lib/c-hyper.c
@@ -299,8 +299,14 @@ static CURLcode status_line(struct Curl_easy *data,
*/
static CURLcode empty_header(struct Curl_easy *data)
{
- return hyper_each_header(data, NULL, 0, NULL, 0) ?
- CURLE_WRITE_ERROR : CURLE_OK;
+ CURLcode result = Curl_http_size(data);
+ if(!result) {
+ result = hyper_each_header(data, NULL, 0, NULL, 0) ?
+ CURLE_WRITE_ERROR : CURLE_OK;
+ if(result)
+ failf(data, "hyperstream: couldn't pass blank header");
+ }
+ return result;
}
CURLcode Curl_hyper_stream(struct Curl_easy *data,
@@ -443,11 +449,9 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
break;
}
- if(empty_header(data)) {
- failf(data, "hyperstream: couldn't pass blank header");
- result = CURLE_OUT_OF_MEMORY;
+ result = empty_header(data);
+ if(result)
break;
- }
/* Curl_http_auth_act() checks what authentication methods that are
* available and decides which one (if any) to use. It will set 'newurl'
diff --git a/lib/http.c b/lib/http.c
index 8f5457adc..4777750ec 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -2903,20 +2903,6 @@ CURLcode Curl_http_firstwrite(struct Curl_easy *data,
{
struct SingleRequest *k = &data->req;
- 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
@@ -3787,6 +3773,29 @@ CURLcode Curl_http_statusline(struct Curl_easy *data,
return CURLE_OK;
}
+/* Content-Length must be ignored if any Transfer-Encoding is present in the
+ response. Refer to RFC 7230 section 3.3.3 and RFC2616 section 4.4. This is
+ figured out here after all headers have been received but before the final
+ call to the user's header callback, so that a valid content length can be
+ retrieved by the user in the final call. */
+CURLcode Curl_http_size(struct Curl_easy *data)
+{
+ struct SingleRequest *k = &data->req;
+ if(data->req.ignore_cl || k->chunk) {
+ k->size = k->maxdownload = -1;
+ }
+ else if(k->size != -1) {
+ 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);
+ k->maxdownload = k->size;
+ }
+ return CURLE_OK;
+}
+
/*
* Read any HTTP header lines from the server and pass them to the client app.
*/
@@ -3981,6 +3990,12 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
}
}
+ if(!k->header) {
+ result = Curl_http_size(data);
+ if(result)
+ return result;
+ }
+
/* At this point we have some idea about the fate of the connection.
If we are closing the connection it may result auth failure. */
#if defined(USE_NTLM)
@@ -4137,31 +4152,6 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
reason */
*stop_reading = TRUE;
#endif
- else {
- /* If we know the expected size of this document, we set the
- maximum download size to the size of the expected
- document or else, we won't know when to stop reading!
-
- Note that we set the download maximum even if we read a
- "Connection: close" header, to make sure that
- "Content-Length: 0" still prevents us from attempting to
- read the (missing) response-body.
- */
- /* According to RFC2616 section 4.4, we MUST ignore
- Content-Length: headers if we are now receiving data
- using chunked Transfer-Encoding.
- */
- if(k->chunk)
- k->maxdownload = k->size = -1;
- }
- if(-1 != k->size) {
- /* We do this operation even if no_body is true, since this
- data might be retrieved later with curl_easy_getinfo()
- and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
-
- Curl_pgrsSetDownloadSize(data, k->size);
- k->maxdownload = k->size;
- }
/* If max download size is *zero* (nothing) we already have
nothing and can safely return ok now! But for HTTP/2, we'd
diff --git a/lib/http.h b/lib/http.h
index e4ab466c0..cb5b56faf 100644
--- a/lib/http.h
+++ b/lib/http.h
@@ -289,6 +289,8 @@ struct http_conn {
#endif
};
+CURLcode Curl_http_size(struct Curl_easy *data);
+
CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
struct connectdata *conn,
ssize_t *nread,