diff options
Diffstat (limited to 'tests/server/sws.c')
-rw-r--r-- | tests/server/sws.c | 91 |
1 files changed, 68 insertions, 23 deletions
diff --git a/tests/server/sws.c b/tests/server/sws.c index 949831d6c..b2d6df7a6 100644 --- a/tests/server/sws.c +++ b/tests/server/sws.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -107,7 +107,7 @@ struct httprequest { bool digest; /* Authorization digest header found */ bool ntlm; /* Authorization ntlm header found */ int writedelay; /* if non-zero, delay this number of seconds between - writes in the response */ + writes in the response */ 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 @@ -117,6 +117,7 @@ struct httprequest { int rcmd; /* doing a special command, see defines above */ int prot_version; /* HTTP version * 10 */ bool pipelining; /* true if request is pipelined */ + int callcount; /* times ProcessRequest() gets called */ }; static int ProcessRequest(struct httprequest *req); @@ -308,13 +309,16 @@ static int ProcessRequest(struct httprequest *req) bool chunked = FALSE; static char request[REQUEST_KEYWORD_SIZE]; static char doc[MAXDOCNAMELEN]; - char logbuf[256]; + char logbuf[456]; int prot_major, prot_minor; char *end; int error; end = strstr(line, end_of_headers); - logmsg("ProcessRequest() called"); + req->callcount++; + + logmsg("Process %d bytes request%s", req->offset, + req->callcount > 1?" [CONTINUED]":""); /* try to figure out the request characteristics as soon as possible, but only once! */ @@ -346,7 +350,7 @@ static int ProcessRequest(struct httprequest *req) FILE *stream; char *filename; - if((strlen(doc) + strlen(request)) < 200) + if((strlen(doc) + strlen(request)) < 400) sprintf(logbuf, "Got request: %s %s HTTP/%d.%d", request, doc, prot_major, prot_minor); else @@ -397,12 +401,13 @@ static int ProcessRequest(struct httprequest *req) return 1; /* done */ } else { + char *orgcmd = NULL; char *cmd = NULL; size_t cmdsize = 0; int num=0; /* get the custom server control "commands" */ - error = getpart(&cmd, &cmdsize, "reply", "servercmd", stream); + error = getpart(&orgcmd, &cmdsize, "reply", "servercmd", stream); fclose(stream); if(error) { logmsg("getpart() failed with error: %d", error); @@ -410,8 +415,9 @@ static int ProcessRequest(struct httprequest *req) return 1; /* done */ } - if(cmdsize) { - logmsg("Found a reply-servercmd section!"); + cmd = orgcmd; + while(cmd && cmdsize) { + char *check; if(!strncmp(CMD_AUTH_REQUIRED, cmd, strlen(CMD_AUTH_REQUIRED))) { logmsg("instructed to require authorization header"); @@ -445,9 +451,26 @@ static int ProcessRequest(struct httprequest *req) else { logmsg("funny instruction found: %s", cmd); } + /* try to deal with CRLF or just LF */ + check = strchr(cmd, '\r'); + if(!check) + check = strchr(cmd, '\n'); + + if(check) { + /* get to the letter following the newline */ + while((*check == '\r') || (*check == '\n')) + check++; + + if(!*check) + /* if we reached a zero, get out */ + break; + cmd = check; + } + else + break; } - if(cmd) - free(cmd); + if(orgcmd) + free(orgcmd); } } else { @@ -481,13 +504,17 @@ static int ProcessRequest(struct httprequest *req) } } } + else if((req->offset >= 3) && (req->testno == DOCNUMBER_NOTHING)) { + logmsg("** Unusual request. Starts with %02x %02x %02x", + line[0], line[1], line[2]); + } if(!end) { /* we don't have a complete request yet! */ - logmsg("ProcessRequest returned without a complete request"); + logmsg("request not complete yet"); return 0; /* not complete yet */ } - logmsg("ProcessRequest found a complete request"); + logmsg("- request found to be complete"); if(use_gopher) { /* when using gopher we cannot check the request until the entire @@ -616,10 +643,11 @@ static int ProcessRequest(struct httprequest *req) req->ntlm = TRUE; /* NTLM found */ logmsg("Received NTLM type-1, sending back data %ld", req->partno); } - else if((req->partno >= 1000) && strstr(req->reqbuf, "Authorization: Basic")) { - /* If the client is passing this Basic-header and the part number is already - >=1000, we add 1 to the part number. This allows simple Basic authentication - negotiation to work in the test suite. */ + else if((req->partno >= 1000) && + strstr(req->reqbuf, "Authorization: Basic")) { + /* If the client is passing this Basic-header and the part number is + already >=1000, we add 1 to the part number. This allows simple Basic + authentication negotiation to work in the test suite. */ req->partno += 1; logmsg("Received Basic request, sending back data %ld", req->partno); } @@ -631,6 +659,7 @@ static int ProcessRequest(struct httprequest *req) req->prot_version >= 11 && end && req->reqbuf + req->offset > end + strlen(end_of_headers) && + !req->cl && (!strncmp(req->reqbuf, "GET", strlen("GET")) || !strncmp(req->reqbuf, "HEAD", strlen("HEAD")))) { /* If we have a persistent connection, HTTP version >= 1.1 @@ -655,8 +684,10 @@ static int ProcessRequest(struct httprequest *req) makes the server NOT wait for PUT/POST data and you can then make the test case send a rejection before any such data has been sent. Test case 154 uses this.*/ - if(req->auth_req && !req->auth) + if(req->auth_req && !req->auth) { + logmsg("Return early due to auth requested by none provided"); return 1; /* done */ + } if(req->cl > 0) { if(req->cl <= req->offset - (end - req->reqbuf) - strlen(end_of_headers)) @@ -756,6 +787,7 @@ static int get_request(curl_socket_t sock, struct httprequest *req) req->rcmd = RCMD_NORMALREQ; req->prot_version = 0; req->pipelining = FALSE; + req->callcount = 0; /*** end of httprequest init ***/ @@ -767,9 +799,9 @@ static int get_request(curl_socket_t sock, struct httprequest *req) } 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! */ + /* 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); @@ -851,7 +883,7 @@ static int send_doc(curl_socket_t sock, struct httprequest *req) char partbuf[80]="data"; - logmsg("Send response number %ld part %ld", req->testno, req->partno); + logmsg("Send response test%ld section <data%ld>", req->testno, req->partno); switch(req->rcmd) { default: @@ -1394,8 +1426,13 @@ int main(int argc, char *argv[]) break; } - if(req.open) - logmsg("=> persistant connection request ended, awaits new request"); + if(req.open) { + logmsg("=> persistant connection request ended, awaits new request\n"); + /* + const char *keepopen="[KEEPING CONNECTION OPEN]"; + storerequest((char *)keepopen, strlen(keepopen)); + */ + } /* if we got a CONNECT, loop and get another request as well! */ } while(req.open || (req.testno == DOCNUMBER_CONNECT)); @@ -1403,6 +1440,14 @@ int main(int argc, char *argv[]) break; logmsg("====> Client disconnect"); + + if(!req.open) + /* When instructed to close connection after server-reply we + wait a very small amount of time before doing so. If this + is not done client might get an ECONNRESET before reading + a single byte of server-reply. */ + wait_ms(50); + sclose(msgsock); msgsock = CURL_SOCKET_BAD; |