From: Daniel Stenberg Date: Wed, 8 Jun 2022 14:32:46 +0000 (+0200) Subject: server/sws: support spaces in the HTTP request path X-Git-Tag: curl-7_84_0~66 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=db8cfdc8f7a6e52b11ebeb3b482af1fe69e90051;p=thirdparty%2Fcurl.git server/sws: support spaces in the HTTP request path --- diff --git a/tests/server/sws.c b/tests/server/sws.c index d51dd604a0..0e623eeeb6 100644 --- a/tests/server/sws.c +++ b/tests/server/sws.c @@ -360,9 +360,9 @@ static int ProcessRequest(struct httprequest *req) char *line = &req->reqbuf[req->checkindex]; bool chunked = FALSE; static char request[REQUEST_KEYWORD_SIZE]; - static char doc[MAXDOCNAMELEN]; char logbuf[456]; - int prot_major, prot_minor; + int prot_major = 0; + int prot_minor = 0; char *end = strstr(line, end_of_headers); req->callcount++; @@ -381,175 +381,167 @@ static int ProcessRequest(struct httprequest *req) return 1; /* done */ } - else if((req->testno == DOCNUMBER_NOTHING) && - sscanf(line, - "%" REQUEST_KEYWORD_SIZE_TXT"s %" MAXDOCNAMELEN_TXT "s HTTP/%d.%d", - request, - doc, - &prot_major, - &prot_minor) == 4) { - char *ptr; - - req->prot_version = prot_major*10 + prot_minor; + else if(req->testno == DOCNUMBER_NOTHING) { + char *http; + bool fine = FALSE; + char *httppath = NULL; + size_t npath = 0; /* httppath length */ - /* find the last slash */ - ptr = strrchr(doc, '/'); - - /* get the number after it */ - if(ptr) { - if((strlen(doc) + strlen(request)) < 400) - msnprintf(logbuf, sizeof(logbuf), "Got request: %s %s HTTP/%d.%d", - request, doc, prot_major, prot_minor); - else - msnprintf(logbuf, sizeof(logbuf), "Got a *HUGE* request HTTP/%d.%d", - prot_major, prot_minor); - logmsg("%s", logbuf); + if(sscanf(line, + "%" REQUEST_KEYWORD_SIZE_TXT"s ", request)) { + http = strstr(line + strlen(request), "HTTP/"); - if(!strncmp("/verifiedserver", ptr, 15)) { - logmsg("Are-we-friendly question received"); - req->testno = DOCNUMBER_WERULEZ; - return 1; /* done */ - } + if(http && sscanf(http, "HTTP/%d.%d", + &prot_major, + &prot_minor) == 2) { + /* between the request keyword and HTTP/ there's a path */ + httppath = line + strlen(request); + npath = http - httppath; - if(!strncmp("/quit", ptr, 5)) { - logmsg("Request-to-quit received"); - req->testno = DOCNUMBER_QUIT; - return 1; /* done */ + /* trim leading spaces */ + while(npath && ISSPACE(*httppath)) { + httppath++; + npath--; + } + /* trim ending spaces */ + while(npath && ISSPACE(httppath[npath - 1])) { + npath--; + } + if(npath) + fine = TRUE; } + } - ptr++; /* skip the slash */ - - /* skip all non-numericals following the slash */ - while(*ptr && !ISDIGIT(*ptr)) - ptr++; + if(fine) { + char *ptr; - req->testno = strtol(ptr, &ptr, 10); + req->prot_version = prot_major*10 + prot_minor; - if(req->testno > 10000) { - req->partno = req->testno % 10000; - req->testno /= 10000; + /* find the last slash */ + ptr = &httppath[npath]; + while(ptr >= httppath) { + if(*ptr == '/') + break; + ptr--; } - else - req->partno = 0; - - if(req->testno) { - msnprintf(logbuf, sizeof(logbuf), "Requested test number %ld part %ld", - req->testno, req->partno); + /* get the number after it */ + if(*ptr == '/') { + if((npath + strlen(request)) < 400) + msnprintf(logbuf, sizeof(logbuf), "Got request: %s %.*s HTTP/%d.%d", + request, npath, httppath, prot_major, prot_minor); + else + msnprintf(logbuf, sizeof(logbuf), "Got a *HUGE* request HTTP/%d.%d", + prot_major, prot_minor); logmsg("%s", logbuf); - } - else { - logmsg("No test number"); - req->testno = DOCNUMBER_NOTHING; - } - } - - if(req->testno == DOCNUMBER_NOTHING) { - /* didn't find any in the first scan, try alternative test case - number placements */ + if(!strncmp("/verifiedserver", ptr, 15)) { + logmsg("Are-we-friendly question received"); + req->testno = DOCNUMBER_WERULEZ; + return 1; /* done */ + } - if(sscanf(req->reqbuf, "CONNECT %" MAXDOCNAMELEN_TXT "s HTTP/%d.%d", - doc, &prot_major, &prot_minor) == 3) { - char *portp = NULL; + if(!strncmp("/quit", ptr, 5)) { + logmsg("Request-to-quit received"); + req->testno = DOCNUMBER_QUIT; + return 1; /* done */ + } - msnprintf(logbuf, sizeof(logbuf), - "Received a CONNECT %s HTTP/%d.%d request", - doc, prot_major, prot_minor); - logmsg("%s", logbuf); + ptr++; /* skip the slash */ - req->connect_request = TRUE; - - if(req->prot_version == 10) - req->open = FALSE; /* HTTP 1.0 closes connection by default */ - - if(doc[0] == '[') { - char *p = &doc[1]; - unsigned long part = 0; - /* scan through the hexgroups and store the value of the last group - in the 'part' variable and use as test case number!! */ - while(*p && (ISXDIGIT(*p) || (*p == ':') || (*p == '.'))) { - char *endp; - part = strtoul(p, &endp, 16); - if(ISXDIGIT(*p)) - p = endp; - else - p++; - } - if(*p != ']') - logmsg("Invalid CONNECT IPv6 address format"); - else if(*(p + 1) != ':') - logmsg("Invalid CONNECT IPv6 port format"); - else - portp = p + 1; + req->testno = strtol(ptr, &ptr, 10); - req->testno = part; + if(req->testno > 10000) { + req->partno = req->testno % 10000; + req->testno /= 10000; } else - portp = strchr(doc, ':'); + req->partno = 0; - if(portp && (*(portp + 1) != '\0') && ISDIGIT(*(portp + 1))) { - unsigned long ulnum = strtoul(portp + 1, NULL, 10); - if(!ulnum || (ulnum > 65535UL)) - logmsg("Invalid CONNECT port received"); - else - req->connect_port = curlx_ultous(ulnum); + if(req->testno) { + msnprintf(logbuf, sizeof(logbuf), "Serve test number %ld part %ld", + req->testno, req->partno); + logmsg("%s", logbuf); + } + else { + logmsg("No test number in path"); + req->testno = DOCNUMBER_NOTHING; } - logmsg("Port number: %d, test case number: %ld", - req->connect_port, req->testno); - } - } - - if(req->testno == DOCNUMBER_NOTHING) { - /* Still no test case number. Try to get the number off the last dot - instead, IE we consider the TLD to be the test number. Test 123 can - then be written as "example.com.123". */ - - /* find the last dot */ - ptr = strrchr(doc, '.'); - - /* get the number after it */ - if(ptr) { - long num; - ptr++; /* skip the dot */ - - num = strtol(ptr, &ptr, 10); - if(num) { - req->testno = num; - if(req->testno > 10000) { - req->partno = req->testno % 10000; - req->testno /= 10000; + } - logmsg("found test %d in requested host name", req->testno); + if(req->testno == DOCNUMBER_NOTHING) { + /* didn't find any in the first scan, try alternative test case + number placements */ + static char doc[MAXDOCNAMELEN]; + if(sscanf(req->reqbuf, "CONNECT %" MAXDOCNAMELEN_TXT "s HTTP/%d.%d", + doc, &prot_major, &prot_minor) == 3) { + char *portp = NULL; + + msnprintf(logbuf, sizeof(logbuf), + "Received a CONNECT %s HTTP/%d.%d request", + doc, prot_major, prot_minor); + logmsg("%s", logbuf); + + req->connect_request = TRUE; + + if(req->prot_version == 10) + req->open = FALSE; /* HTTP 1.0 closes connection by default */ + + if(doc[0] == '[') { + char *p = &doc[1]; + unsigned long part = 0; + /* scan through the hexgroups and store the value of the last group + in the 'part' variable and use as test case number!! */ + while(*p && (ISXDIGIT(*p) || (*p == ':') || (*p == '.'))) { + char *endp; + part = strtoul(p, &endp, 16); + if(ISXDIGIT(*p)) + p = endp; + else + p++; + } + if(*p != ']') + logmsg("Invalid CONNECT IPv6 address format"); + else if(*(p + 1) != ':') + logmsg("Invalid CONNECT IPv6 port format"); + else + portp = p + 1; + req->testno = part; } else - req->partno = 0; - } + portp = strchr(doc, ':'); + + if(portp && (*(portp + 1) != '\0') && ISDIGIT(*(portp + 1))) { + unsigned long ulnum = strtoul(portp + 1, NULL, 10); + if(!ulnum || (ulnum > 65535UL)) + logmsg("Invalid CONNECT port received"); + else + req->connect_port = curlx_ultous(ulnum); - if(req->testno != DOCNUMBER_NOTHING) { - logmsg("Requested test number %ld part %ld (from host name)", - req->testno, req->partno); + } + logmsg("Port number: %d, test case number: %ld", + req->connect_port, req->testno); } } - } - if(req->testno == DOCNUMBER_NOTHING) - /* might get the test number */ - parse_cmdfile(req); + if(req->testno == DOCNUMBER_NOTHING) + /* might get the test number */ + parse_cmdfile(req); - if(req->testno == DOCNUMBER_NOTHING) { - logmsg("Did not find test number in PATH"); - req->testno = DOCNUMBER_404; + if(req->testno == DOCNUMBER_NOTHING) { + logmsg("Did not find test number in PATH"); + req->testno = DOCNUMBER_404; + } + else + parse_servercmd(req); + } + else if((req->offset >= 3)) { + logmsg("** Unusual request. Starts with %02x %02x %02x (%c%c%c)", + line[0], line[1], line[2], line[0], line[1], line[2]); } - else - parse_servercmd(req); - } - else if((req->offset >= 3) && (req->testno == DOCNUMBER_NOTHING)) { - logmsg("** Unusual request. Starts with %02x %02x %02x (%c%c%c)", - line[0], line[1], line[2], line[0], line[1], line[2]); } if(!end) {