40 #include <sys/types.h>
41 #ifdef HAVE_SYS_SOCKET_H
42 #include <sys/socket.h>
44 #ifdef HAVE_NETINET_IN_H
45 #include <netinet/in.h>
47 #ifdef _XOPEN_SOURCE_EXTENDED
49 #include <arpa/inet.h>
64 #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
67 #define EINPROGRESS WSAEINPROGRESS
68 #define EWOULDBLOCK WSAEWOULDBLOCK
69 #define EISCONN WSAEISCONN
70 #define ENOTSOCK WSAENOTSOCK
71 #define ECONNREFUSED WSAECONNREFUSED
74 #define REQBUFSIZ 150000
75 #define REQBUFSIZ_TXT "149999"
95 #define DEFAULT_PORT 8999
97 #ifndef DEFAULT_LOGFILE
98 #define DEFAULT_LOGFILE "log/sws.log"
101 #define SWSVERSION "cURL test suite HTTP server/0.1"
103 #define REQUEST_DUMP "log/server.input"
104 #define RESPONSE_DUMP "log/server.response"
106 #define TEST_DATA_PATH "%s/data/test%d"
109 #define MAXDOCNAMELEN 140000
110 #define MAXDOCNAMELEN_TXT "139999"
112 #define REQUEST_KEYWORD_SIZE 256
114 #define CMD_AUTH_REQUIRED "auth_required"
131 static const char *docquit =
132 "HTTP/1.1 200 Goodbye\r\n"
136 static const char *docconnect =
137 "HTTP/1.1 200 Mighty fine indeed\r\n"
141 static const char *docbadconnect =
142 "HTTP/1.1 501 Forbidden you fool\r\n"
146 static const char *doc404 =
"HTTP/1.1 404 Not Found\n"
148 "Connection: close\n"
149 "Content-Type: text/html\n"
151 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"
153 "<TITLE>404 Not Found</TITLE>\n"
155 "<H1>Not Found</H1>\n"
156 "The requested URL was not found on this server.\n"
157 "<P><HR><ADDRESS>" SWSVERSION "</ADDRESS>\n" "</BODY></HTML>\n";
160 static volatile int sigpipe;
164 static void logmsg(
const char *msg, ...)
166 time_t
t = time(
NULL);
175 fprintf(logfp,
"%02d:%02d:%02d (%d) %s\n",
178 curr_time->tm_sec, (
int)getpid(), buffer);
184 static void sigpipe_handler(
int sig)
191 #define END_OF_HEADERS "\r\n\r\n"
193 static char *test2file(
int testno)
195 static char filename[256];
208 int prot_major, prot_minor;
223 ptr = strrchr(doc,
'/');
232 if((strlen(doc) + strlen(request)) < 200)
233 sprintf(logbuf,
"Got request: %s %s HTTP/%d.%d",
234 request, doc, prot_major, prot_minor);
236 sprintf(logbuf,
"Got a *HUGE* request HTTP/%d.%d",
237 prot_major, prot_minor);
240 if(!
strncmp(
"/verifiedserver", ptr, 15)) {
241 logmsg(
"Are-we-friendly question received");
246 if(!
strncmp(
"/quit", ptr, 15)) {
247 logmsg(
"Request-to-quit received");
254 req->
testno = strtol(ptr, &ptr, 10);
263 sprintf(logbuf,
"Reqested test number %d part %d",
268 filename = test2file(req->
testno);
270 stream=fopen(filename,
"rb");
272 logmsg(
"Couldn't open test file %d", req->
testno);
277 cmd = (
char *)
spitout(stream,
"reply",
"servercmd", &cmdsize);
281 logmsg(
"Found a reply-servercmd section!");
284 logmsg(
"instructed to require authorization header");
291 if(sscanf(req->
reqbuf,
"CONNECT %" MAXDOCNAMELEN_TXT
"s HTTP/%d.%d",
292 doc, &prot_major, &prot_minor) == 3) {
293 sprintf(logbuf,
"Receiced a CONNECT %s HTTP/%d.%d request",
294 doc, prot_major, prot_minor);
297 if(prot_major*10+prot_minor == 10)
303 else if(!
strncmp(doc,
"test", 4)) {
304 char *ptr = strchr(doc,
':');
306 req->
testno = atoi(ptr+1);
314 logmsg(
"Did not find test number in PATH");
341 req->
cl = strtol(line+15, &line, 10);
343 logmsg(
"Found Content-Legth: %d in the request", req->
cl);
346 else if(!
strncasecmp(
"Transfer-Encoding: chunked", line,
347 strlen(
"Transfer-Encoding: chunked"))) {
353 if(strstr(req->
reqbuf,
"\r\n0\r\n"))
360 line = strchr(line,
'\n');
365 if(!req->
auth && strstr(req->
reqbuf,
"Authorization:")) {
368 logmsg(
"Authorization header found, as required");
371 if(!req->
digest && strstr(req->
reqbuf,
"Authorization: Digest")) {
377 logmsg(
"Received Digest request, sending back data %d", req->
partno);
379 else if(!req->
ntlm &&
380 strstr(req->
reqbuf,
"Authorization: NTLM TlRMTVNTUAAD")) {
384 logmsg(
"Received NTLM type-3, sending back data %d", req->
partno);
386 else if(!req->
ntlm &&
387 strstr(req->
reqbuf,
"Authorization: NTLM TlRMTVNTUAAB")) {
391 logmsg(
"Received NTLM type-1, sending back data %d", req->
partno);
393 if(strstr(req->
reqbuf,
"Connection: close"))
412 fwrite(reqbuf, 1, strlen(reqbuf), dump);
418 logmsg(
"Failed to write request input to " REQUEST_DUMP);
423 static int get_request(
int sock,
struct httprequest *req)
426 char *reqbuf = req->
reqbuf;
444 logmsg(
"recv() returned error");
447 logmsg(
"Connection closed by client");
459 logmsg(
"Request buffer overflow, closing connection");
474 static int send_doc(
int sock,
struct httprequest *req)
484 int persistant =
TRUE;
486 static char weare[256];
488 char partbuf[80]=
"data";
492 logmsg(
"Send response number %d part %d", req->
testno, req->
partno);
497 logmsg(
"Replying to QUIT");
502 logmsg(
"Identifying ourselves as friends");
503 sprintf(weare,
"HTTP/1.1 200 OK\r\n\r\nWE ROOLZ: %d\r\n",
508 logmsg(
"Bailing out due to internal error");
511 logmsg(
"Replying to CONNECT");
515 logmsg(
"Replying to a bad CONNECT");
516 buffer = docbadconnect;
520 logmsg(
"Replying to with a 404");
527 count = strlen(buffer);
530 char *filename = test2file(req->
testno);
535 stream=fopen(filename,
"rb");
537 logmsg(
"Couldn't open test file");
541 buffer =
spitout(stream,
"reply", partbuf, &count);
542 ptr = (
char *)buffer;
547 stream=fopen(filename,
"rb");
549 logmsg(
"Couldn't open test file");
554 cmd = (
char *)
spitout(stream,
"reply",
"postcmd", &cmdsize);
568 if(strstr(buffer,
"swsclose") || !count) {
570 logmsg(
"connection close instruction swsclose found in response");
574 written =
swrite(sock, buffer, count);
576 logmsg(
"Sending response failed and we bailed out!");
580 fwrite(buffer, 1, written, dump);
588 logmsg(
"Response sent!");
598 if(2 == sscanf(ptr,
"%31s %d", command, &num)) {
599 if(!
strcmp(
"wait", command))
602 logmsg(
"Unknown command in reply command section");
604 ptr = strchr(ptr,
'\n');
609 }
while(ptr && *ptr);
614 req->
open = persistant;
619 #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
620 static void win32_init(
void)
622 WORD wVersionRequested;
625 wVersionRequested = MAKEWORD(2, 0);
627 err = WSAStartup(wVersionRequested, &wsaData);
630 perror(
"Winsock init failed");
631 fprintf(logfp,
"Error initializing winsock -- aborting\n");
636 if (
LOBYTE( wsaData.wVersion ) != 2 ||
637 HIBYTE( wsaData.wVersion ) != 0 ) {
640 perror(
"Winsock init failed");
641 fprintf(logfp,
"No suitable winsock.dll found -- aborting\n");
646 static void win32_cleanup(
void)
652 int main(
int argc,
char *argv[])
654 struct sockaddr_in me;
655 int sock, msgsock, flag;
662 port = atoi(argv[1]);
669 logfp = fopen(logfile,
"a");
675 #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
681 signal(SIGPIPE, sigpipe_handler);
683 #ifdef HAVE_SIGINTERRUPT
684 siginterrupt(SIGPIPE, 1);
688 sock = socket(AF_INET, SOCK_STREAM, 0);
690 perror(
"opening stream socket");
691 fprintf(logfp,
"Error opening socket -- aborting\n");
698 (sock, SOL_SOCKET, SO_REUSEADDR, (
const void *) &flag,
700 perror(
"setsockopt(SO_REUSEADDR)");
703 me.sin_family = AF_INET;
704 me.sin_addr.s_addr = INADDR_ANY;
705 me.sin_port = htons(port);
706 if (bind(sock, (
struct sockaddr *) &me,
sizeof me) < 0) {
707 perror(
"binding stream socket");
708 fprintf(logfp,
"Error binding socket -- aborting\n");
713 pidfile = fopen(
".http.pid",
"w");
715 fprintf(pidfile,
"%d\n", (
int)getpid());
719 fprintf(stderr,
"Couldn't write pid file\n");
730 logmsg(
"** New client connected");
733 if(get_request(msgsock, &req))
737 send_doc(msgsock, &req);
740 logmsg(
"special request received, no persistancy");
744 logmsg(
"instructed to close connection after server-reply");
749 logmsg(
"persistant connection, awaits new request");
753 logmsg(
"** Closing client connection");
763 #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#define REQUEST_KEYWORD_SIZE
void storerequest(char *reqbuf)
GLuint GLuint GLsizei count
#define MAXDOCNAMELEN_TXT
int ProcessRequest(struct httprequest *req)
static WindowRef ValidModeCallbackProc inCallback OSStatus err
const char * spitout(FILE *stream, const char *main, const char *sub, int *size)
int vsprintf(idStr &string, const char *fmt, va_list argptr)
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
int main(int argc, char *argv[])
#define CMD_AUTH_REQUIRED
struct tm * localtime(const time_t *)
int sprintf(idStr &string, const char *fmt,...)