├── files ├── himank │ └── myhttpd │ │ ├── H.txt │ │ ├── a.txt │ │ ├── him.txt │ │ ├── sample.html │ │ └── 2.html ├── 1.txt ├── someone │ └── some.txt ├── sample.html ├── 2.html └── page5.html ├── src ├── makefile ├── myhttpd.h ├── senddata.h ├── myserver.h ├── parse.h ├── myserver.cpp ├── myhttpd.cpp ├── senddata.cpp └── parse.cpp ├── .gitattributes ├── ReadMe.md └── .gitignore /files/himank/myhttpd/H.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/himank/myhttpd/a.txt: -------------------------------------------------------------------------------- 1 | File contenet of a.txt 2 | -------------------------------------------------------------------------------- /files/himank/myhttpd/him.txt: -------------------------------------------------------------------------------- 1 | Hi .. How are you ..? 2 | -------------------------------------------------------------------------------- /files/1.txt: -------------------------------------------------------------------------------- 1 | Hello You are getting response from the server. 2 | -------------------------------------------------------------------------------- /files/someone/some.txt: -------------------------------------------------------------------------------- 1 | Hi .. This is inside of some unknown user ..!! 2 | -------------------------------------------------------------------------------- /src/makefile: -------------------------------------------------------------------------------- 1 | objects = myhttpd.o myserver.o senddata.o parse.o 2 | 3 | myhttpd: $(objects) 4 | g++ -o myhttpd $(objects) -lpthread 5 | 6 | myhttpd.o: myhttpd.h myserver.h parse.h 7 | 8 | myserver.o: myserver.h myhttpd.h parse.h 9 | 10 | senddata.o: senddata.h parse.h myhttpd.h 11 | 12 | parse.o: parse.h myhttpd.h senddata.h 13 | 14 | 15 | .PHONY: clean 16 | clean: 17 | -rm edit $(objects) 18 | -------------------------------------------------------------------------------- /files/sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | "Hello, World" 4 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 |
11 |

Multi Threaded Web Server..!

12 |
15 | 16 |

This is the home page for the server

17 |

Made by: Himank Chaudhary 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /files/himank/myhttpd/sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | "Hello, World" 4 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 |
11 |

Multi Threaded Web Server..!

12 |
15 | 16 |

This is the home page for the server

17 |

Made by: Himank Chaudhary 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /files/2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Title 4 | 5 | 6 | 7 |

8 | 9 | 10 |

WELCOME TO Server!

11 |
12 |

13 |

     Hi there! This Server is dedicated to multiple clients in one go ..!.

14 | 15 | 16 | 17 | 18 | 20 |
 Brought to you by: 19 | "H" and Himank Chaudhary
21 | 22 |
     When you are done looking through these masterpieces, I encourage you to visit again!!
