Andrew Biggs pointed out a "Expect: 100-continue" flaw where libcurl didn't
authorDaniel Stenberg <daniel@haxx.se>
Fri, 18 Aug 2006 22:54:57 +0000 (22:54 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 18 Aug 2006 22:54:57 +0000 (22:54 +0000)
send the whole request at once, even though the Expect: header was disabled
by the application. An effect of this change is also that small (< 1024
bytes) POSTs are now always sent without Expect: header since we deem it
more costly to bother about that than the risk that we send the data in
vain.

CHANGES
RELEASE-NOTES
lib/http.c
lib/http.h
tests/data/test508
tests/data/test510
tests/data/test513
tests/data/test515

diff --git a/CHANGES b/CHANGES
index b2c3938..bacba4b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,14 @@
 
                                   Changelog
 
+Daniel (19 August 2006)
+- Andrew Biggs pointed out a "Expect: 100-continue" flaw where libcurl didn't
+  send the whole request at once, even though the Expect: header was disabled
+  by the application. An effect of this change is also that small (< 1024
+  bytes) POSTs are now always sent without Expect: header since we deem it
+  more costly to bother about that than the risk that we send the data in
+  vain.
+
 Daniel (9 August 2006)
 - Armel Asselin made the CURLOPT_PREQUOTE option work fine even when
   CURLOPT_NOBODY is set true. PREQUOTE is then run roughly at the same place
@@ -13,7 +21,7 @@ Daniel (9 August 2006)
   transfer.
 
 Daniel (8 August 2006)
-- Fixed a flaw in the "Expect: 100-continue" treatment. If you did two POSTs
+- Fixed a flaw in the "Expect: 100-continue" treatment. If you did two POSTs
   on a persistent connection and allowed the first to use that header, you
   could not disable it for the second request.
 
index cab9482..1f90ffe 100644 (file)
@@ -29,6 +29,6 @@ New curl mirrors:
 This release would not have looked like this without help, code, reports and
 advice from friends like these:
 
- Domenico Andreoli, Armel Asselin, Gisle Vanem, Yang Tse
+ Domenico Andreoli, Armel Asselin, Gisle Vanem, Yang Tse, Andrew Biggs
 
         Thanks! (and sorry if I forgot to mention someone)
index 310c0a6..4df91be 100644 (file)
@@ -2249,16 +2249,24 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
 
       if(data->set.postfields) {
 
-        if((data->state.authhost.done || data->state.authproxy.done )
-           && (postsize < MAX_INITIAL_POST_SIZE)) {
-          /* If we're not done with the authentication phase, we don't expect
-             to actually send off any data yet. Hence, we delay the sending of
-             the body until we receive that friendly 100-continue response */
+        /* for really small posts we don't use Expect: headers at all, and for
+           the somewhat bigger ones we allow the app to disable it */
+        if(postsize > TINY_INITIAL_POST_SIZE) {
+          result = expect100(data, req_buffer);
+          if(result)
+            return result;
+        }
+        else
+          data->state.expect100header = FALSE;
+
+        if(!data->state.expect100header &&
+           (postsize < MAX_INITIAL_POST_SIZE))  {
+          /* if we don't use expect:-100  AND
+             postsize is less than MAX_INITIAL_POST_SIZE
 
-          /* The post data is less than MAX_INITIAL_PORT_SIZE, then append it
-             to the header. This limit is no magic limit but only set to
-             prevent really huge POSTs to get the data duplicated with
-             malloc() and family. */
+             then append the post data to the HTTP request header. This limit
+             is no magic limit but only set to prevent really huge POSTs to
+             get the data duplicated with malloc() and family. */
 
           result = add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
           if(result)
@@ -2297,18 +2305,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
           /* set the upload size to the progress meter */
           Curl_pgrsSetUploadSize(data, http->postsize);
 
-          result = expect100(data, req_buffer);
-          if(result)
-            return result;
-
           add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
         }
       }
       else {
-        result = expect100(data, req_buffer);
-        if(result)
-          return result;
-
         add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
 
         if(data->set.postfieldsize) {
index e84e28b..1c8ee7e 100644 (file)
@@ -74,7 +74,11 @@ int Curl_http_should_fail(struct connectdata *conn);
    It must not be greater than 64K to work on VMS.
 */
 #ifndef MAX_INITIAL_POST_SIZE
-#define MAX_INITIAL_POST_SIZE 1024
+#define MAX_INITIAL_POST_SIZE (64*1024)
+#endif
+
+#ifndef TINY_INITIAL_POST_SIZE
+#define TINY_INITIAL_POST_SIZE 1024
 #endif
 
 #endif
index 3d3c6c9..9ebbaa9 100644 (file)
@@ -39,7 +39,6 @@ Host: 127.0.0.1:%HTTPPORT
 Accept: */*\r
 Content-Length: 45\r
 Content-Type: application/x-www-form-urlencoded\r
-Expect: 100-continue\r
 \r
 this is what we post to the silly web server
 </protocol>
index 79c2d11..1c883f1 100644 (file)
@@ -39,7 +39,6 @@ Host: 127.0.0.1:%HTTPPORT
 Accept: */*\r
 Transfer-Encoding: chunked\r
 Content-Type: application/x-www-form-urlencoded\r
-Expect: 100-continue\r
 \r
 3\r
 one\r
index 920cbcc..44063bc 100644 (file)
@@ -30,7 +30,6 @@ Host: 127.0.0.1:%HTTPPORT
 Accept: */*\r
 Content-Length: 1\r
 Content-Type: application/x-www-form-urlencoded\r
-Expect: 100-continue\r
 \r
 </protocol>
 # 42 - aborted by callback
index f6be8c4..566da84 100644 (file)
@@ -40,7 +40,6 @@ Host: 127.0.0.1:%HTTPPORT
 Accept: */*\r
 Content-Length: 0\r
 Content-Type: application/x-www-form-urlencoded\r
-Expect: 100-continue\r
 \r
 </protocol>
 </verify>