├── 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 |
11 | Multi Threaded Web Server..!
12 | |
13 |
14 |
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 |
11 | Multi Threaded Web Server..!
12 | |
13 |
14 |
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 | WELCOME TO Server! |
10 |
11 |
12 |
13 | Hi there! This Server is dedicated to multiple clients in one go ..!.
14 |
15 |
16 |
17 | | |
18 | Brought to you by:
19 | "H" and Himank Chaudhary |
20 |
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 | WELCOME TO Server! |
10 |
11 |
12 |
13 | Hi there! This Server is dedicated to multiple clients in one go ..!.
14 |
15 |
16 |
17 |
18 | - '' -
19 | - '' -
20 | -
21 |
25 |
26 |
27 |
28 | | |
29 | Brought to you by:
30 | "H" and Himank Chaudhary |
31 |
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 |
99 |

100 |

101 |
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 |
All Rights Reserved @ himank-chaudhary 2012
120 |
121 |

122 |

123 |

124 |

125 |

126 |

127 |
128 |
129 |
--------------------------------------------------------------------------------