From 6ed72fd7fa138e427ce51a95832ce9b398f67440 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 25 Aug 2010 00:45:52 +0200 Subject: [PATCH] sws: added basic gopher support --- tests/server/sws.c | 75 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/tests/server/sws.c b/tests/server/sws.c index 44a84a986..8a93b3b8d 100644 --- a/tests/server/sws.c +++ b/tests/server/sws.c @@ -75,6 +75,7 @@ #ifdef ENABLE_IPV6 static bool use_ipv6 = FALSE; #endif +static bool use_gopher = FALSE; static const char *ipv_inuse = "IPv4"; static int serverlogslocked = 0; @@ -159,6 +160,7 @@ enum { DOCNUMBER_404 = -1 }; +const char *end_of_headers = END_OF_HEADERS; /* sent as reply to a QUIT */ static const char *docquit = @@ -307,13 +309,22 @@ static int ProcessRequest(struct httprequest *req) int prot_major, prot_minor; char *end; int error; - end = strstr(line, END_OF_HEADERS); + end = strstr(line, end_of_headers); logmsg("ProcessRequest() called"); /* try to figure out the request characteristics as soon as possible, but only once! */ - if((req->testno == DOCNUMBER_NOTHING) && + + if(use_gopher && + (req->testno == DOCNUMBER_NOTHING) && + !strncmp("/verifiedserver", line, 15)) { + logmsg("Are-we-friendly question received"); + req->testno = DOCNUMBER_WERULEZ; + return 1; /* done */ + } + + else if((req->testno == DOCNUMBER_NOTHING) && sscanf(line, "%" REQUEST_KEYWORD_SIZE_TXT"s %" MAXDOCNAMELEN_TXT "s HTTP/%d.%d", request, @@ -471,10 +482,40 @@ static int ProcessRequest(struct httprequest *req) } logmsg("ProcessRequest found a complete request"); + if(use_gopher) { + /* when using gopher we cannot check the request until the entire + thing has been received */ + char *ptr; + + /* find the last slash in the line */ + ptr = strrchr(line, '/'); + + if(ptr) { + ptr++; /* skip the slash */ + + /* skip all non-numericals following the slash */ + while(*ptr && !ISDIGIT(*ptr)) + ptr++; + + req->testno = strtol(ptr, &ptr, 10); + + if(req->testno > 10000) { + req->partno = req->testno % 10000; + req->testno /= 10000; + } + else + req->partno = 0; + + sprintf(logbuf, "Requested GOPHER test number %ld part %ld", + req->testno, req->partno); + logmsg("%s", logbuf); + } + } + if(req->pipe) /* we do have a full set, advance the checkindex to after the end of the headers, for the pipelining case mostly */ - req->checkindex += (end - line) + strlen(END_OF_HEADERS); + req->checkindex += (end - line) + strlen(end_of_headers); /* **** Persistence **** * @@ -582,12 +623,12 @@ static int ProcessRequest(struct httprequest *req) req->open && req->prot_version >= 11 && end && - req->reqbuf + req->offset > end + strlen(END_OF_HEADERS) && + req->reqbuf + req->offset > end + strlen(end_of_headers) && (!strncmp(req->reqbuf, "GET", strlen("GET")) || !strncmp(req->reqbuf, "HEAD", strlen("HEAD")))) { /* If we have a persistent connection, HTTP version >= 1.1 and GET/HEAD request, enable pipelining. */ - req->checkindex = (end - req->reqbuf) + strlen(END_OF_HEADERS); + req->checkindex = (end - req->reqbuf) + strlen(end_of_headers); req->pipelining = TRUE; } @@ -596,10 +637,10 @@ static int ProcessRequest(struct httprequest *req) return 1; /* done */ /* scan for more header ends within this chunk */ line = &req->reqbuf[req->checkindex]; - end = strstr(line, END_OF_HEADERS); + end = strstr(line, end_of_headers); if(!end) break; - req->checkindex += (end - line) + strlen(END_OF_HEADERS); + req->checkindex += (end - line) + strlen(end_of_headers); req->pipe--; } @@ -611,7 +652,7 @@ static int ProcessRequest(struct httprequest *req) return 1; /* done */ if(req->cl > 0) { - if(req->cl <= req->offset - (end - req->reqbuf) - strlen(END_OF_HEADERS)) + if(req->cl <= req->offset - (end - req->reqbuf) - strlen(end_of_headers)) return 1; /* done */ else return 0; /* not complete yet */ @@ -842,8 +883,11 @@ static int send_doc(curl_socket_t sock, struct httprequest *req) logmsg("Identifying ourselves as friends"); sprintf(msgbuf, "WE ROOLZ: %ld\r\n", (long)getpid()); msglen = strlen(msgbuf); - sprintf(weare, "HTTP/1.1 200 OK\r\nContent-Length: %zu\r\n\r\n%s", - msglen, msgbuf); + if(use_gopher) + sprintf(weare, "%s", msgbuf); + else + sprintf(weare, "HTTP/1.1 200 OK\r\nContent-Length: %zu\r\n\r\n%s", + msglen, msgbuf); buffer = weare; break; case DOCNUMBER_INTERNAL: @@ -1050,7 +1094,7 @@ static int send_doc(curl_socket_t sock, struct httprequest *req) if(cmd) free(cmd); - req->open = persistant; + req->open = use_gopher?FALSE:persistant; prevtestno = req->testno; prevpartno = req->partno; @@ -1106,6 +1150,11 @@ int main(int argc, char *argv[]) if(argc>arg) serverlogfile = argv[arg++]; } + else if(!strcmp("--gopher", argv[arg])) { + arg++; + use_gopher = TRUE; + end_of_headers = "\r\n"; /* gopher style is much simpler */ + } else if(!strcmp("--ipv4", argv[arg])) { #ifdef ENABLE_IPV6 ipv_inuse = "IPv4"; @@ -1157,6 +1206,7 @@ int main(int argc, char *argv[]) " --ipv6\n" " --port [port]\n" " --srcdir [path]\n" + " --gopher\n" " --fork"); return 0; } @@ -1221,7 +1271,8 @@ int main(int argc, char *argv[]) goto sws_cleanup; } - logmsg("Running %s version on port %d", ipv_inuse, (int)port); + logmsg("Running %s %s version on port %d", + use_gopher?"GOPHER":"HTTP", ipv_inuse, (int)port); /* start accepting connections */ rc = listen(sock, 5);