//Bobpache web server //Bob Lindquist #include #include #include #include #include #include #include #include #include #include #include #include const int BUFSIZE=10000; #define START_PAGE "/root/bobpache/index.html" #define ERROR_PATH "/root/bobpache/error.html" #define BAD_REQUEST "/root/bobpache/badrequest.html" int WriteFile(int socket,char *path,ofstream *out,int ip); void WriteMeta(int socket,char *path,char *version); int MakeServerSocket(char *port) { const int MAXNAMELEN = 255; //longest a name can be const int BACKLOG = 3; //max number of queued connections char localhostname[MAXNAMELEN]; // local host name int s; //file descriptor struct sockaddr_in sa; //gotta love arcane socket types struct hostent *hp; //host entry struct servent *sp; //service entry int portnum;//stores the port int ret; //error code form bind gethostname(localhostname,MAXNAMELEN); hp = gethostbyname(localhostname); //no need to check for error here because localhost will resolve sscanf(port, "%d", &portnum); if (portnum == 0) { sp=getservbyname(port, "tcp"); if (sp==NULL) { perror("server.cc line 37:"); return -1; } portnum = ntohs(sp->s_port); } sa.sin_port = htons(portnum); bcopy((char *)hp->h_addr, (char *)&sa.sin_addr, hp->h_length); sa.sin_family = hp->h_addrtype; s = socket(hp->h_addrtype, SOCK_STREAM, 0); if (s==-1) { perror("server.cc line 50:"); return -1; } ret = bind(s, (struct sockaddr *)&sa, sizeof(sa)); if (ret==-1) { perror("server.cc line 55:"); return -1; } ret=listen(s, BACKLOG); if (ret==-1) { perror("server.cc line 62:"); return -1; } cout << "Waiting for connection on port " << port << endl; return s; } int main(int argc, char *argv[]) { int s=-1; // socket descriptor int len; // length of reveived data char buf[BUFSIZE]; // buffer in which to read int ret; // return code from various system calls char temp[BUFSIZE]; // if they didnt specify a port char ip[BUFSIZE]; int addr; //shorter than typing sa.sin_addr.s_addr ofstream log("access_log"); ofstream error("error_log"); struct sockaddr_in sa;//window to the world int sa_len = sizeof(sa);//how big is our window if (argc!=2) cout << "Usage: bobpache [port]" << endl << "Get it right next time buddy!" << endl; else { s = MakeServerSocket(argv[1]); } if (s!=-1) while (1) { int fd2,len2; char get[BUFSIZE]; float version=0; char *tmpver; char path[BUFSIZE]; char *thePath; char protocol[BUFSIZE]; int fd = accept(s, (struct sockaddr *)&sa, (unsigned int *)&sa_len); //file descriptor we talk out of int tempCount=0; time_t hmm=time(NULL); struct tm *current=localtime(&hmm); addr=sa.sin_addr.s_addr; sprintf(ip,"%i.%i.%i.%i",(addr)&0xFF,(addr>>8)&0xFF,(addr>>16)&0xFF,(addr>>24)&0xFF); cout << "Connection: "; cout << " address is " << ip; cout << " family " << sa.sin_family; cout << " port " << ntohs(sa.sin_port); cout << endl; whosyourdaddy: len=read(fd,buf,1024); buf[len]=0; //if (buf[0]!='G'||buf[1]!='E'||buf[2]!='T'||buf[3]!=' ') goto end; cout << buf << endl; sscanf(buf,"%s %s %s",get,path,protocol); cout << "get=" << get << "=" << endl << "protocol=" << protocol << endl << "path="<tm_mday << "/" << current->tm_mon<< "/" << current->tm_year+1900 << ":" << current->tm_hour << ":" << current->tm_min << ":" << current->tm_sec << "-"<< (timezone/60/60>=10?"":"0")<tm_wday==0) tmp="Sat"; else if (current->tm_wday==1) tmp="Sun"; else if (current->tm_wday==2) tmp="Mon"; else if (current->tm_wday==3) tmp="Tue"; else if (current->tm_wday==4) tmp="Wed"; else if (current->tm_wday==5) tmp="Thu"; else if (current->tm_wday==6) tmp="Fri"; else tmp="Bob"; char *tmp2; if (current->tm_mon==0) tmp2="Jan"; else if (current->tm_mon==1) tmp2="Feb"; else if (current->tm_mon==2) tmp2="Mar"; else if (current->tm_mon==3) tmp2="Apr"; else if (current->tm_mon==4) tmp2="May"; else if (current->tm_mon==5) tmp2="Jun"; else if (current->tm_mon==6) tmp2="Jul"; else if (current->tm_mon==7) tmp2="Aug"; else if (current->tm_mon==8) tmp2="Sep"; else if (current->tm_mon==9) tmp2="Oct"; else if (current->tm_mon==10) tmp2="Nov"; else if (current->tm_mon==11) tmp2="Dec"; else tmp2="Bob"; //tmp,current->tm_mday,tmp2,current->tm_year+1900,current->tm_hour,current->tm_min,current->tm_sec); *error << "[" << tmp << " " << tmp2 << " " <tm_mday << " "<tm_hour << ":" << current->tm_min << ":" << current->tm_sec << " GMT " << current->tm_year+1900 << "] [error] [client " << (ip&0xFF) << "." << ((ip>>8)&0xFF) << "."<< ((ip>>16)&0xFF) << "." << ((ip>>24)&0xFF) << "] File does not exist: " << path<< endl; sprintf(buf,"HTTP/1.0 400 File not Found\n"); len=write(socket,buf,strlen(buf)); do { len2=read(fd2,buf,BUFSIZE); count+=len2; if (len2>0) len=write(socket,buf,len2); } while(len2>0); } else { { do { len2=read(fd2,buf,BUFSIZE); count+=len2; if (len2>0) len=write(socket,buf,len2); } while(len2>0); } } return count; } void WriteMeta(int socket,char *path,char *version) { char buf[BUFSIZE]; int theCount=0,len=0; int fd=open(path,O_RDONLY,0); if (fd==-1) { perror( "file not open:"); return; } do { len=read(fd,buf,BUFSIZE); if (len>0) theCount+=len; } while(len>0); close(fd); sprintf(buf,"HTTP/%s 200 Ok\n",version); len=write(socket,buf,strlen(buf)); //write date time_t hmm=time(NULL); struct tm *current=gmtime(&hmm); char *tmp; if (current->tm_wday==0) tmp="Sat"; else if (current->tm_wday==1) tmp="Sun"; else if (current->tm_wday==2) tmp="Mon"; else if (current->tm_wday==3) tmp="Tue"; else if (current->tm_wday==4) tmp="Wed"; else if (current->tm_wday==5) tmp="Thu"; else if (current->tm_wday==6) tmp="Fri"; else tmp="Bob"; char *tmp2; if (current->tm_mon==0) tmp2="Jan"; else if (current->tm_mon==1) tmp2="Feb"; else if (current->tm_mon==2) tmp2="Mar"; else if (current->tm_mon==3) tmp2="Apr"; else if (current->tm_mon==4) tmp2="May"; else if (current->tm_mon==5) tmp2="Jun"; else if (current->tm_mon==6) tmp2="Jul"; else if (current->tm_mon==7) tmp2="Aug"; else if (current->tm_mon==8) tmp2="Sep"; else if (current->tm_mon==9) tmp2="Oct"; else if (current->tm_mon==10) tmp2="Nov"; else if (current->tm_mon==11) tmp2="Dec"; else tmp2="Bob"; sprintf(buf,"Date: %s, %i %s %i %i:%i:%i GMT\n",tmp,current->tm_mday,tmp2,current->tm_year+1900,current->tm_hour,current->tm_min,current->tm_sec); len=write(socket,buf,strlen(buf)); sprintf(buf,"Server: bobpache/1.0\n"); len=write(socket,buf,strlen(buf)); //write modified struct stat info; len=stat(path,&info); time_t t=info.st_mtime; struct tm *current2=localtime(&t); if (current2->tm_wday==0) tmp="Sat"; else if (current2->tm_wday==1) tmp="Sun"; else if (current2->tm_wday==2) tmp="Mon"; else if (current2->tm_wday==3) tmp="Tue"; else if (current2->tm_wday==4) tmp="Wed"; else if (current2->tm_wday==5) tmp="Thu"; else if (current2->tm_wday==6) tmp="Fri"; else tmp="Bob"; if (current2->tm_mon==0) tmp2="Jan"; else if (current2->tm_mon==1) tmp2="Feb"; else if (current2->tm_mon==2) tmp2="Mar"; else if (current2->tm_mon==3) tmp2="Apr"; else if (current2->tm_mon==4) tmp2="May"; else if (current2->tm_mon==5) tmp2="Jun"; else if (current2->tm_mon==6) tmp2="Jul"; else if (current2->tm_mon==7) tmp2="Aug"; else if (current2->tm_mon==8) tmp2="Sep"; else if (current2->tm_mon==9) tmp2="Oct"; else if (current2->tm_mon==10) tmp2="Nov"; else if (current2->tm_mon==11) tmp2="Dec"; else tmp2="Bob"; sprintf(buf,"Last-Modified: %s, %i %s %i %i:%i:%i GMT\n",tmp,current2->tm_mday,tmp2,current2->tm_year+1900,current2->tm_hour,current2->tm_min,current2->tm_sec); len=write(socket,buf,strlen(buf)); sprintf(buf,"Content-Length: %i\n\n",theCount); len=write(socket,buf,strlen(buf)); // sprintf(buf,"Connection: close\n\n"); // len=write(socket,buf,strlen(buf)); }