v0.1.1
This commit is contained in:
parent
38359bd957
commit
d6eb46d310
53
CHANGELOG.md
53
CHANGELOG.md
|
@ -1,3 +1,56 @@
|
|||
# 0.1.1 Third Pre-Release
|
||||
|
||||
- Add mappings for common MIME types
|
||||
- Heavily improved resource utilization
|
||||
- Removed non-cached file backend
|
||||
- Updated dockerfile to remove build files after build
|
||||
|
||||
## Known Issues
|
||||
|
||||
- Benchmark program does not include resource utilization
|
||||
|
||||
## Benchmark Results
|
||||
|
||||
Each benchmark makes 1000 requests requesting a 21.9Mb file using
|
||||
100 users to the webserver running in a Docker container.
|
||||
|
||||
The results from this benchmark vary quite a bit. About half the time,
|
||||
Apache can beat anthracite.
|
||||
|
||||
```
|
||||
=====[ Anthracite Benchmarking Tool ]=====
|
||||
Requests : 1000
|
||||
Users/Threads: 100
|
||||
|
||||
|
||||
====[ anthracite ]=====
|
||||
Average Response Time: 5.5128 seconds
|
||||
p995 Response Time : 8.3105 seconds
|
||||
p99 Response Time : 8.1796 seconds
|
||||
p90 Response Time : 6.4393 seconds
|
||||
p75 Response Time : 5.8587 seconds
|
||||
p50 Response Time : 5.4393 seconds
|
||||
Total Response Time : 5512.8397 seconds
|
||||
====[ nginx ]=====
|
||||
Average Response Time: 6.0201 seconds
|
||||
p995 Response Time : 12.4648 seconds
|
||||
p99 Response Time : 11.9635 seconds
|
||||
p90 Response Time : 8.7204 seconds
|
||||
p75 Response Time : 6.7331 seconds
|
||||
p50 Response Time : 5.5341 seconds
|
||||
Total Response Time : 6020.1369 seconds
|
||||
====[ apache ]=====
|
||||
Average Response Time: 5.9795 seconds
|
||||
p995 Response Time : 12.8266 seconds
|
||||
p99 Response Time : 11.6336 seconds
|
||||
p90 Response Time : 7.1465 seconds
|
||||
p75 Response Time : 6.4420 seconds
|
||||
p50 Response Time : 5.8224 seconds
|
||||
Total Response Time : 5979.5446 seconds
|
||||
==========
|
||||
Total Test Time : 179.7469 seconds
|
||||
```
|
||||
|
||||
# 0.1.0 Second Pre-Release
|
||||
|
||||
- Allowed multiple clients to be handled at once via multithreadding
|
||||
|
|
|
@ -4,4 +4,9 @@ RUN apk add --no-cache build-base
|
|||
COPY ./src/ .
|
||||
RUN make build-release
|
||||
|
||||
FROM alpine
|
||||
RUN apk add --no-cache build-base
|
||||
COPY --from=build-env /anthracite /anthracite
|
||||
COPY --from=build-env /www /www
|
||||
COPY --from=build-env /error_pages /error_pages
|
||||
CMD ["/anthracite"]
|
||||
|
|
|
@ -34,6 +34,7 @@ def make_request(request_number, server_name):
|
|||
response_times[server_name].append(response_time)
|
||||
else:
|
||||
print(f'Request {request_number}: Request failed with status code {response.status_code}')
|
||||
|
||||
print('=====[ Anthracite Benchmarking Tool ]=====')
|
||||
print(f'Requests : {num_requests}')
|
||||
print(f'Users/Threads: {num_users}\n\n')
|
||||
|
|
|
@ -12,6 +12,9 @@ build-docker:
|
|||
run: build
|
||||
./anthracite 8080
|
||||
|
||||
run-test: build
|
||||
./anthracite 8080 ./test_www
|
||||
|
||||
debug: build
|
||||
gdb --args ./anthracite 8080
|
||||
|
||||
|
|
|
@ -4,28 +4,11 @@
|
|||
class file_backend : public backend {
|
||||
private:
|
||||
unordered_map<string, string> file_cache;
|
||||
bool cache_enabled;
|
||||
|
||||
unique_ptr<http_response> handle_request_nocache(http_request& req) {
|
||||
string filename = req.path() == "/" ? "index.html" : req.path();
|
||||
filename = "./www/" + filename;
|
||||
ifstream stream(filename);
|
||||
|
||||
int status = 200;
|
||||
if (!stream.is_open()) {
|
||||
status = 404;
|
||||
filename = "./error_pages/404.html";
|
||||
stream = ifstream(filename);
|
||||
}
|
||||
|
||||
stringstream buffer;
|
||||
buffer << stream.rdbuf();
|
||||
return make_unique<http_response>(buffer.str(), status);
|
||||
}
|
||||
string file_dir;
|
||||
|
||||
unique_ptr<http_response> handle_request_cache(http_request& req) {
|
||||
string filename = req.path() == "/" ? "/index.html" : req.path();
|
||||
filename = "./www" + filename;
|
||||
string filename = req.path() == "/" ? "index.html" : req.path();
|
||||
filename = file_dir + filename;
|
||||
auto file_info = file_cache.find(filename);
|
||||
|
||||
int status = 200;
|
||||
|
@ -35,7 +18,7 @@ private:
|
|||
file_info = file_cache.find(filename);
|
||||
}
|
||||
|
||||
return make_unique<http_response>(file_info->second, status);
|
||||
return make_unique<http_response>(file_info->second, filename, status);
|
||||
}
|
||||
|
||||
void populate_cache_dir(string dir) {
|
||||
|
@ -55,18 +38,16 @@ private:
|
|||
}
|
||||
|
||||
void populate_cache() {
|
||||
populate_cache_dir("./www/");
|
||||
populate_cache_dir(file_dir);
|
||||
populate_cache_dir("./error_pages/");
|
||||
}
|
||||
|
||||
public:
|
||||
file_backend(bool enable_cache) : cache_enabled(enable_cache) {
|
||||
if(cache_enabled) {
|
||||
file_backend(string dir = "./www") : file_dir(dir) {
|
||||
populate_cache();
|
||||
}
|
||||
}
|
||||
|
||||
unique_ptr<http_response> handle_request(http_request& req) override {
|
||||
return cache_enabled ? handle_request_cache(req) : handle_request_nocache(req);
|
||||
return handle_request_cache(req);
|
||||
}
|
||||
};
|
||||
|
|
51
src/http.cpp
51
src/http.cpp
|
@ -139,6 +139,27 @@ static unordered_map<int, string> const http_status_map = {
|
|||
{ 420, "ENHANCE YOUR CALM" }
|
||||
};
|
||||
|
||||
static unordered_map<std::string, std::string> const mime_types = {
|
||||
{ "html", "text/html" },
|
||||
{ "css", "text/css" },
|
||||
|
||||
{ "js", "application/javascript" },
|
||||
{ "pdf", "application/pdf" },
|
||||
|
||||
{ "ico", "image/x-icon" },
|
||||
{ "jpg", "image/jpeg" },
|
||||
{ "jpeg", "image/jpeg" },
|
||||
{ "png", "image/png" },
|
||||
{ "gif", "image/gif" },
|
||||
{ "bmp", "image/bmp" },
|
||||
|
||||
{ "mp4", "video/mp4" },
|
||||
{ "avi", "video/x-msvideo" },
|
||||
{ "mkv", "video/x-matroska" },
|
||||
{ "mov", "video/quicktime" },
|
||||
{ "wmv", "video/x-ms-wmv" },
|
||||
};
|
||||
|
||||
class name_value {
|
||||
private:
|
||||
string _name;
|
||||
|
@ -378,13 +399,15 @@ public:
|
|||
class http_response {
|
||||
private:
|
||||
int _status_code;
|
||||
string _content;
|
||||
string& _content;
|
||||
string _filename;
|
||||
unordered_map<string, http_header> _headers; // kinda goofy, whatever
|
||||
|
||||
public:
|
||||
http_response(string content, int status_code = 200)
|
||||
: _content(std::move(content))
|
||||
http_response(string& content, string filename, int status_code = 200)
|
||||
: _content(content)
|
||||
, _status_code(status_code)
|
||||
, _filename(std::move(filename))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -397,12 +420,22 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
string to_string()
|
||||
string& content()
|
||||
{
|
||||
return _content;
|
||||
}
|
||||
|
||||
string header_to_string()
|
||||
{
|
||||
string response = "";
|
||||
response += "HTTP/1.1 " + ::to_string(_status_code) + " " + http_status_map.find(_status_code)->second + "\r\n";
|
||||
|
||||
add_header(http_header("Content-Type", "text/html"), false);
|
||||
string content_type = "text/html";
|
||||
string file_extension = _filename.substr(_filename.rfind('.') + 1);
|
||||
auto mime_type = mime_types.find(file_extension);
|
||||
if (mime_type != mime_types.end()) {
|
||||
content_type = mime_type->second;
|
||||
}
|
||||
add_header(http_header("Content-Type", content_type), false);
|
||||
add_header(http_header("Content-Length", ::to_string(_content.length())), false);
|
||||
add_header(http_header("Server", "Anthracite/0.0.1"), false);
|
||||
|
||||
|
@ -411,8 +444,12 @@ public:
|
|||
}
|
||||
|
||||
response += "\r\n";
|
||||
response += _content;
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
string to_string()
|
||||
{
|
||||
return header_to_string() + _content;
|
||||
}
|
||||
};
|
||||
|
|
13
src/main.cpp
13
src/main.cpp
|
@ -16,6 +16,7 @@ using namespace std;
|
|||
void log_request_and_response(http_request& req, unique_ptr<http_response>& resp);
|
||||
|
||||
constexpr int default_port = 80;
|
||||
constexpr int max_worker_threads = 128;
|
||||
|
||||
int active_threads = 0;
|
||||
mutex mtx;
|
||||
|
@ -26,15 +27,15 @@ void handle_client(anthracite_socket s, file_backend& fb)
|
|||
http_request req(s);
|
||||
unique_ptr<http_response> resp = fb.handle_request(req);
|
||||
log_request_and_response(req, resp);
|
||||
s.send_message(resp->to_string());
|
||||
string header = resp->header_to_string();
|
||||
s.send_message(header);
|
||||
s.send_message(resp->content());
|
||||
resp.reset();
|
||||
s.close_conn();
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
active_threads--;
|
||||
}
|
||||
|
||||
cv.notify_one();
|
||||
}
|
||||
|
||||
|
@ -48,14 +49,14 @@ int main(int argc, char** argv)
|
|||
|
||||
cout << "Initializing Anthracite" << endl;
|
||||
anthracite_socket s(port_number);
|
||||
file_backend fb(true);
|
||||
file_backend fb(argc > 2 ? argv[2] : "./www");
|
||||
cout << "Initialization Complete" << endl;
|
||||
cout << "Listening for HTTP connections on port " << port_number << endl;
|
||||
|
||||
for (;;) {
|
||||
while (true) {
|
||||
s.wait_for_conn();
|
||||
std::unique_lock<std::mutex> lock(mtx);
|
||||
cv.wait(lock, [] { return active_threads < 20; });
|
||||
cv.wait(lock, [] { return active_threads < max_worker_threads; });
|
||||
active_threads++;
|
||||
thread(handle_client, s, ref(fb)).detach();
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
client_socket = -1;
|
||||
}
|
||||
|
||||
void send_message(string msg)
|
||||
void send_message(string& msg)
|
||||
{
|
||||
if (client_socket == -1) {
|
||||
return;
|
||||
|
|
BIN
src/test_www/images/emma.bmp
Normal file
BIN
src/test_www/images/emma.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 496 KiB |
BIN
src/test_www/images/favicon.ico
Normal file
BIN
src/test_www/images/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 319 B |
BIN
src/test_www/images/favicon_anim.ico
Normal file
BIN
src/test_www/images/favicon_anim.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
BIN
src/test_www/images/lola.jpeg
Normal file
BIN
src/test_www/images/lola.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
BIN
src/test_www/images/tini.png
Normal file
BIN
src/test_www/images/tini.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
9
src/test_www/index.html
Normal file
9
src/test_www/index.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
<head>
|
||||
<title>Anthracite</title>
|
||||
<link rel="icon" type="image/x-icon" href="/images/favicon.ico">
|
||||
</head>
|
||||
<center>
|
||||
<h1>Anthracite is Running!</h1>
|
||||
<p>If you are seeing this page, then Anthracite is configured correctly!</p>
|
||||
<p>Add files to the "www" directory to begin serving your website.</p>
|
||||
</center>
|
18
src/test_www/test.css
Normal file
18
src/test_www/test.css
Normal file
|
@ -0,0 +1,18 @@
|
|||
.cool-style {
|
||||
background: linear-gradient(to right, #ef5350, #f48fb1, #7e57c2, #2196f3, #26c6da, #43a047, #eeff41, #f9a825, #ff5722);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.content img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
margin: 10px;
|
||||
}
|
25
src/test_www/test.html
Normal file
25
src/test_www/test.html
Normal file
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Anthracite</title>
|
||||
<link rel="icon" type="image/x-icon" href="/images/favicon_anim.ico">
|
||||
<link rel="stylesheet" href="test.css">
|
||||
</head>
|
||||
<body>
|
||||
<center>
|
||||
<h1 class="cool-style">Test Page!</h1>
|
||||
<h2>Dogs</h2>
|
||||
<div class="content">
|
||||
<img src="/images/tini.png" alt="A border collie" />
|
||||
<img src="/images/lola.jpeg" alt="A border collie" />
|
||||
<img src="/images/emma.bmp" alt="A corgi" />
|
||||
</div>
|
||||
<h2>Trains</h2>
|
||||
<div>
|
||||
<video controls>
|
||||
<source src="videos/train_vid.mp4" />
|
||||
</video>
|
||||
</div>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
BIN
src/test_www/videos/train_vid.mp4
Normal file
BIN
src/test_www/videos/train_vid.mp4
Normal file
Binary file not shown.
|
@ -1,3 +1,7 @@
|
|||
<head>
|
||||
<title>Anthracite</title>
|
||||
<link rel="icon" type="image/x-icon" href="/images/favicon.ico">
|
||||
</head>
|
||||
<center>
|
||||
<h1>Anthracite is Running!</h1>
|
||||
<p>If you are seeing this page, then Anthracite is configured correctly!</p>
|
||||
|
|
1020251
src/www/large.html
1020251
src/www/large.html
File diff suppressed because it is too large
Load diff
|
@ -1,3 +0,0 @@
|
|||
<center>
|
||||
<h1>Test Page!</h1>
|
||||
</center>
|
Loading…
Reference in a new issue