//* A test for a Web server with a request parser *

#include "tnplib.h" #include <iostream> #include <cstdio> #include <cstring> using namespace std; inline void D(const char *errormessage) { #ifdef _DEBUG cerr << errormessage << endl; #endif } void CreateReply(const char * status, const char * title, const char * message, char * buffer) { strcpy(buffer, "HTTP/1.1 "); strcat(buffer, status); strcat(buffer, "\r\n"); strcat(buffer, "Server: eTCP Demo Server\r\n"); // Date: must be provided unless the server has no reliable clock - then it must not be provided strcat(buffer, "Connection: close\r\n"); strcat(buffer, "Cache-Control: no-cache\r\nExpires: 0\r\nETag: \"\"\r\n"); strcat(buffer, "Content-Type: text/html; charset=UTF-8\r\n"); strcat(buffer, "\r\n"); // HTML Page header strcat(buffer, "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\r\n"); strcat(buffer, "<meta http-equiv=\"Content-type\" content=\"text/html; charset=UTF-8\">\r\n"); strcat(buffer, "<html>\r\n<head><title>"); strcat(buffer, title); strcat(buffer, "</title></head>\r\n<body>\r\n"); strcat(buffer, message); // HTML Page footer strcat(buffer, "\r\n</body>\r\n</html>\r\n"); } void CreateStatusReply(const char * status, char * buffer) { char tit[128]; char msg[128]; strcpy(tit, "Error "); strcat(tit, status); strcpy(msg, "<h1>Error ---</h1><p>"); msg[11]=status[0]; msg[12]=status[1]; msg[13]=status[2]; strcat(msg, status); strcat(msg, "</p>"); CreateReply(status, tit, msg, buffer); } void CreateErrorReply(int error, char * buffer) { switch(error) { case 400: CreateStatusReply( "400 Bad Request", buffer); break; case 401: CreateStatusReply( "401 Unauthorized", buffer); break; case 402: CreateStatusReply( "402 Payment Required", buffer); break; case 403: CreateStatusReply( "403 Forbidden", buffer); break; case 404: CreateStatusReply( "404 Not Found", buffer); break; case 405: CreateStatusReply( "405 Method Not Allowed", buffer); break; case 406: CreateStatusReply( "406 Not Acceptable", buffer); break; case 407: CreateStatusReply( "407 Proxy Authentication Required", buffer); break; case 411: CreateStatusReply( "411 Length Required", buffer); break; case 414: CreateStatusReply( "414 Request-URI Too Large", buffer); break; case 500: CreateStatusReply( "500 Internal Server Error", buffer); break; case 501: CreateStatusReply( "501 Not Implemented", buffer); break; case 503: CreateStatusReply( "503 Service Unavailable", buffer); break; default: CreateReply( "500 Internal Server Error", "500 Internal Server Error", "500 Internal Server Error: Out of range error message", buffer); break; } } void CreateContentReply(const char * title, const char * message, char * buffer) { CreateReply("200 Ok", title, message, buffer); } void CreateRedirection(const char * whereto, char * buffer) { strcpy(buffer, "HTTP/1.1 301 Moved Permanently\r\n"); strcat(buffer, "Location: "); strcat(buffer, whereto); strcat(buffer, "\r\n"); strcat(buffer, "Server: eTCP Demo Server\r\n"); strcat(buffer, "Connection: close\r\n"); strcat(buffer, "\r\n"); } void ParseURL(const char * buffer, char * method, char * localurl, char * params) { const char * s; int j; method[0]='\0'; localurl[0]='\0'; params[0]='\0'; s=buffer; j=0; while (*s!=' ' && j<15) { method[j]=*s; ++s; ++j; } method[j]='\0'; if (*s!=' ') { method[0]='\0'; return; } ++s; if (strncmp( s, "http://", 7)==0) { s=s+7; while (*s!='\0' && *s!='/') ++s; if (*s!='/') return; } j=0; while (*s!='\0' && *s!=' ' && *s!='?') { localurl[j]=*s; ++s; ++j; } localurl[j]='\0'; if (*s=='?') { ++s; j=0; while (*s!='\0' && *s!=' ') { params[j]=*s; ++s; ++j; } params[j]='\0'; } } void SimpleHTTPServer(int port) { char buffer[65536]; char webpage[65536]; char method[16]; char localurl[128]; char params[256]; int status; SOCKET serve = TCPStartServer(port, 10, 1); for (;;) { SOCKET visitor = TCPWaitForConnection(serve); status = TCPRecvLine(visitor, buffer, sizeof(buffer) ); if (status<0) continue; D(buffer); ParseURL(buffer, method, localurl, params); do { status = TCPRecvDumpLine(visitor); } while (status>0); strcpy(buffer, "<h1>ParseURL Diagnostics</h1>\r\n"); strcat(buffer, "<p>Method: "); strcat(buffer, method); strcat(buffer, "</p>\r\n"); strcat(buffer, "<p>URL: "); strcat(buffer, localurl); strcat(buffer, "</p>\r\n"); strcat(buffer, "<p>Parameters: "); strcat(buffer, params); strcat(buffer, "</p>\r\n"); strcat(buffer, "\r\n"); CreateContentReply("ParseURL Diagnostics", buffer, webpage); TCPSendLine(visitor, webpage); D(webpage); TCPPrepClose(visitor); TCPStopClient(visitor); D("Done"); } } int main() { SocketLibStart(); SimpleHTTPServer(8088); SocketLibEnd(); return(0); }