23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/myhttpd.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 @HimankChaudhary 2 | // 3 | // Author : Himank Chaudhary 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | #ifndef MYHTTPD_H_ 18 | #define MYHTTPD_H_ 19 | 20 | #include "../src/parse.h" 21 | #include 22 | #include "../src/myserver.h" 23 | extern pthread_mutex_t rqueue_lock; 24 | extern pthread_cond_t rqueue_cond; 25 | extern pthread_mutex_t print_lock; 26 | extern pthread_cond_t print_cond; 27 | extern Parse *P; 28 | class RunServer; 29 | extern int sockId; 30 | extern bool r_daemon; 31 | extern RunServer *run; 32 | 33 | extern string port; 34 | extern bool logging; 35 | extern string scheduling; 36 | extern int threadnum; 37 | extern bool summary; 38 | extern int r_time; 39 | extern string l_file; 40 | extern string rootdir; 41 | 42 | 43 | 44 | #endif // ALLHEADERS_H_ 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/senddata.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 @HimankChaudhary 2 | // 3 | // Author : Himank Chaudhary 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | #include 18 | #ifndef SENDDATA_H_ 19 | #define SENDDATA_H_ 20 | 21 | #include 22 | #include 23 | 24 | using namespace std; 25 | 26 | 27 | class SendData 28 | { 29 | public: 30 | //ifstream::pos_type size; 31 | //SendData(); 32 | void sendData(clientInfo ); 33 | void fileRequestedData(clientInfo ); 34 | void requestPrint(clientInfo ); 35 | void generatingLog(clientInfo ); 36 | void listingDir(clientInfo ); 37 | void displaylog(clientInfo c); 38 | //bool sortDirectory(const string& str1, const string& str2); 39 | 40 | //void sendDataHTML(clientInfo); 41 | 42 | 43 | //static void request_helper(); 44 | 45 | 46 | }; 47 | 48 | 49 | #endif /* SCHEDULING_H_ */ 50 | -------------------------------------------------------------------------------- /src/myserver.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 @HimankChaudhary 2 | // 3 | // Author : Himank Chaudhary 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | #ifndef MYSERVER_H_ 18 | #define MYSERVER_H_ 19 | 20 | #ifndef MAXCONNECTION 21 | #define MAXCONNECTION 10 22 | #endif 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | class RunServer 29 | { 30 | public: 31 | struct addrinfo inValue, *serverInfo, *validInfo; 32 | struct sockaddr_storage clientAddr; 33 | int acceptId, address,yes; 34 | char ip[INET6_ADDRSTRLEN]; 35 | char ip1[INET6_ADDRSTRLEN]; 36 | socklen_t addrlen; 37 | //struct clientInfo *rclientData; 38 | RunServer(); 39 | void accept_connection(); 40 | void *get_ip_address(sockaddr *s); 41 | u_int16_t get_port_number(struct sockaddr *s); 42 | 43 | }; 44 | 45 | #endif /* MYSERVER_H_ */ 46 | -------------------------------------------------------------------------------- /files/himank/myhttpd/2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Title 4 | 5 | 6 | 7 |
8 | 9 | 10 |

WELCOME TO Server!

11 |
12 |

13 |

     Hi there! This Server is dedicated to multiple clients in one go ..!.

14 | 15 | 16 |

17 |
    18 |
  • '' -
  • 19 |
  • '' -
  • 20 |
  • 21 |
      22 |
    • 23 |
    • 24 |
    25 |
26 | 27 | 28 | 29 | 31 |
 Brought to you by: 30 | "H" and Himank Chaudhary
32 | 33 |
     When you are done looking through these masterpieces, I encourage you to visit again!!
