4.16 My HTTP POST or PUT requests are slow
- libcurl makes all POST and PUT requests (except for POST requests with a
- tiny request body) use the "Expect: 100-continue" header. This header
- allows the server to deny the operation early so that libcurl can bail out
- before having to send any data. This is useful in authentication
- cases and others.
+ libcurl makes all POST and PUT requests (except for requests with a small
+ request body) use the "Expect: 100-continue" header. This header allows the
+ server to deny the operation early so that libcurl can bail out before having
+ to send any data. This is useful in authentication cases and others.
However, many servers do not implement the Expect: stuff properly and if the
server does not respond (positively) within 1 second libcurl will continue
return result;
}
- if(http->postsize) {
+ /* For really small puts we don't use Expect: headers at all, and for
+ the somewhat bigger ones we allow the app to disable it. Just make
+ sure that the expect100header is always set to the preferred value
+ here. */
+ ptr = Curl_checkheaders(data, STRCONST("Expect"));
+ if(ptr) {
+ data->state.expect100header =
+ Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue"));
+ }
+ else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0) {
result = expect100(data, conn, r);
if(result)
return result;
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 78\r
-Expect: 100-continue\r
\r
Weird
file
Accept: */*\r
Proxy-Connection: Keep-Alive\r
Content-Length: 3\r
-Expect: 100-continue\r
\r
st
</protocol>
Accept: */*\r
Proxy-Connection: Keep-Alive\r
Content-Length: 3\r
-Expect: 100-continue\r
\r
st
GET http://%HOSTIP:%HTTPPORT/%TESTNUMBER.upload2 HTTP/1.1\r
Accept: */*\r
Proxy-Connection: Keep-Alive\r
Content-Length: 3\r
-Expect: 100-continue\r
\r
st
</protocol>
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 85\r
-Expect: 100-continue\r
\r
This is data we upload with PUT
a second line
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 85\r
-Expect: 100-continue\r
\r
This is data we upload with PUT
a second line
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 100\r
-Expect: 100-continue\r
\r
012345678
012345678
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 78\r
-Expect: 100-continue\r
\r
Weird
file
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 78\r
-Expect: 100-continue\r
\r
Weird
file
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 78\r
-Expect: 100-continue\r
\r
Weird
file
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 85\r
-Expect: 100-continue\r
\r
This is data we upload with PUT
a second line
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 85\r
-Expect: 100-continue\r
\r
This is data we upload with PUT
a second line
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 85\r
-Expect: 100-continue\r
\r
This is data we upload with PUT
a second line
HTTP PUT expect 100-continue with a 400
</name>
<command option="no-output">
--T log/file%TESTNUMBER http://%HOSTIP:%HTTPPORT/%TESTNUMBER -T log/file%TESTNUMBER http://%HOSTIP:%HTTPPORT/%TESTNUMBER0001
+-H "Expect: 100-continue" -T log/file%TESTNUMBER http://%HOSTIP:%HTTPPORT/%TESTNUMBER -T log/file%TESTNUMBER http://%HOSTIP:%HTTPPORT/%TESTNUMBER0001
</command>
</client>
Host: %HOSTIP:%HTTPPORT\r
User-Agent: curl/%VERSION\r
Accept: */*\r
-Content-Length: 100\r
Expect: 100-continue\r
+Content-Length: 100\r
\r
PUT /%TESTNUMBER0001 HTTP/1.1\r
Host: %HOSTIP:%HTTPPORT\r
User-Agent: curl/%VERSION\r
Accept: */*\r
-Content-Length: 100\r
Expect: 100-continue\r
+Content-Length: 100\r
\r
</protocol>
</verify>
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 85\r
-Expect: 100-continue\r
\r
This is data we upload with PUT
a second line
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 4\r
-Expect: 100-continue\r
\r
moo
GET /blah/moo.html&testcase=/%TESTNUMBER0002 HTTP/1.1\r
Accept: */*\r
User-Agent: Http Agent\r
Content-Length: 13\r
-Expect: 100-continue\r
\r
Hello Cloud!
</protocol>
Accept: */*\r
User-Agent: Http Agent\r
Content-Length: 13\r
-Expect: 100-continue\r
\r
Hello Cloud!
</protocol>
# Server-side
<reply>
-<servercmd>
-auth_required
-</servercmd>
<data>
HTTP/1.1 401 Authorization Required swsclose\r
Server: Apache/1.3.27 (Darwin) PHP/4.1.2\r
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 85\r
-Expect: 100-continue\r
\r
+This is data we upload with PUT
+a second line
+line three
+four is the number of lines
PUT /%TESTNUMBER HTTP/1.1\r
Host: %HOSTIP:%HTTPPORT\r
Authorization: Digest username="testuser", realm="gimme all yer s3cr3ts", nonce="11223344", uri="/%TESTNUMBER", response="b71551e12d1c456e47d8388ecb2edeca"\r
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 85\r
-Expect: 100-continue\r
\r
This is data we upload with PUT
a second line
# Server-side
<reply>
-<servercmd>
-auth_required
-</servercmd>
<data>
HTTP/1.1 401 NTLM Authorization Required swsclose\r
Server: Apache/1.3.27 (Darwin) PHP/4.1.2\r
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 85\r
-Expect: 100-continue\r
\r
+This is data we upload with PUT
+a second line
+line three
+four is the number of lines
PUT /%TESTNUMBER HTTP/1.1\r
Host: %HOSTIP:%HTTPPORT\r
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=\r
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 85\r
-Expect: 100-continue\r
\r
This is data we upload with PUT
a second line
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 85\r
-Expect: 100-continue\r
\r
This is data we upload with PUT
a second line
Host: %HOSTIP:%HTTPPORT\r
Accept: */*\r
Content-Length: 22\r
-Expect: 100-continue\r
\r
This is test PUT data
POST /1948 HTTP/1.1\r
Accept: */*\r
Proxy-Connection: Keep-Alive\r
Content-Length: 3\r
-Expect: 100-continue\r
\r
st
</protocol>
Accept: */*\r
Proxy-Connection: Keep-Alive\r
Content-Length: 3\r
-Expect: 100-continue\r
\r
st
</protocol>
Accept: */*\r
Proxy-Connection: Keep-Alive\r
Content-Length: 3\r
-Expect: 100-continue\r
\r
st
</protocol>
Accept: */*\r
Proxy-Connection: Keep-Alive\r
Content-Length: 78\r
-Expect: 100-continue\r
\r
Weird
file
User-Agent: curl/%VERSION\r
Accept: */*\r
Transfer-Encoding: chunked\r
-Expect: 100-continue\r
\r
%if hyper
1E\r
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 38\r
-Expect: 100-continue\r
\r
Weird
file
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 50\r
-Expect: 100-continue\r
\r
012345678
012345678
<command>
http://%HOSTIP:%HTTPPORT/we/want/%TESTNUMBER -T log/test%TESTNUMBER.txt
</command>
+# 1053700 x 'x', large enough to invoke the 100-continue behaviour
<file name="log/test%TESTNUMBER.txt">
-Weird
- file
- to
- upload
-for
- testing
-the
- PUT
- feature
+%repeat[1053700 x x]%
</file>
</client>
Host: %HOSTIP:%HTTPPORT\r
User-Agent: curl/%VERSION\r
Accept: */*\r
-Content-Length: 78\r
+Content-Length: 1053701\r
Expect: 100-continue\r
\r
PUT /we/want/%TESTNUMBER HTTP/1.1\r
Host: %HOSTIP:%HTTPPORT\r
User-Agent: curl/%VERSION\r
Accept: */*\r
-Content-Length: 78\r
+Content-Length: 1053701\r
\r
-Weird
- file
- to
- upload
-for
- testing
-the
- PUT
- feature
+%repeat[1053700 x x]%
</protocol>
</verify>
</testcase>
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 1201\r
-Expect: 100-continue\r
\r
%repeat[200 x banana]%
</protocol>
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 10\r
-Expect: 100-continue\r
\r
surprise!
PUT /%TESTNUMBER HTTP/1.1\r
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 10\r
-Expect: 100-continue\r
\r
surprise!
</protocol>
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 10\r
-Expect: 100-continue\r
\r
surprise!
</protocol>
Accept: */*\r
Testno: %TESTNUMBER\r
Content-Length: 19\r
-Expect: 100-continue\r
\r
first %TESTNUMBER contents
PUT /two/first%TESTNUMBER HTTP/1.1\r
Accept: */*\r
Testno: %TESTNUMBER\r
Content-Length: 19\r
-Expect: 100-continue\r
\r
first %TESTNUMBER contents
PUT /one/second%TESTNUMBER HTTP/1.1\r
Accept: */*\r
Testno: %TESTNUMBER\r
Content-Length: 20\r
-Expect: 100-continue\r
\r
second %TESTNUMBER contents
PUT /two/second%TESTNUMBER HTTP/1.1\r
Accept: */*\r
Testno: %TESTNUMBER\r
Content-Length: 20\r
-Expect: 100-continue\r
\r
second %TESTNUMBER contents
</protocol>
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 12\r
-Expect: 100-continue\r
\r
a few bytes
</protocol>
User-Agent: curl/%VERSION\r
Accept: */*\r
Content-Length: 85\r
-Expect: 100-continue\r
\r
This is data we upload with PUT
a second line