v0.1.1
This commit is contained in:
parent
38359bd957
commit
d6eb46d310
20 changed files with 178 additions and 1020295 deletions
|
@ -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) {
|
||||
populate_cache();
|
||||
}
|
||||
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…
Add table
Add a link
Reference in a new issue