├── CMakeLists.txt
├── README.md
├── html_parser.cpp
├── html_parser.h
├── main.cpp
└── main.html
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | project(Basic-Http-Server-cpp)
2 |
3 | find_package( Threads REQUIRED )
4 |
5 | add_executable(server
6 | ${CMAKE_CURRENT_SOURCE_DIR}/html_parser.cpp
7 | ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
8 | )
9 |
10 | if(WIN32)
11 | target_link_libraries(server ws2_32)
12 | endif()
13 |
14 | if(UNIX)
15 | #target_compile_options(server PUBLIC "-pthread") Replaced with
16 | endif()
17 |
18 | target_link_libraries(server Threads::Threads)
19 |
20 | file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/main.html
21 | DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Basic-Http-Server-Cpp
2 | HTTP server implemented in C++ without any third party library.
3 |
4 | * Only used standard libraries
5 |
6 | ## Features
7 |
8 | * Implemented only using GNU C/C++ Library
9 | * Handles GET/POST requests
10 | * Asynchronous request handling
11 | * Multithreaded/Thread Pooling
12 | * Handles over 20,000 concurrent connections.
13 | * Serves over 100,000 requests per second on a modern personal computer
14 | ## Compile and Run
15 |
16 | * Compile with a C++11 compliant compiler:
17 | ```sh
18 | make
19 | ./server
20 | ```
21 | ### Run
22 | It is basic dictionary app. With 2 functions add word to dictionary and check if word contains in the dictionary
23 |
24 | * Check word if it is in the dictionary with Get Request
25 | ```sh
26 | http://127.0.0.1/check?name=EXAMPLE_WORD
27 | ```
28 | * Add word to the dictionary with Post Request
29 | ```sh
30 | http://127.0.0.1/add
31 | Body should contain raw text => "name=test_word"
32 | ```
33 |
34 | 
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | ## Perfonmance Results
43 |
44 | Tested in Ubuntu 18.04 , Intel Core m-5y70 2.6GHZ-8GB-256SSD
45 | * Benchmarking http://127.0.0.1/
46 | ```
47 | kayacan@therion:/home/kayacan# ab -c 10000 -n 100000 http://127.0.0.1/
48 | This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
49 |
50 | Benchmarking 127.0.0.1 (be patient)
51 |
52 | Server Hostname: 127.0.0.1
53 | Server Port: 80
54 |
55 | Document Path: /
56 | Document Length: 468 bytes
57 |
58 | Concurrency Level: 10000
59 | Time taken for tests: 3.385 seconds
60 | Complete requests: 100000
61 | Failed requests: 0
62 | Total transferred: 53500000 bytes
63 | HTML transferred: 46800000 bytes
64 | Requests per second: 29545.55 [#/sec] (mean)
65 | Time per request: 338.461 [ms] (mean)
66 | Time per request: 0.034 [ms] (mean, across all concurrent requests)
67 | Transfer rate: 15436.39 [Kbytes/sec] received
68 |
69 | Connection Times (ms)
70 | min mean[+/-sd] median max
71 | Connect: 0 115 385.7 39 3121
72 | Processing: 1 39 46.1 42 327
73 | Waiting: 0 30 40.9 31 309
74 | Total: 3 154 400.0 83 3248
75 |
76 | ```
77 |
78 |
79 | * Benchmarking Get Request http://127.0.0.1/check?name=EXAMPLE
80 | ```
81 | kayacan@therion:/home/kayacan# ab -c 10000 -n 100000 localhost/check?name=EXAMPLE
82 | This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
83 |
84 |
85 | Server Software:
86 | Server Hostname: localhost
87 | Server Port: 80
88 |
89 | Document Path: /check?name=EXAMPLE
90 | Document Length: 498 bytes
91 |
92 | Concurrency Level: 10000
93 | Time taken for tests: 3.059 seconds
94 | Complete requests: 100000
95 | Failed requests: 0
96 | Total transferred: 56500000 bytes
97 | HTML transferred: 49800000 bytes
98 | Requests per second: 32691.55 [#/sec] (mean)
99 | Time per request: 305.889 [ms] (mean)
100 | Time per request: 0.031 [ms] (mean, across all concurrent requests)
101 | Transfer rate: 18037.82 [Kbytes/sec] received
102 |
103 | Connection Times (ms)
104 | min mean[+/-sd] median max
105 | Connect: 35 122 183.8 84 1148
106 | Processing: 37 100 37.0 93 429
107 | Waiting: 10 52 41.3 41 395
108 | Total: 125 222 198.9 216 1480
109 | ```
110 |
111 |
112 |
113 | * Benchmarking Post Request http://127.0.0.1/add (body="Add_Keyword") #I did not try to add different words yet
114 | ```
115 | kayacan@therion:/home/kayacan# ab -c 10000 -p t -n 100000 http://127.0.0.1/add
116 | This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
117 |
118 | Server Software:
119 | Server Hostname: 127.0.0.1
120 | Server Port: 80
121 |
122 | Document Path: /add
123 | Document Length: 468 bytes
124 |
125 | Concurrency Level: 10000
126 | Time taken for tests: 3.093 seconds
127 | Complete requests: 100000
128 | Failed requests: 0
129 | Total transferred: 53500000 bytes
130 | Total body sent: 13100000
131 | HTML transferred: 46800000 bytes
132 | Requests per second: 32332.34 [#/sec] (mean)
133 | Time per request: 309.288 [ms] (mean)
134 | Time per request: 0.031 [ms] (mean, across all concurrent requests)
135 | Transfer rate: 16892.38 [Kbytes/sec] received
136 | 4136.27 kb/s sent
137 | 21028.65 kb/s total
138 |
139 | Connection Times (ms)
140 | min mean[+/-sd] median max
141 | Connect: 6 87 216.7 36 1100
142 | Processing: 7 43 24.0 40 265
143 | Waiting: 4 26 19.4 24 253
144 | Total: 23 130 220.5 75 1172
145 |
146 | ```
147 |
--------------------------------------------------------------------------------
/html_parser.cpp:
--------------------------------------------------------------------------------
1 | #include "html_parser.h"
2 |
3 |
4 | html_parser::html_parser(char * buffer,int buffer_length)
5 | {
6 | if(buffer_length==0) return ;
7 | std::vector lines;
8 | int header_ends=0;
9 | for (int i = 0; i < buffer_length; i++)
10 | {
11 | std::string a;
12 | while(i=0 && buffer[t]!='\n' && buffer[t]!='=')
47 | t--;
48 | t++;
49 | while(t
2 | #include
3 | #include