-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
2,034 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
cmake_minimum_required(VERSION 3.27) | ||
project(Tanzanite) | ||
|
||
set(CMAKE_CXX_STANDARD 17) | ||
file(GLOB_RECURSE PROJECT_SOURCE_FILES "src/proj/*.cpp" "src/proj/*.h") | ||
file(GLOB_RECURSE RESOURCE_FILES "src/resource/*") | ||
include_directories(${CMAKE_SOURCE_DIR}/ext) | ||
|
||
add_executable(Tanzanite ${PROJECT_SOURCE_FILES} ${RESOURCE_FILES}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#ifndef TANZANITE_INCLUDE_H | ||
#define TANZANITE_INCLUDE_H | ||
|
||
#include "utils/logger.h" | ||
#include <iostream> | ||
#include <algorithm> | ||
#include <vector> | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
#include <iostream> | ||
#include <thread> | ||
#include <vector> | ||
#include <sstream> | ||
#include <fstream> | ||
#include <cstring> | ||
#include <netinet/in.h> | ||
#include <unistd.h> | ||
#include <sys/socket.h> | ||
#include <algorithm> | ||
|
||
const int PORT = 8080; | ||
const int BUFFER_SIZE = 1024; | ||
|
||
std::string get_error_response(int status_code, const std::string& error_message) { | ||
std::string error_page_path = "error.html"; | ||
std::ifstream error_file(error_page_path); | ||
if (!error_file.is_open()) { | ||
return "HTTP/1.1 500 Internal Server Error\r\n" | ||
"Content-Type: text/plain\r\n" | ||
"Content-Length: 22\r\n" | ||
"\r\n" | ||
"500 Internal Server Error"; | ||
} | ||
|
||
std::stringstream buffer; | ||
buffer << error_file.rdbuf(); | ||
std::string error_content = buffer.str(); | ||
error_file.close(); | ||
|
||
std::string status_code_str = std::to_string(status_code); | ||
size_t pos = error_content.find("%ERROR_CODE%"); | ||
while (pos != std::string::npos) { | ||
error_content.replace(pos, std::string("%ERROR_CODE%").length(), status_code_str); | ||
pos = error_content.find("%ERROR_CODE%", pos + status_code_str.length()); | ||
} | ||
|
||
pos = error_content.find("%ERROR_MESSAGE%"); | ||
if (pos != std::string::npos) { | ||
error_content.replace(pos, std::string("%ERROR_MESSAGE%").length(), error_message); | ||
} | ||
|
||
std::string error_response = | ||
"HTTP/1.1 " + status_code_str + " Not Found\r\n" | ||
"Content-Type: text/html\r\n" | ||
"Content-Length: " + std::to_string(error_content.size()) + "\r\n" | ||
"\r\n" + error_content; | ||
|
||
return error_response; | ||
} | ||
|
||
|
||
bool ends_with(const std::string& str, const std::string& suffix) { | ||
return str.size() >= suffix.size() && | ||
str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; | ||
} | ||
|
||
std::string get_mime_type(const std::string& path) { | ||
if (ends_with(path, ".html")) return "text/html"; | ||
if (ends_with(path, ".css")) return "text/css"; | ||
if (ends_with(path, ".js")) return "application/javascript"; | ||
if (ends_with(path, ".png")) return "image/png"; | ||
if (ends_with(path, ".jpg")) return "image/jpeg"; | ||
if (ends_with(path, ".gif")) return "image/gif"; | ||
return "application/octet-stream"; | ||
} | ||
std::string read_file(const std::string& file_path) { | ||
std::ifstream file(file_path); | ||
if (!file.is_open()) return "404 Not Found"; | ||
|
||
std::stringstream buffer; | ||
buffer << file.rdbuf(); | ||
return buffer.str(); | ||
} | ||
|
||
void handle_client(int client_socket) { | ||
char buffer[BUFFER_SIZE]; | ||
memset(buffer, 0, BUFFER_SIZE); | ||
|
||
read(client_socket, buffer, BUFFER_SIZE - 1); | ||
std::string request(buffer); | ||
|
||
std::istringstream request_stream(request); | ||
std::string method; | ||
std::string path; | ||
request_stream >> method >> path; | ||
|
||
std::string response; | ||
if (method == "GET") { | ||
std::string file_path = "." + path; | ||
if (file_path == "./") file_path = "./index.html"; | ||
std::string response_body = read_file(file_path); | ||
if (response_body == "404 Not Found") { | ||
response = get_error_response(404, "Page Not Found"); | ||
} else { | ||
std::string mime_type = get_mime_type(file_path); | ||
response = | ||
"HTTP/1.1 200 OK\r\n" | ||
"Content-Type: " + mime_type + "\r\n" | ||
"Content-Length: " + std::to_string(response_body.size()) + "\r\n" | ||
"\r\n" + response_body; | ||
} | ||
} else { | ||
response = get_error_response(405, "Method Not Allowed"); | ||
} | ||
|
||
write(client_socket, response.c_str(), response.size()); | ||
close(client_socket); | ||
} | ||
|
||
int main() { | ||
int server_fd, client_socket; | ||
struct sockaddr_in address; | ||
int opt = 1; | ||
int addrlen = sizeof(address); | ||
|
||
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { | ||
perror("socket failed"); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { | ||
perror("setsockopt"); | ||
close(server_fd); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
address.sin_family = AF_INET; | ||
address.sin_addr.s_addr = INADDR_ANY; | ||
address.sin_port = htons(PORT); | ||
|
||
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { | ||
perror("bind failed"); | ||
close(server_fd); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
if (listen(server_fd, 3) < 0) { | ||
perror("listen"); | ||
close(server_fd); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
std::cout << "Tanzanite Server is running on port " << PORT << std::endl; | ||
|
||
while (true) { | ||
if ((client_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { | ||
perror("accept"); | ||
close(server_fd); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
std::thread(handle_client, client_socket).detach(); | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#ifndef TANZANITE_LOGGER_H | ||
#define TANZANITE_LOGGER_H | ||
|
||
#include <iostream> | ||
|
||
#define INFO 1 | ||
#define WARNING 2 | ||
#define ERROR 3 | ||
#define SUCCESS 4 | ||
#define FATAL 5 | ||
|
||
#define COLOR_INFO "\033[1;32m" // Green | ||
#define COLOR_WARNING "\033[1;33m" // Yellow | ||
#define COLOR_ERROR "\033[1;31m" // Red | ||
#define COLOR_SUCCESS "\033[1;36m" // Cyan | ||
#define COLOR_FATAL "\033[1;35m" // Magenta | ||
#define COLOR_RESET "\033[0m" // Reset color | ||
|
||
void log(int log_severity) | ||
{ | ||
switch (log_severity) { | ||
case INFO: | ||
std::cerr << COLOR_INFO << "[INFO]: "; | ||
break; | ||
case WARNING: | ||
std::cerr << COLOR_WARNING << "[WARNING]: "; | ||
break; | ||
case ERROR: | ||
std::cerr << COLOR_ERROR << "[ERROR]: "; | ||
break; | ||
case SUCCESS: | ||
std::cerr << COLOR_SUCCESS << "[SUCCESS]: "; | ||
break; | ||
case FATAL: | ||
std::cerr << COLOR_FATAL << "[FATAL]: "; | ||
break; | ||
default: | ||
std::cerr << "[LOG]: "; | ||
break; | ||
} | ||
} | ||
|
||
/* Log class to handle the log messages */ | ||
class Logger | ||
{ | ||
public: | ||
Logger(int log_severity) : log_severity(log_severity) | ||
{ | ||
log(log_severity); | ||
} | ||
|
||
~Logger() | ||
{ | ||
std::cerr << COLOR_RESET << std::endl; | ||
} | ||
|
||
template <typename T> | ||
Logger& operator<<(const T& data) | ||
{ | ||
std::cerr << data; | ||
return *this; | ||
} | ||
|
||
private: | ||
int log_severity; | ||
}; | ||
|
||
#define LOG(level) Logger(level) | ||
|
||
#endif //REDIRECTOR_LOGGER_H |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Error %ERROR_CODE%</title> | ||
<link rel="icon" type="image/png" href="assets/tanzanite.png"> | ||
<script src="js/particles.js"></script> | ||
<script src="js/init_particles.js"></script> | ||
<style> | ||
body { | ||
background-color: #11101d; | ||
color: #ffffff; | ||
font-family: Arial, sans-serif; | ||
margin: 0; | ||
padding: 0; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
height: 100vh; | ||
overflow: hidden; | ||
} | ||
.container { | ||
text-align: center; | ||
padding: 20px; | ||
background-color: #1f1d35; | ||
border-radius: 10px; | ||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); | ||
max-width: 80%; | ||
border: 2px solid #4e6cd3; /* Outline color */ | ||
} | ||
h1 { | ||
font-size: 32px; | ||
margin-bottom: 20px; | ||
color: #ffffff; | ||
} | ||
p { | ||
font-size: 18px; | ||
color: #969698; | ||
} | ||
.icon { | ||
display: block; | ||
margin: 0 auto 20px; | ||
width: 100px; /* Adjust the width as needed */ | ||
} | ||
#particles-container { | ||
position: absolute; | ||
width: 98%; | ||
height: 98%; | ||
z-index: -1; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
|
||
<div id="particles-container"></div> | ||
|
||
<div class="container"> | ||
<img class="icon" src="assets/tanzanite.png" alt="Tanzanite Icon"> | ||
<h1>Error %ERROR_CODE%: %ERROR_MESSAGE%</h1> | ||
<p>Sorry, an error occurred.</p> | ||
</div> | ||
|
||
<script> | ||
initializeParticles(); | ||
</script> | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Tanzanite Web Server</title> | ||
<link rel="icon" type="image/png" href="assets/tanzanite.png"> | ||
<script src="js/particles.js"></script> | ||
<script src="js/init_particles.js"></script> | ||
<style> | ||
body { | ||
background-color: #11101d; | ||
color: #ffffff; | ||
font-family: Arial, sans-serif; | ||
margin: 0; | ||
padding: 0; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
height: 100vh; | ||
overflow: hidden; | ||
} | ||
.container { | ||
text-align: center; | ||
padding: 20px; | ||
background-color: #1f1d35; | ||
border-radius: 10px; | ||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); | ||
max-width: 80%; | ||
border: 2px solid #4e6cd3; /* Outline color */ | ||
} | ||
h1 { | ||
font-size: 32px; | ||
margin-bottom: 20px; | ||
color: #ffffff; | ||
} | ||
p { | ||
font-size: 18px; | ||
color: #969698; | ||
} | ||
.icon { | ||
display: block; | ||
margin: 0 auto 20px; | ||
width: 100px; /* Adjust the width as needed */ | ||
} | ||
#particles-container { | ||
position: absolute; | ||
width: 98%; | ||
height: 98%; | ||
z-index: -1; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
|
||
<div id="particles-container"></div> | ||
|
||
<div class="container"> | ||
<img class="icon" src="assets/tanzanite.png" alt="Tanzanite Icon"> | ||
<h1>Welcome to Tanzanite Web Server</h1> | ||
<p>This is the home page served by the Tanzanite web server.</p> | ||
</div> | ||
|
||
<script> | ||
initializeParticles(); | ||
</script> | ||
|
||
</body> | ||
</html> |
Oops, something went wrong.