mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
http error response: stop sending when error is received
When libcurl has said to the server that there's a POST or PUT coming (with a content-length and all) it has to either deliver that amount of data or it needs to close the connection before trying a second request. Adds test case 1129, 1130 and 1131 The bug report is about when used with 100-continue, but the change is more generic. Bug: http://curl.haxx.se/mail/lib-2011-06/0191.html Reported by: Steven Parkes
This commit is contained in:
parent
d007c3ca76
commit
3f9b4afdfd
67
lib/http.c
67
lib/http.c
@ -404,8 +404,10 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
|||||||
data left to send, keep on sending. */
|
data left to send, keep on sending. */
|
||||||
|
|
||||||
/* rewind data when completely done sending! */
|
/* rewind data when completely done sending! */
|
||||||
if(!conn->bits.authneg)
|
if(!conn->bits.authneg) {
|
||||||
conn->bits.rewindaftersend = TRUE;
|
conn->bits.rewindaftersend = TRUE;
|
||||||
|
infof(data, "Rewind stream after send\n");
|
||||||
|
}
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
@ -1683,6 +1685,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
if(!data->state.first_host)
|
if(!data->state.first_host)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
http->writebytecount = http->readbytecount = 0;
|
||||||
|
|
||||||
if((conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_FTP)) &&
|
if((conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_FTP)) &&
|
||||||
data->set.upload) {
|
data->set.upload) {
|
||||||
@ -2543,6 +2546,17 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
Curl_pgrsSetUploadCounter(data, http->writebytecount);
|
Curl_pgrsSetUploadCounter(data, http->writebytecount);
|
||||||
if(Curl_pgrsUpdate(conn))
|
if(Curl_pgrsUpdate(conn))
|
||||||
result = CURLE_ABORTED_BY_CALLBACK;
|
result = CURLE_ABORTED_BY_CALLBACK;
|
||||||
|
|
||||||
|
if(http->writebytecount >= postsize) {
|
||||||
|
/* already sent the entire request body, mark the "upload" as
|
||||||
|
complete */
|
||||||
|
infof(data, "upload completely sent off: %" FORMAT_OFF_T "out of "
|
||||||
|
"%" FORMAT_OFF_T " bytes\n",
|
||||||
|
http->writebytecount, postsize);
|
||||||
|
data->req.upload_done = TRUE;
|
||||||
|
data->req.keepon &= ~KEEP_SEND; /* we're done writing */
|
||||||
|
data->req.exp100 = EXP100_SEND_DATA; /* already sent */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -2814,17 +2828,6 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(417 == k->httpcode) {
|
|
||||||
/*
|
|
||||||
* we got: "417 Expectation Failed" this means:
|
|
||||||
* we have made a HTTP call and our Expect Header
|
|
||||||
* seems to cause a problem => abort the write operations
|
|
||||||
* (or prevent them from starting).
|
|
||||||
*/
|
|
||||||
k->exp100 = EXP100_FAILED;
|
|
||||||
k->keepon &= ~KEEP_SEND;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When all the headers have been parsed, see if we should give
|
* When all the headers have been parsed, see if we should give
|
||||||
* up and return an error.
|
* up and return an error.
|
||||||
@ -2864,6 +2867,46 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
|||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
if(k->httpcode >= 300) {
|
||||||
|
if((!conn->bits.authneg) && !conn->bits.close &&
|
||||||
|
!conn->bits.rewindaftersend) {
|
||||||
|
/*
|
||||||
|
* General treatment of errors when about to send data. Including :
|
||||||
|
* "417 Expectation Failed", while waiting for 100-continue.
|
||||||
|
*
|
||||||
|
* The check for close above is done simply because of something
|
||||||
|
* else has already deemed the connection to get closed then
|
||||||
|
* something else should've considered the big picture and we
|
||||||
|
* avoid this check.
|
||||||
|
*
|
||||||
|
* rewindaftersend indicates that something has told libcurl to
|
||||||
|
* continue sending even if it gets discarded
|
||||||
|
*/
|
||||||
|
|
||||||
|
switch(data->set.httpreq) {
|
||||||
|
case HTTPREQ_PUT:
|
||||||
|
case HTTPREQ_POST:
|
||||||
|
case HTTPREQ_POST_FORM:
|
||||||
|
/* We got an error response. If this happened before the whole
|
||||||
|
* request body has been sent we stop sending and mark the
|
||||||
|
* connection for closure after we've read the entire response.
|
||||||
|
*/
|
||||||
|
if(!k->upload_done) {
|
||||||
|
infof(data, "HTTP error before end of send, stop sending\n");
|
||||||
|
conn->bits.close = TRUE; /* close after this */
|
||||||
|
k->upload_done = TRUE;
|
||||||
|
k->keepon &= ~KEEP_SEND; /* don't send */
|
||||||
|
if(data->state.expect100header)
|
||||||
|
k->exp100 = EXP100_FAILED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* default label present to avoid compiler warnings */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(conn->bits.rewindaftersend) {
|
if(conn->bits.rewindaftersend) {
|
||||||
/* We rewind after a complete send, so thus we continue
|
/* We rewind after a complete send, so thus we continue
|
||||||
sending now */
|
sending now */
|
||||||
|
@ -1043,6 +1043,12 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
if(result || *done)
|
if(result || *done)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
else if(k->keepon & KEEP_RECV) {
|
||||||
|
DEBUGF(infof(data, "additional stuff not fine %s:%d: %d %d\n",
|
||||||
|
__FILE__, __LINE__,
|
||||||
|
select_res & CURL_CSELECT_IN,
|
||||||
|
conn->bits.stream_was_rewound));
|
||||||
|
}
|
||||||
|
|
||||||
/* If we still have writing to do, we check if we have a writable socket. */
|
/* If we still have writing to do, we check if we have a writable socket. */
|
||||||
if((k->keepon & KEEP_SEND) && (select_res & CURL_CSELECT_OUT)) {
|
if((k->keepon & KEEP_SEND) && (select_res & CURL_CSELECT_OUT)) {
|
||||||
|
@ -71,9 +71,10 @@ test1094 test1095 test1096 test1097 test1098 test1099 test1100 test1101 \
|
|||||||
test1102 test1103 test1104 test1105 test1106 test1107 test1108 test1109 \
|
test1102 test1103 test1104 test1105 test1106 test1107 test1108 test1109 \
|
||||||
test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 \
|
test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 \
|
||||||
test1118 test1119 test1120 test1121 test1122 test1123 test1124 test1125 \
|
test1118 test1119 test1120 test1121 test1122 test1123 test1124 test1125 \
|
||||||
test1126 test1127 test1128 test1200 test1201 test1202 test1203 test1300 \
|
test1126 test1127 test1128 test1129 test1130 test1131 test1200 test1201 \
|
||||||
test1301 test1302 test1303 test1304 test1305 test1306 test1307 test1308 \
|
test1202 test1203 test1300 test1301 test1302 test1303 test1304 test1305 \
|
||||||
test1309 test2000 test2001 test2002 test2003 test2004 test2005
|
test1306 test1307 test1308 test1309 test2000 test2001 test2002 test2003 \
|
||||||
|
test2004 test2005
|
||||||
|
|
||||||
EXTRA_DIST = $(TESTCASES) DISABLED
|
EXTRA_DIST = $(TESTCASES) DISABLED
|
||||||
|
|
||||||
|
97
tests/data/test1129
Normal file
97
tests/data/test1129
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
HTTP
|
||||||
|
HTTP POST
|
||||||
|
Expect: 100-continue
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data nocheck="yes">
|
||||||
|
HTTP/1.1 404 NOOOOOOOOO
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Content-Length: 6
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<data1>
|
||||||
|
HTTP/1.1 404 NEITHER
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Content-Length: 6
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data1>
|
||||||
|
|
||||||
|
# we use skip to make the test server never read the full payload off
|
||||||
|
# the socket and instead return the response at once
|
||||||
|
<servercmd>
|
||||||
|
skip: 1025
|
||||||
|
</servercmd>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
# 1025 x 'x'
|
||||||
|
<file name="log/file1129">
|
||||||
|
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||||
|
</file>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<name>
|
||||||
|
HTTP POST expect 100-continue with a 404
|
||||||
|
</name>
|
||||||
|
<command option="no-output">
|
||||||
|
-d @log/file1129 http://%HOSTIP:%HTTPPORT/1129 http://%HOSTIP:%HTTPPORT/11290001
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<stdout>
|
||||||
|
HTTP/1.1 404 NOOOOOOOOO
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Content-Length: 6
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
HTTP/1.1 404 NEITHER
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Content-Length: 6
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</stdout>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
POST /1129 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 1025
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
Expect: 100-continue
|
||||||
|
|
||||||
|
POST /11290001 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 1025
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
Expect: 100-continue
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
97
tests/data/test1130
Normal file
97
tests/data/test1130
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
HTTP
|
||||||
|
HTTP POST
|
||||||
|
Expect: 100-continue
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data nocheck="yes">
|
||||||
|
HTTP/1.1 404 NOOOOOOOOO
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Content-Length: 6
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<data1>
|
||||||
|
HTTP/1.1 404 NEITHER
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Content-Length: 6
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data1>
|
||||||
|
|
||||||
|
# we use skip to make the test server never read the full payload off
|
||||||
|
# the socket and instead return the response at once
|
||||||
|
<servercmd>
|
||||||
|
skip: 100
|
||||||
|
</servercmd>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
# 100 x 'x'
|
||||||
|
<file name="log/file1130">
|
||||||
|
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||||
|
</file>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<name>
|
||||||
|
HTTP POST forced expect 100-continue with a 404
|
||||||
|
</name>
|
||||||
|
<command option="no-output">
|
||||||
|
-d @log/file1130 http://%HOSTIP:%HTTPPORT/1130 http://%HOSTIP:%HTTPPORT/11300001 -H "Expect: 100-continue"
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<stdout>
|
||||||
|
HTTP/1.1 404 NOOOOOOOOO
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Content-Length: 6
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
HTTP/1.1 404 NEITHER
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Content-Length: 6
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</stdout>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
POST /1130 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Expect: 100-continue
|
||||||
|
Content-Length: 100
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
POST /11300001 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Expect: 100-continue
|
||||||
|
Content-Length: 100
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
95
tests/data/test1131
Normal file
95
tests/data/test1131
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
HTTP
|
||||||
|
HTTP PUT
|
||||||
|
Expect: 100-continue
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data nocheck="yes">
|
||||||
|
HTTP/1.1 400 NOOOOOOOOO
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Content-Length: 9
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
FAILURE1
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<data1>
|
||||||
|
HTTP/1.1 400 NEITHER
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Content-Length: 9
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
FAILURE2
|
||||||
|
</data1>
|
||||||
|
|
||||||
|
# we use skip to make the test server never read the full payload off
|
||||||
|
# the socket and instead return the response at once
|
||||||
|
<servercmd>
|
||||||
|
skip: 100
|
||||||
|
</servercmd>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
# 100 x 'x'
|
||||||
|
<file name="log/file1131">
|
||||||
|
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||||
|
</file>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<name>
|
||||||
|
HTTP PUT expect 100-continue with a 400
|
||||||
|
</name>
|
||||||
|
<command option="no-output">
|
||||||
|
-T log/file1131 http://%HOSTIP:%HTTPPORT/1131 -T log/file1131 http://%HOSTIP:%HTTPPORT/11310001
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<stdout>
|
||||||
|
HTTP/1.1 400 NOOOOOOOOO
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Content-Length: 9
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
FAILURE1
|
||||||
|
HTTP/1.1 400 NEITHER
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Content-Length: 9
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
FAILURE2
|
||||||
|
</stdout>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
PUT /1131 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 100
|
||||||
|
Expect: 100-continue
|
||||||
|
|
||||||
|
PUT /11310001 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 100
|
||||||
|
Expect: 100-continue
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
Loading…
Reference in New Issue
Block a user