aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2008-08-29 10:47:59 +0000
committerDaniel Stenberg <daniel@haxx.se>2008-08-29 10:47:59 +0000
commitc67a99ff27036c824be15f01e21b91c3ec08da4a (patch)
treec2d84c831212e7b4f026764abadfa10b2312cf6e /tests
parentbae4e12302e783af59ad40cef3fb72c42a3bef17 (diff)
- When libcurl was doing a HTTP POST and the server would respond with
"Connection: close" and actually close the connection after the response-body, libcurl could still have outstanding data to send and it would not properly notice this and stop sending. This caused weirdness and sad faces. http://curl.haxx.se/bug/view.cgi?id=2080222 Note that there are still reasons to consider libcurl's behavior when getting a >= 400 response code while sending data, as Craig Perras' note "http upload: how to stop on error" specifies: http://curl.haxx.se/mail/archive-2008-08/0138.html
Diffstat (limited to 'tests')
-rw-r--r--tests/FILEFORMAT10
-rw-r--r--tests/data/test107065
-rw-r--r--tests/server/sws.c36
3 files changed, 100 insertions, 11 deletions
diff --git a/tests/FILEFORMAT b/tests/FILEFORMAT
index 555cee52d..e4be47ab4 100644
--- a/tests/FILEFORMAT
+++ b/tests/FILEFORMAT
@@ -113,12 +113,14 @@ PASVBADIP
- makes PASV send back an illegal IP in its 227 response
For HTTP/HTTPS:
-auth_required - if this is set and a POST/PUT is made without auth, the
+auth_required if this is set and a POST/PUT is made without auth, the
server will NOT wait for the full request body to get sent
-idle - do nothing after receiving the request, just "sit idle"
-stream - continuously send data to the client, never-ending
-pipe: [num] - tell the server to expect this many HTTP requests before
+idle do nothing after receiving the request, just "sit idle"
+stream continuously send data to the client, never-ending
+pipe: [num] tell the server to expect this many HTTP requests before
sending back anything, to allow pipelining tests
+skip: [num] instructs the server to ignore reading this many bytes from a PUT
+ or POST request
</servercmd>
</reply>
diff --git a/tests/data/test1070 b/tests/data/test1070
new file mode 100644
index 000000000..715e4a08d
--- /dev/null
+++ b/tests/data/test1070
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 403 Go away and swsclose
+Server: test-server/fake
+Content-Type: text/html
+Content-Length: 55
+Connection: close
+
+you are not supposed to be allowed to send things here
+</data>
+<servercmd>
+skip: 2300
+</servercmd>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP POST with server sending error before (all) data is received
+ </name>
+ <command>
+ -d @log/input1070 http://%HOSTIP:%HTTPPORT/1070
+</command>
+<file name="log/input1070">
+This creates the named file with this content before the test case is run,
+which is useful if the test case needs a file to act on. We create this file
+rather large (larger than your typical TCP packet) so that not all of it can nor
+will be sent in one go as that is kind of the point of this test!
+
+Here's 2000 x 'O':
+OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
+</file>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol nonewline="yes">
+POST /1070 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+Content-Length: 2313
+Content-Type: application/x-www-form-urlencoded
+Expect: 100-continue
+
+This creates
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/server/sws.c b/tests/server/sws.c
index a114cac43..f658d1863 100644
--- a/tests/server/sws.c
+++ b/tests/server/sws.c
@@ -99,6 +99,10 @@ struct httprequest {
bool ntlm; /* Authorization ntlm header found */
int pipe; /* if non-zero, expect this many requests to do a "piped"
request/response */
+ int skip; /* if non-zero, the server is instructed to not read this
+ many bytes from a PUT/POST request. Ie the client sends N
+ bytes said in Content-Length, but the server only reads N
+ - skip bytes. */
int rcmd; /* doing a special command, see defines above */
int prot_version; /* HTTP version * 10 */
bool pipelining; /* true if request is pipelined */
@@ -303,6 +307,13 @@ int ProcessRequest(struct httprequest *req)
req->pipe = num-1; /* decrease by one since we don't count the
first request in this number */
}
+ else if(1 == sscanf(cmd, "skip: %d", &num)) {
+ logmsg("instructed to skip this number of bytes %d", num);
+ req->skip = num;
+ }
+ else {
+ logmsg("funny instruction found: %s", cmd);
+ }
free(cmd);
}
}
@@ -351,7 +362,7 @@ int ProcessRequest(struct httprequest *req)
headers, for the pipelining case mostly */
req->checkindex += (end - line) + strlen(END_OF_HEADERS);
- /* **** Persistency ****
+ /* **** Persistence ****
*
* If the request is a HTTP/1.0 one, we close the connection unconditionally
* when we're done.
@@ -363,14 +374,17 @@ int ProcessRequest(struct httprequest *req)
*/
do {
- if(!req->cl && curlx_strnequal("Content-Length:", line, 15)) {
+ if((req->cl<=0) && curlx_strnequal("Content-Length:", line, 15)) {
/* If we don't ignore content-length, we read it and we read the whole
request including the body before we return. If we've been told to
ignore the content-length, we will return as soon as all headers
have been received */
- req->cl = strtol(line+15, &line, 10);
+ size_t cl = strtol(line+15, &line, 10);
+ req->cl = cl - req->skip;
- logmsg("Found Content-Length: %d in the request", req->cl);
+ logmsg("Found Content-Length: %d in the request", cl);
+ if(req->skip)
+ logmsg("... but will abort after %d bytes", req->cl);
break;
}
else if(curlx_strnequal("Transfer-Encoding: chunked", line,
@@ -457,7 +471,7 @@ int ProcessRequest(struct httprequest *req)
if(req->auth_req && !req->auth)
return 1;
- if(req->cl) {
+ if(req->cl > 0) {
if(req->cl <= req->offset - (end - req->reqbuf) - strlen(END_OF_HEADERS))
return 1; /* done */
else
@@ -552,6 +566,7 @@ static int get_request(curl_socket_t sock, struct httprequest *req)
req->digest = FALSE;
req->ntlm = FALSE;
req->pipe = 0;
+ req->skip = 0;
req->rcmd = RCMD_NORMALREQ;
req->prot_version = 0;
req->pipelining = FALSE;
@@ -564,8 +579,15 @@ static int get_request(curl_socket_t sock, struct httprequest *req)
got = pipereq_length;
pipereq_length = 0;
}
- else
- got = sread(sock, reqbuf + req->offset, REQBUFSIZ-1 - req->offset);
+ else {
+ if(req->skip)
+ /* we are instructed to not read the entire thing, so we make sure to only
+ read what we're supposed to and NOT read the enire thing the client
+ wants to send! */
+ got = sread(sock, reqbuf + req->offset, req->cl);
+ else
+ got = sread(sock, reqbuf + req->offset, REQBUFSIZ-1 - req->offset);
+ }
if (got <= 0) {
if (got < 0) {
logmsg("recv() returned error: %d", SOCKERRNO);