34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # Multithreaded Web Server 2 | A web server implemented in C++ on a UNIX based platform so that it can serve multiple incoming client requests. 3 | 4 | ## Overview 5 | The server reads a request (GET or HEAD) from the client and serves the content from the current directory. By default the server is handling multiple requests i.e. queuing thread reads requests from the given port and places the requests in ready queue. Scheduling thread reads the request from the ready queue and based on the scheduling policy issues the request to one of the available worker threads. The worker thread then serves the response back to the client and closes the connection. 6 | 7 | If debug mode is set through the command line then the server will handle only one request at a time. 8 | 9 | Moreover, in case of Head request only file metadata information should be returned. In case of Get request whole file content is returned. 10 | 11 | If the request is for a particular file and that file does not exist then the listing of directory is displaced based on alphabetic order. 12 | 13 | Logging of request is done in a file. 14 | 15 | ## Scheduling 16 | Two scheduling policies are used to serve the requests: 17 | * First come first served. 18 | * Shortest Job First. 19 | 20 | A total of 12 threads are running. A threadpool of initial size (10) + one scheduler thread + main thread. 21 | 22 | By default file directory is set to : "/home/himank/workspace/TeamG14/files" which should be changed based on where the files are present. 23 | 24 | 25 | Command line options, 26 | * myhttpd [-d] [-h] [-l file] [?p port] [-r dir] [-t time] [-n threadnum] [-ssched] 27 | * -d -> It will run in debugging mode. 28 | * -h -> It will show the summary and exit. 29 | * -l file-> It will switch on the logging functionality and use the filename which you will specify in the parameters. Format(eg: /home/timberlake/cse521/log.txt) 30 | * -p portno -> It will change the by default value of port no 8080 to the one you specified. 31 | * -r directory -> Please specify the path here as by default root directory of my system is set. In format(eg: /home/timberlake/cse521/TeamG14 ) 32 | * -t time -> It will change the by default wait time of scheduler thread from 30 seconds to one you specify. 33 | * -n threadnum -> It will change the by default threadpool size of 10 to the number you specify here. 34 | * -s scheduling -> By default it is "FCFC", specify "SJF" here to change the scheduling. 35 | -------------------------------------------------------------------------------- /src/parse.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 @HimankChaudhary 2 | // 3 | // Author : Himank Chaudhary 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | //#include 18 | #ifndef PARSE_H_ 19 | #define PARSE_H_ 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | using namespace::std; 32 | //enum RequestMethod {GET,HEAD,OTHER}; 33 | 34 | //typedef struct clientInfo; 35 | //typedef struct clientIdentity; 36 | struct clientIdentity 37 | { 38 | 39 | int acceptId; 40 | string ip; 41 | int portno; 42 | string requesttime; 43 | }; 44 | struct clientInfo 45 | { 46 | string r_method; 47 | string r_type; 48 | string r_version; 49 | string r_firstline; 50 | //char filename[150]; 51 | string r_filename; 52 | string r_time; 53 | string r_servetime; 54 | int r_acceptid; 55 | string r_ip; 56 | u_int16_t r_portno; 57 | int r_filesize; 58 | bool status_file; 59 | string r_ctype; 60 | bool rootcheck; 61 | int status_code; 62 | 63 | }; 64 | 65 | class Parse 66 | { 67 | public: 68 | //struct clientInfo cInfo; 69 | 70 | 71 | 72 | //char *parseWord[4], 73 | 74 | list clientlist; 75 | list requestlist; 76 | //vector dirlist; 77 | //Parse(); 78 | //Parse(clientIdentity *); 79 | //static void * parseRequest_helper(void *c); 80 | bool fileExists(char *filename); 81 | void parseRequest(clientIdentity); 82 | void readyQueue(clientInfo ); 83 | void checkRequest(clientInfo); 84 | void fileRequestedData(); 85 | //void schedulerThread(); 86 | void popRequest(); 87 | static void *popRequest_helper(void *); 88 | void serveRequest(); 89 | static void *serveRequest_helper(void *); 90 | void changeFolder(clientInfo); 91 | 92 | 93 | }; 94 | #endif /* PARSE_H_ */ 95 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | -------------------------------------------------------------------------------- /src/myserver.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 @HimankChaudhary 2 | // 3 | // Author : Himank Chaudhary 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "../src/myserver.h" 25 | #include "../src/parse.h" 26 | #include "../src/myhttpd.h" 27 | 28 | using namespace std; 29 | 30 | // Set Default values 31 | RunServer::RunServer() 32 | { 33 | memset(&inValue, 0, sizeof(inValue)); 34 | inValue.ai_family = AF_UNSPEC; 35 | inValue.ai_socktype = SOCK_STREAM; 36 | inValue.ai_flags = AI_PASSIVE; 37 | yes=1; 38 | } 39 | 40 | // Return Port Number 41 | u_int16_t RunServer::get_port_number(struct sockaddr *s) 42 | { 43 | if(s->sa_family == AF_INET) 44 | return (((struct sockaddr_in *)s)->sin_port); 45 | else 46 | return (((struct sockaddr_in6 *)s)->sin6_port); 47 | } 48 | 49 | //Return Ip address 50 | void * RunServer::get_ip_address(sockaddr *s) 51 | { 52 | if(s->sa_family == AF_INET) 53 | return &((sockaddr_in *)s)->sin_addr; 54 | else 55 | return &((sockaddr_in6 *)s)->sin6_addr; 56 | } 57 | 58 | // This function will create the socket for all the incoming client connections & update the client structure and pass 59 | // this structure to Parse class 60 | void RunServer::accept_connection() 61 | { 62 | //struct sockaddr_in serverInfo; 63 | 64 | if (getaddrinfo(NULL, port.c_str(), &inValue, &serverInfo) != 0) 65 | perror("Get Address:"); 66 | 67 | for(validInfo = serverInfo; validInfo != NULL; validInfo = validInfo->ai_next) { 68 | if((sockId = (socket(validInfo->ai_family, validInfo->ai_socktype,0))) == -1) 69 | perror("Socket:"); 70 | 71 | addrlen = sizeof(serverInfo); 72 | 73 | if (setsockopt(sockId, SOL_SOCKET, SO_REUSEADDR, &yes,sizeof(int)) == -1){ 74 | perror("setsockopt"); 75 | break; 76 | } 77 | 78 | if(bind(sockId,validInfo->ai_addr, validInfo->ai_addrlen) == -1) 79 | perror("Bind:"); 80 | 81 | break; 82 | } 83 | 84 | // successfully done with bind 85 | 86 | struct sockaddr_in *ipv4 = (struct sockaddr_in *)validInfo->ai_addr; 87 | void *addr; 88 | addr = &(ipv4->sin_addr); 89 | inet_ntop(validInfo->ai_family,addr, ip, sizeof(ip)); 90 | freeaddrinfo(serverInfo); 91 | if(listen(sockId, MAXCONNECTION) == -1) 92 | perror("Listen:"); 93 | 94 | while(true) { // Main thread will listen continously 95 | address = sizeof(clientAddr); 96 | 97 | if((acceptId = accept(sockId,(struct sockaddr*)&clientAddr,(socklen_t *)&address)) == -1) 98 | perror("Accept:"); 99 | 100 | inet_ntop(clientAddr.ss_family,get_ip_address((struct sockaddr *)&clientAddr),ip1, sizeof(ip1)); 101 | u_int16_t clientport = get_port_number((struct sockaddr *)&(validInfo)); 102 | time_t tim=time(NULL); 103 | tm *now=gmtime(&tim); 104 | char currtime[50]; 105 | 106 | if (strftime(currtime, 50,"%x:%X", now) == 0) 107 | perror("Date Error"); 108 | 109 | string requesttime(currtime); 110 | clientIdentity cid; 111 | cid.acceptId = acceptId; 112 | string s(ip1); 113 | cid.ip=s; 114 | cid.portno = clientport; 115 | cid.requesttime = requesttime; 116 | P->parseRequest(cid); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/myhttpd.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 @HimankChaudhary 2 | // 3 | // Author : Himank Chaudhary 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | #include 18 | #include 19 | #include 20 | #include "../src/myhttpd.h" 21 | #include "../src/myserver.h" 22 | #include "../src/parse.h" 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | 30 | string port = "8080"; 31 | bool r_daemon = false; 32 | bool logging = false; 33 | string scheduling ="FCFS"; 34 | int threadnum = 10; 35 | bool summary = false; 36 | int r_time = 30; 37 | string l_file ="log.txt"; 38 | string rootdir ="/home/himank/workspace/TeamG14/files"; 39 | 40 | using namespace std; 41 | 42 | 43 | //bool r_daemon = false; 44 | int sockId =0; 45 | Parse *P = new Parse(); 46 | pthread_mutex_t rqueue_lock; 47 | pthread_cond_t rqueue_cond; 48 | pthread_mutex_t print_lock; 49 | pthread_cond_t print_cond; 50 | pthread_t thread_scheduler; 51 | pthread_t threads[30]; 52 | RunServer *run = new RunServer(); 53 | sig_atomic_t flag =0; 54 | 55 | void signal_callback_handler(int signum) 56 | { 57 | //close(sockId); 58 | //delete P; 59 | //P= null; 60 | //exit(signum); 61 | flag++; 62 | close(sockId); 63 | delete P; 64 | P = NULL; 65 | delete run; 66 | run = NULL; 67 | pthread_exit(NULL); 68 | exit(signum); 69 | } 70 | 71 | void printh() 72 | { 73 | cout<accept_connection(); 138 | 139 | if(summary) { 140 | printh(); 141 | } else { 142 | if (pthread_mutex_init(&rqueue_lock, NULL) != 0) { 143 | printf("\n mutex init failed\n"); 144 | return 1; 145 | } 146 | pthread_mutex_init(&print_lock, NULL); 147 | pthread_cond_init (&rqueue_cond, NULL); 148 | pthread_cond_init (&print_cond, NULL); 149 | pthread_create(&thread_scheduler,NULL,&Parse::popRequest_helper,P); 150 | 151 | for(int i =0;iaccept_connection(); 155 | 156 | pthread_mutex_destroy(&rqueue_lock); 157 | pthread_cond_destroy(&rqueue_cond); 158 | pthread_mutex_destroy(&print_lock); 159 | pthread_cond_destroy(&print_cond); 160 | pthread_exit(NULL); 161 | } 162 | 163 | signal(SIGINT, signal_callback_handler); 164 | close(sockId); 165 | delete P; 166 | P = NULL; 167 | delete run; 168 | run = NULL; 169 | return 0; 170 | } 171 | -------------------------------------------------------------------------------- /src/senddata.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 @HimankChaudhary 2 | // 3 | // Author : Himank Chaudhary 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "../src/parse.h" 34 | #include "../src/senddata.h" 35 | #include"../src/myhttpd.h" 36 | using namespace std; 37 | 38 | void SendData::sendData(clientInfo c) // Sending data 39 | { 40 | if(c.status_file ==true && c.r_type =="GET") { 41 | char currtime[50]; 42 | char lastmodify[50]; 43 | struct stat buf; 44 | time_t tim=time(NULL); 45 | tm *now=gmtime(&tim); 46 | 47 | if (strftime(currtime, 50,"%c", now) == 0) 48 | perror("Date Error"); 49 | char * fname = new char[c.r_filename.size() + 1]; 50 | std::copy(c.r_filename.begin(), c.r_filename.end(), fname); 51 | fname[c.r_filename.size()] = '\0'; 52 | stat(fname,&buf); 53 | strcpy(lastmodify,ctime(&buf.st_mtime)); 54 | delete[] fname; 55 | fname = NULL; 56 | int pos = c.r_filename.find_last_of("."); 57 | string c_type = c.r_filename.substr(pos+1,c.r_filename.size()); 58 | 59 | // Type of file requested 60 | if (c_type == "txt" || c_type == "html" || c_type == "htm") 61 | c.r_ctype ="text/html"; 62 | else if(c_type == "gif" || c_type == "jpeg") 63 | c.r_ctype = "image/"+c_type; 64 | else 65 | c.r_ctype = " "; 66 | 67 | std::stringstream ss; 68 | ss << c.r_filesize; 69 | string filesize = ss.str(); 70 | string header = c.r_type + " "+ c.r_method +" 200 OK\r\nDate: "; 71 | string time(currtime); 72 | header = header + time; 73 | header = header +"\r\n" +"Server: myhttpd 1.0\r\n" + "Last-Modified:"; 74 | string lmodify(lastmodify); 75 | header = header + lmodify ;//+"\r\n"; 76 | header = header + "Content-Type:" + c.r_ctype +"\r\n" + "Content-Length:" + filesize +"\r\n\r\n"; 77 | 78 | if (send(c.r_acceptid, header.c_str(), strlen(header.c_str()), 0) == -1) 79 | perror("send"); 80 | 81 | ifstream file; 82 | char *readblock; 83 | size_t size; 84 | file.open(c.r_filename.c_str()); 85 | if (file.is_open()) { 86 | string read; 87 | file.seekg (0, ios::end); 88 | size = file.tellg(); 89 | readblock = new char [size]; 90 | file.seekg (0, ios::beg); 91 | file.read(readblock, size); 92 | } else { 93 | cout<<"Never went Inside"< tolower( *rit ) ) 198 | return false; 199 | if( left.size() < right.size() ) 200 | return true; 201 | return false; 202 | } 203 | 204 | // List the directory 205 | void SendData::listingDir(clientInfo c) 206 | { 207 | struct dirent *de=NULL; 208 | DIR *d=NULL; 209 | int last = c.r_filename.find_last_of("/"); 210 | string dir = c.r_filename.substr(0,last); 211 | vector dirlist; 212 | char * dirname = new char[dir.size() + 1]; 213 | std::copy(dir.begin(), dir.end(), dirname); 214 | dirname[dir.size()] = '\0'; 215 | d=opendir(dirname); 216 | if(d == NULL) { 217 | // perror("Couldn't open directory"); 218 | write(c.r_acceptid,"Error 404: Directory Not Found",30); 219 | c.status_code = 404; 220 | } else { 221 | while(de = readdir(d)) { 222 | string s(de->d_name); 223 | dirlist.push_back(s); 224 | } 225 | 226 | vector::iterator it; 227 | std::sort(dirlist.begin(),dirlist.end(), sortDirectory); 228 | write(c.r_acceptid,"Files Listing:",14); 229 | for ( it=dirlist.begin() ; it < dirlist.end(); it++ ) { 230 | write(c.r_acceptid, (*it).c_str(), strlen((*it).c_str())); 231 | write(c.r_acceptid,"\n",1); 232 | } 233 | 234 | closedir(d); 235 | 236 | delete [] dirname; 237 | dirname = NULL; 238 | } 239 | } 240 | 241 | 242 | 243 | -------------------------------------------------------------------------------- /src/parse.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 @HimankChaudhary 2 | // 3 | // Author : Himank Chaudhary 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "../src/myhttpd.h" 31 | #include "../src/parse.h" 32 | #include "../src/senddata.h" 33 | #include 34 | #include 35 | 36 | 37 | using namespace std; 38 | 39 | // This function have the current client structure, this function will parse the request and fill the fields 40 | void Parse::parseRequest(clientIdentity c_id) 41 | { 42 | int i=1; 43 | int recvbytes=0; 44 | char buffer[1024]; 45 | clientInfo cInfo; 46 | 47 | char *p,*pbuffer; 48 | 49 | fcntl( c_id.acceptId, O_NONBLOCK, 0 ); 50 | 51 | if((recvbytes = (recv(c_id.acceptId, buffer, sizeof(buffer),0))) == -1) 52 | perror("Receive:"); 53 | buffer[recvbytes] = '\0'; 54 | string tofetchfline(buffer); 55 | 56 | int current = 0; 57 | int next = tofetchfline.find_first_of("\r\n", current ); 58 | if(next < 0) { 59 | write(cInfo.r_acceptid,"Error: Bad Request, Retry",25); 60 | close (cInfo.r_acceptid); 61 | } else { 62 | cInfo.r_firstline = tofetchfline.substr( current, next - current); 63 | string parseWord[3]; 64 | pbuffer = new char[cInfo.r_firstline.size() + 1]; 65 | std::copy(cInfo.r_firstline.begin(), cInfo.r_firstline.end(), pbuffer); 66 | pbuffer[cInfo.r_firstline.size()] = '\0'; 67 | 68 | p=strtok (pbuffer," /"); 69 | parseWord[0].assign(p); 70 | while (i < 3) { 71 | p=strtok(NULL," "); 72 | parseWord[i].assign(p); 73 | i++; 74 | } 75 | 76 | cInfo.r_acceptid = c_id.acceptId; 77 | cInfo.r_portno = c_id.portno; 78 | cInfo.r_ip = c_id.ip; 79 | cInfo.r_time = c_id.requesttime; 80 | cInfo.r_type = parseWord[0]; 81 | cInfo.r_filename = parseWord[1]; 82 | 83 | int ii = cInfo.r_filename.find_first_of("/",0); 84 | int jj = cInfo.r_filename.find_first_of("/",ii+1); 85 | if(jj >= 0) 86 | cInfo.rootcheck = false; 87 | else 88 | cInfo.rootcheck = true; 89 | cInfo.r_filename = rootdir + cInfo.r_filename; 90 | cInfo.r_method = parseWord[2]; 91 | 92 | delete [] pbuffer; 93 | pbuffer = NULL; 94 | changeFolder(cInfo); 95 | } 96 | } 97 | 98 | // If tilt is present in the client request then change the folder 99 | void Parse::changeFolder(clientInfo c) 100 | { 101 | int next = c.r_filename.find_first_of("~",0); 102 | int size = c.r_filename.size(); 103 | if(next > 0 && next < size) { 104 | int pos = c.r_filename.find_first_of("/",next); 105 | string requestfor = c.r_filename.substr(next+1,pos -(next+1)); 106 | string restString = c.r_filename.substr(pos,c.r_filename.size()-pos); 107 | c.r_filename.erase(next,c.r_filename.size()); 108 | c.r_filename = c.r_filename + requestfor +"/myhttpd" +restString; 109 | } 110 | 111 | checkRequest(c); 112 | } 113 | 114 | // if file requested exists or not 115 | bool Parse::fileExists(char *filename) 116 | { 117 | struct stat filenamecheck; 118 | if (stat(filename, &filenamecheck) != -1) 119 | return true; 120 | 121 | return false; 122 | } 123 | 124 | // Check type of request 125 | void Parse::checkRequest(clientInfo cInfo) 126 | { 127 | 128 | int pos = cInfo.r_filename.find_last_of("/"); 129 | int next = cInfo.r_filename.find_first_of(".",pos); 130 | if(next > 0) { 131 | char * fname = new char[cInfo.r_filename.size() + 1]; 132 | std::copy(cInfo.r_filename.begin(), cInfo.r_filename.end(), fname); 133 | fname[cInfo.r_filename.size()] = '\0'; 134 | ifstream::pos_type size = 0; 135 | 136 | if(fileExists(fname) && cInfo.r_type == "GET") { 137 | ifstream file; 138 | file.open(fname); 139 | if (file.is_open()) { 140 | file.seekg (0, ios::end); 141 | size = file.tellg(); 142 | } 143 | cInfo.status_file = true; 144 | cInfo.r_filesize = (int)size; 145 | file.close(); 146 | delete [] fname; 147 | fname = NULL; 148 | if(r_daemon) { 149 | SendData S; 150 | S.sendData(cInfo); 151 | } else { 152 | readyQueue(cInfo); 153 | } 154 | } else if(fileExists(fname) && cInfo.r_type == "HEAD") { 155 | cInfo.status_file = true; 156 | cInfo.r_filesize = 0; 157 | delete [] fname; 158 | fname = NULL; 159 | if(r_daemon) { 160 | SendData S; 161 | S.sendData(cInfo); 162 | } else { 163 | readyQueue(cInfo); 164 | } 165 | } else { 166 | delete [] fname; 167 | fname = NULL; 168 | cInfo.r_filesize = 0; 169 | cInfo.status_file = false; 170 | if(r_daemon) { 171 | SendData S; 172 | S.sendData(cInfo); 173 | } else { 174 | readyQueue(cInfo); 175 | } 176 | } 177 | } else { 178 | cInfo.r_filesize = 0; 179 | cInfo.status_file = false; 180 | if(r_daemon) { 181 | SendData S; 182 | S.sendData(cInfo); 183 | } else { 184 | readyQueue(cInfo); 185 | } 186 | } 187 | } 188 | 189 | 190 | // Sort the request based on file size 191 | bool sortRequest(const clientInfo& lhs, const clientInfo& rhs) 192 | { 193 | return lhs.r_filesize < rhs.r_filesize; 194 | } 195 | 196 | // Here main thread will put the request in the queue 197 | void Parse::readyQueue(clientInfo cInfo) 198 | { 199 | pthread_mutex_lock(&rqueue_lock); 200 | clientlist.push_back(cInfo); 201 | pthread_cond_signal(&rqueue_cond); 202 | pthread_mutex_unlock(&rqueue_lock); 203 | } 204 | 205 | // In this scheduler thread will fetch the request from the queue based on the scheduling policies 206 | void Parse::popRequest() 207 | { 208 | sleep(r_time); 209 | while(1) { 210 | clientInfo c; 211 | transform(scheduling.begin(), scheduling.end(),scheduling.begin(),::toupper); 212 | if(scheduling =="SJF") { 213 | pthread_mutex_lock(&rqueue_lock); 214 | 215 | while(clientlist.empty()) 216 | pthread_cond_wait(&rqueue_cond, &rqueue_lock); 217 | 218 | clientlist.sort(sortRequest); 219 | c = clientlist.front(); 220 | clientlist.pop_front(); 221 | pthread_mutex_unlock(&rqueue_lock); 222 | } else { 223 | pthread_mutex_lock(&rqueue_lock); 224 | while(clientlist.empty()) 225 | pthread_cond_wait(&rqueue_cond, &rqueue_lock); 226 | c = clientlist.front(); 227 | clientlist.pop_front(); 228 | pthread_mutex_unlock(&rqueue_lock); 229 | } 230 | 231 | pthread_mutex_lock(&print_lock); 232 | requestlist.push_back(c); 233 | pthread_cond_signal(&print_cond); 234 | pthread_mutex_unlock(&print_lock); 235 | } 236 | } 237 | 238 | void *Parse::popRequest_helper(void *c) 239 | { 240 | //Parse *P =(Parse *)c; 241 | //P->popRequest(); 242 | ((Parse *)c)->popRequest(); 243 | //delete P; 244 | return NULL; 245 | } 246 | 247 | void *Parse::serveRequest_helper(void *c) 248 | { 249 | Parse *P1 =(Parse *)c; 250 | P1->serveRequest(); 251 | return NULL; 252 | } 253 | 254 | // In this function contionsly threads are acting to serve the client request. 255 | void Parse::serveRequest() 256 | { 257 | pthread_detach(pthread_self()); 258 | while(1) { 259 | pthread_mutex_lock(&print_lock); 260 | 261 | while(requestlist.empty()) 262 | pthread_cond_wait(&print_cond, &print_lock); 263 | 264 | SendData S; 265 | clientInfo c; 266 | c = requestlist.front(); 267 | requestlist.pop_front(); 268 | time_t tim=time(NULL); 269 | tm *now=gmtime(&tim); 270 | char currtime[50]; 271 | if (strftime(currtime, 50,"%x:%X", now) == 0) 272 | perror("Date Panga"); 273 | string servetime(currtime); 274 | c.r_servetime = servetime; 275 | pthread_mutex_unlock(&print_lock); 276 | S.sendData(c); 277 | } 278 | } 279 | -------------------------------------------------------------------------------- /files/page5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Contact Us 8 | 9 | 10 | 11 | 12 | 55 | 56 | 57 | 59 | 60 | 61 | 62 |
63 | 64 |
65 |
66 |     Himank Chaudhary
67 |
68 | 92 | 96 |
97 |

Mail

98 |
99 |           100 | 101 |
102 |
103 | Email
104 |
105 |
106 |

Social Networking

107 |

             

108 |

 

109 |

@HimankChaudhary

110 |

 

111 |
112 |
113 |

himankch@buffalo.edu

114 |

himank.tomar@gmail.com

115 |

himank.chaudhary@hotmail.com

116 |

 

117 |
118 |
119 | 120 |
121 | 122 | 123 | 124 | 125 | 126 | 127 |
128 | 129 | --------------------------------------------------------------------------------