diff --git a/CHANGES b/CHANGES index b2c3938582c4a2b4b437b1372474818995a157fd..bacba4bd8bcb68ce5fc9e093556966e73aec9032 100644 --- 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. diff --git a/RELEASE-NOTES b/RELEASE-NOTES index cab94828a2e31e061c9d1279d71f6e99c26ce564..1f90ffe89e040c2067f6363bc325e56092236a81 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -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) diff --git a/lib/http.c b/lib/http.c index 310c0a6177dc42d485a30c06eed4320577399e9c..4df91be0a3af8dfc958e3bc201392208b07fd95e 100644 --- a/lib/http.c +++ b/lib/http.c @@ -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) { diff --git a/lib/http.h b/lib/http.h index e84e28b07516fac0689c64ecea6a995c15801cb3..1c8ee7e3905be865b755cb61b4af7aca5d297a44 100644 --- a/lib/http.h +++ b/lib/http.h @@ -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 diff --git a/tests/data/test508 b/tests/data/test508 index 3d3c6c9e07382c29a2472ffe8f4c36c38bd9b0a4..9ebbaa92ac7394a2cc508e9b9ea52f5a18de36b5 100644 --- a/tests/data/test508 +++ b/tests/data/test508 @@ -39,7 +39,6 @@ Host: 127.0.0.1:%HTTPPORT Accept: */* Content-Length: 45 Content-Type: application/x-www-form-urlencoded -Expect: 100-continue this is what we post to the silly web server </protocol> diff --git a/tests/data/test510 b/tests/data/test510 index 79c2d11a645a0c8e0a1b12d80bf5b4d4dea57a25..1c883f18d17cbea4f48cab338805eb6f9cff6d51 100644 --- a/tests/data/test510 +++ b/tests/data/test510 @@ -39,7 +39,6 @@ Host: 127.0.0.1:%HTTPPORT Accept: */* Transfer-Encoding: chunked Content-Type: application/x-www-form-urlencoded -Expect: 100-continue 3 one diff --git a/tests/data/test513 b/tests/data/test513 index 920cbcc17738dceeecd667982423fa40c3f15d1b..44063bc1885048a78ab9e707763d6054d36a5665 100644 --- a/tests/data/test513 +++ b/tests/data/test513 @@ -30,7 +30,6 @@ Host: 127.0.0.1:%HTTPPORT Accept: */* Content-Length: 1 Content-Type: application/x-www-form-urlencoded -Expect: 100-continue </protocol> # 42 - aborted by callback diff --git a/tests/data/test515 b/tests/data/test515 index f6be8c42c0bfc219ecd1440427dc381d1e52ff58..566da84f402c2a3266779e4c69bb754ae0d1ce10 100644 --- a/tests/data/test515 +++ b/tests/data/test515 @@ -40,7 +40,6 @@ Host: 127.0.0.1:%HTTPPORT Accept: */* Content-Length: 0 Content-Type: application/x-www-form-urlencoded -Expect: 100-continue </protocol> </verify>