//HTTPD Server #include #include #include #include #include #include #include #include #include #include #include #include #define SERVERPORT 8000 #define SERVERNAME "karlsworld" #define MAX_PENDING 20 #define MAXTHREADS 20 #define MAX_LINE 256 #define BUFFERSIZE 20000 #define HEADERSIZE 500 #define MESSAGESIZE 1000 #define SERVERROOT "docroot" #define TEMPDIR "/home/karl/tmp" #define DELAY 500 void *server_thread(void *arg); const char *getFNFError(char *location); const char *getFNRError(char *location); string int2string(int x); int new_s; int main(int argc, char * argv[]) { struct sockaddr_in sin; char buf[MAX_LINE]; //int new_s; int s, len; //thread_index = 0; cout << "\nRunning Karl's Web Server on Port " << int2string(SERVERPORT) << "\n\n"; bzero((char *)&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(SERVERPORT); if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) { perror("httpd: socket error"); exit(1); } if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { perror("httpd: socket error"); exit(1); } listen(s, MAX_PENDING); //printf("\nWaiting for a connection\n"); for (;;) { //if (thread_index>=MAXTHREADS) thread_index=0; if ((new_s = accept(s, (struct sockaddr *)&sin, &len)) < 0) { perror("httpd: server accept error"); exit(1); } pthread_t thread_handle; pthread_create(&thread_handle, NULL, server_thread, NULL); close(thread_handle); //for (int x=0;x0;y/=10) { ret = (char)((y%10)+'0') + ret; //cout << ret << "\n"; } return ret; } } void *server_thread(void *arg) { //int *t = (int *)arg; int tSocket = new_s; int len=0; bool removefile = 0; char *crequest=(char *)(malloc(sizeof(char)*BUFFERSIZE)); //cout << "Entered server thread.\n"; ifstream infile; len = read(tSocket,crequest,BUFFERSIZE); //cout << "Recieved request " << crequest << "\n"; if (len <=0) return; string request = crequest; delete(crequest); //cout << "No error yet\n"; int docstart=request.find("GET"); if (docstart==string::npos) return; docstart += 4; int docend=request.find(" HTTP",docstart); if (docend==string::npos) { docend=request.length()-2; } string location = request.substr(docstart,docend-docstart); string query = ""; int qsloc = location.find("?"); if (qsloc!=string::npos) { //cout << "Here's the Error!\n"; query = location.substr(qsloc+1,location.length()-qsloc-1); location = location.substr(0,qsloc); //cout << "Stripped Query String " << query << "\n"; } int floc=location.rfind("/"); if (floc==string::npos) return; int dloc=location.find(".",floc); //add index.html if necessary if (dloc==string::npos) { string tlocation = SERVERROOT; string addme = "/index.html"; if (location.at(location.length()-1)=='/') { addme = "index.html"; } tlocation += location + addme; infile.open(tlocation.c_str(),ios::in); if (infile) { location+=addme; floc=location.rfind("/"); dloc=location.find(".",floc); } infile.close(); } //directory listing if (dloc==string::npos) { cout << "Sending directory " << location << "\n"; string dircommand="ls -l "; dircommand += SERVERROOT; dircommand += location+"> "+location.substr(floc+1,location.length()-1)+".tmp"; system(dircommand.c_str()); location = location.substr(floc+1,location.length()-1)+".tmp"; infile.open(location.c_str(), ios::in); removefile=1; send(tSocket,"HTTP/1.0 200 OK\r\n", strlen("HTTP/1.0 200 OK\r\n"),0); send(tSocket,"Content-type: text/plain\r\n\r\n", strlen("Content-type: text/plain\r\n\r\n"), 0); } //HTML file else if (location.find("cgi",dloc)!=string::npos) { cout << "Running CGI file " << location << "\n"; string servenv = "SERVER_PORT="; servenv+=int2string(SERVERPORT); query = "QUERY_STRING="+query; string content_length = "CONTENT_LENGTH=" + int2string(query.length()); string servname = "SERVER_NAME="; servname+=SERVERNAME; putenv("REQUEST_METHOD=GET"); putenv(servenv.c_str()); putenv(query.c_str()); putenv(content_length.c_str()); putenv(servname.c_str()); string dircommand="cd "; dircommand += SERVERROOT; dircommand += location.substr(0,floc); dircommand += "; ./"+location.substr(floc+1,location.length()-1)+"> "+location.substr(floc+1,location.length()-1)+".tmp"; system(dircommand.c_str()); location = SERVERROOT+location+".tmp"; infile.open(location.c_str(), ios::in); removefile=1; } else { location = SERVERROOT + location; cout << "Looking for file: " << location << "\n"; infile.open(location.c_str(), ios::in); if (!infile) { send(tSocket,"HTTP/1.0 404 error\r\n", strlen("HTTP/1.0 404 error\r\n"),0); send(tSocket,"Content-type: text/html\r\n\r\n", strlen("Content-type: text/html\r\n\r\n"), 0); send(tSocket,getFNFError(location.c_str()),strlen(getFNFError(location.c_str())),0); close(tSocket); return; } //HTML file else if (location.find("htm",dloc)!=string::npos) { send(tSocket,"HTTP/1.0 200 OK\r\n", strlen("HTTP/1.0 200 OK\r\n"),0); send(tSocket,"Content-type: text/html\r\n\r\n", strlen("Content-type: text/html\r\n\r\n"), 0); } //TXT file else if (location.find("txt",dloc)!=string::npos) { send(tSocket,"HTTP/1.0 200 OK\r\n", strlen("HTTP/1.0 200 OK\r\n"),0); send(tSocket,"Content-type: text/plain\r\n\r\n", strlen("Content-type: text/plain\r\n\r\n"), 0); } //CSS file else if (location.find("css",dloc)!=string::npos) { send(tSocket,"HTTP/1.0 200 OK\r\n", strlen("HTTP/1.0 200 OK\r\n"),0); send(tSocket,"Content-type: text/plain\r\n\r\n", strlen("Content-type: text/css\r\n\r\n"), 0); } //GIF file else if (location.find("gif",dloc)!=string::npos) { send(tSocket,"HTTP/1.0 200 OK\r\n", strlen("HTTP/1.0 200 OK\r\n"),0); send(tSocket,"Content-type: image/gif\r\n\r\n", strlen("Content-type: image/gif\r\n\r\n"), 0); } //JPG file else if (location.find("jpg",dloc)!=string::npos) { send(tSocket,"HTTP/1.0 200 OK\r\n", strlen("HTTP/1.0 200 OK\r\n"),0); send(tSocket,"Content-type: image/jpeg\r\n\r\n", strlen("Content-type: image/jpeg\r\n\r\n"), 0); } else { send(tSocket,"HTTP/1.0 404 error\r\n", strlen("HTTP/1.0 404 error\r\n"),0); send(tSocket,"Content-type: text/html\r\n\r\n", strlen("Content-type: text/html\r\n\r\n"), 0); send(tSocket,getFNRError(location.c_str()),strlen(getFNRError(location.c_str())),0); infile.close(); close(tSocket); return; } } //send(tSocket,"What Up!\r\n",strlen("What Up!\r\n"),0); while (!infile.eof()) { unsigned char *finput=(unsigned char *)malloc(BUFFERSIZE*sizeof(char)); //cout << "Reading File\n"; //infile.get(finput, BUFFERSIZE, '\0'); infile.read(finput, BUFFERSIZE); //cout << "Read: " << finput << "\n"; send(tSocket,(char *)finput,infile.gcount(),0);//strlen(finput),0); delete(finput); } infile.close(); close(tSocket); if (removefile) { string dircommand="rm "+location; system(dircommand.c_str()); } } const char *getFNFError(char *location) { string docstuff= location; docstuff = "Error! File Not Found \n

404 Error!

File Not Found

\n Error: The requested file (" + docstuff; docstuff += ") was not found.\n"; return docstuff.c_str(); } const char *getFNRError(char *location) { string docstuff = location; docstuff = "Error! File Not Recognized\n

404 Error!

File Not Recognized

\n Error: the requested file (" + docstuff; docstuff += ") was not recognized.\n"; return docstuff.c_str(); }