diff --git a/lib/http.c b/lib/http.c
index aea19d5167..6b1538a737 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -519,6 +519,7 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data,
/* We decided to abort the ongoing transfer */
streamclose(conn, "Mid-auth HTTP and much data left to send");
data->req.size = 0; /* do not download any more than 0 bytes */
+ data->req.http_bodyless = TRUE;
}
return CURLE_OK;
}
@@ -3118,32 +3119,50 @@ static CURLcode http_header_c(struct Curl_easy *data,
struct SingleRequest *k = &data->req;
const char *v;
- /* Check for Content-Length: header lines to get size */
+ /* Check for Content-Length: header lines to get size. Browsers insist we
+ should accept multiple Content-Length headers and that a comma separated
+ list also is fine and then we should accept them all as long as they are
+ the same value. Different values trigger error.
+ */
v = (!k->http_bodyless && !data->set.ignorecl) ?
HD_VAL(hd, hdlen, "Content-Length:") : NULL;
if(v) {
- curl_off_t contentlength;
- int offt = curlx_str_numblanks(&v, &contentlength);
+ do {
+ curl_off_t contentlength;
+ int offt = curlx_str_numblanks(&v, &contentlength);
- if(offt == STRE_OK) {
- k->size = contentlength;
- k->maxdownload = k->size;
- }
- else if(offt == STRE_OVERFLOW) {
- /* out of range */
- if(data->set.max_filesize) {
- failf(data, "Maximum file size exceeded");
- return CURLE_FILESIZE_EXCEEDED;
+ if(offt == STRE_OVERFLOW) {
+ /* out of range */
+ if(data->set.max_filesize) {
+ failf(data, "Maximum file size exceeded");
+ return CURLE_FILESIZE_EXCEEDED;
+ }
+ streamclose(conn, "overflow content-length");
+ infof(data, "Overflow Content-Length: value");
+ return CURLE_OK;
}
- streamclose(conn, "overflow content-length");
- infof(data, "Overflow Content-Length: value");
- }
- else {
- /* negative or just rubbish - bad HTTP */
- failf(data, "Invalid Content-Length: value");
- return CURLE_WEIRD_SERVER_REPLY;
- }
- return CURLE_OK;
+ else {
+ if((offt == STRE_OK) &&
+ ((k->size == -1) || /* not set to something before */
+ (k->size == contentlength))) { /* or the same value */
+
+ k->size = contentlength;
+ curlx_str_passblanks(&v);
+
+ /* on a comma, loop and get the next instead */
+ if(!curlx_str_single(&v, ','))
+ continue;
+
+ if(!curlx_str_newline(&v)) {
+ k->maxdownload = k->size;
+ return CURLE_OK;
+ }
+ }
+ /* negative, different value or just rubbish - bad HTTP */
+ failf(data, "Invalid Content-Length: value");
+ return CURLE_WEIRD_SERVER_REPLY;
+ }
+ } while(1);
}
v = (!k->http_bodyless && data->set.str[STRING_ENCODING]) ?
HD_VAL(hd, hdlen, "Content-Encoding:") : NULL;
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 0d2d47c99a..11d9fb7cff 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -109,7 +109,7 @@ test727 test728 test729 test730 test731 test732 test733 test734 test735 \
test736 test737 test738 test739 test740 test741 test742 test743 test744 \
test745 test746 test747 test748 test749 test750 test751 test752 test753 \
test754 test755 test756 test757 test758 test759 test760 test761 test762 \
-test763 test764 test765 test766 \
+test763 test764 test765 test766 test767 test768 test769 test770 test771 \
\
test780 test781 test782 test783 test784 test785 test786 test787 test788 \
test789 test790 test791 test792 test793 test794 test796 test797 \
diff --git a/tests/data/test767 b/tests/data/test767
new file mode 100644
index 0000000000..0927be4f1b
--- /dev/null
+++ b/tests/data/test767
@@ -0,0 +1,58 @@
+
+
+
+HTTP
+HTTP GET
+
+
+
+#
+# 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-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+
+
+
+#
+# Client-side
+
+
+http
+
+
+HTTP with two Content-Length response header fields same size
+
+
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+
+
+
+#
+# Verify data after the test has been "shot"
+
+
+GET /%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+
+
+Allocations: 135
+Maximum allocated: 136000
+
+
+
diff --git a/tests/data/test768 b/tests/data/test768
new file mode 100644
index 0000000000..ced4353c30
--- /dev/null
+++ b/tests/data/test768
@@ -0,0 +1,57 @@
+
+
+
+HTTP
+HTTP GET
+
+
+
+#
+# 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: 6badness
+Content-Length: 44
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+
+
+
+#
+# Client-side
+
+
+http
+
+
+HTTP with letters after the number in Content-Length
+
+
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+
+
+
+#
+# Verify data after the test has been "shot"
+
+
+GET /%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+
+
+8
+
+
+
diff --git a/tests/data/test769 b/tests/data/test769
new file mode 100644
index 0000000000..773d741e3f
--- /dev/null
+++ b/tests/data/test769
@@ -0,0 +1,53 @@
+
+
+
+HTTP
+HTTP GET
+
+
+
+#
+# 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
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+
+
+
+#
+# Client-side
+
+
+http
+
+
+HTTP with space after Content-Length number
+
+
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+
+
+
+#
+# Verify data after the test has been "shot"
+
+
+GET /%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+
+
+
diff --git a/tests/data/test770 b/tests/data/test770
new file mode 100644
index 0000000000..98e3850c4c
--- /dev/null
+++ b/tests/data/test770
@@ -0,0 +1,58 @@
+
+
+
+HTTP
+HTTP GET
+
+
+
+#
+# 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,06,6
+Content-Length: 6, 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+
+
+
+#
+# Client-side
+
+
+http
+
+
+HTTP with Content-Length headers using comma separated list
+
+
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+
+
+
+#
+# Verify data after the test has been "shot"
+
+
+GET /%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+
+
+Allocations: 135
+Maximum allocated: 136000
+
+
+
diff --git a/tests/data/test771 b/tests/data/test771
new file mode 100644
index 0000000000..b57c87c88b
--- /dev/null
+++ b/tests/data/test771
@@ -0,0 +1,57 @@
+
+
+
+HTTP
+HTTP GET
+
+
+
+#
+# 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: 44
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+
+
+
+#
+# Client-side
+
+
+http
+
+
+HTTP with two Content-Length headers using different sizes
+
+
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+
+
+
+#
+# Verify data after the test has been "shot"
+
+
+GET /%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+
+
+8
+
+
+