#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: TNP Demo Server\r\n");
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=ISO-8859-1\r\n");
strcat(buffer, "\r\n");
strcat(buffer, "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\r\n");
strcat(buffer, "<meta http-equiv=\"Content-type\" content=\"text/html; charset=iso-8859-1\">\r\n");
strcat(buffer, "<html>\r\n<head><title>");
strcat(buffer, title);
strcat(buffer, "</title></head>\r\n<body>\r\n");
strcat(buffer, message);
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[10]=status[0];
msg[11]=status[1];
msg[12]=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: TNP 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';
}
}
const char * page12 = "<h1>Device Status</h1><p>The device is on.</p>";
const char * page13 = "<h1>Device Status</h1><p>The device is off.</p>";
const char * page22 = "<h1>Device On</h1><p>The device was already on.</p>";
const char * page23 = "<h1>Device On</h1><p>The device is now on.</p>";
const char * page32 = "<h1>Device Off</h1><p>The device is now off.</p>";
const char * page33 = "<h1>Device Off</h1><p>The device was already off.</p>";
const char * menuln = "<hr /><p> <a href=\"/\">status</a> <a href=\"/on.html\">switch on</a> <a href=\"/off.html\">switch off</a> </p>";
void SimpleHTTPServer(int port) {
char buffer[2048];
char webpage[4096];
char method[16];
char localurl[128];
char params[256];
int status;
int mode =0;
SOCKET serve = TCPStartServer(port, 10);
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);
if (strcmp(method, "GET")!=0) {
CreateErrorReply(400, webpage);
} else if (strcmp(localurl, "/")==0) {
if (mode==0) {
strcpy(buffer, page13);
} else {
strcpy(buffer, page12);
}
strcat(buffer, menuln);
CreateContentReply("TNP Web Server", buffer, webpage);
} else if (strcmp(localurl, "/on.html")==0) {
if (mode==0) {
strcpy(buffer, page23);
mode=1;
cout << "Switiching on" << endl << flush;
} else {
strcpy(buffer, page22);
}
strcat(buffer, menuln);
CreateContentReply("TNP Web Server", buffer, webpage);
} else if (strcmp(localurl, "/off.html")==0) {
if (mode==0) {
strcpy(buffer, page33);
} else {
strcpy(buffer, page32);
mode=0;
cout << "Switiching off" << endl << flush;
}
strcat(buffer, menuln);
CreateContentReply("TNP Web Server", buffer, webpage);
} else {
CreateErrorReply(404, webpage);
}
TCPSendLine(visitor, webpage);
D(webpage);
TCPPrepClose(visitor);
TCPStopClient(visitor);
D("Done");
}
}
int main()
{
SocketLibStart();
SimpleHTTPServer(8088);
SocketLibEnd();
return(0);
}