summaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp156
1 files changed, 0 insertions, 156 deletions
diff --git a/src/main.cpp b/src/main.cpp
deleted file mode 100644
index c0c9bb3..0000000
--- a/src/main.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-#include <getopt.h>
-
-#include <filesystem>
-#include <fstream>
-#include <iostream>
-#include <sstream>
-
-#include "CGIScript.h"
-#include "ClientConnection.h"
-#include "HttpRequest.h"
-#include "HttpResponse.h"
-#include "ServerConnection.h"
-
-static std::string content_type_for_extension(const std::filesystem::path& extension)
-{
- if (extension == ".html")
- return "text/html";
- if (extension == ".css")
- return "text/css";
- if (extension == ".gif")
- return "image/gif";
- if (extension == ".png")
- return "image/png";
- if (extension == ".webp")
- return "image/webp";
- return "text/plain";
-}
-
-static HttpResponse serve_from_filesystem(const HttpRequest& request)
-{
- namespace fs = std::filesystem;
-
- HttpResponse response;
- response.add_header("Server", "cfws");
-
- // Remove leading slash from the path if it exists
- std::string relative_request_path = request.uri();
- while (*relative_request_path.begin() == '/')
- relative_request_path.erase(0, 1);
-
- fs::path request_path = fs::current_path() / relative_request_path;
-
- // Look for an index.html if the requested path is a directory
- if (fs::is_directory(request_path)) {
- request_path /= "index.html";
- }
-
- if (fs::exists(request_path)) {
- std::string file_path = request_path.string();
- std::ifstream input_file(file_path);
- if (!input_file.is_open()) {
- std::cerr << "Failed to open file " << file_path << std::endl;
- }
-
- std::string file_contents((std::istreambuf_iterator<char>(input_file)), std::istreambuf_iterator<char>());
-
- response.set_status_code(HttpStatusCode::OK);
- response.add_header("Content-Type", content_type_for_extension(request_path.extension()));
- response.set_content(file_contents);
- } else {
- response.set_status_code(HttpStatusCode::NotFound);
- response.add_header("Content-Type", "text/plain");
- response.set_content("Page not found!");
- }
-
- return response;
-}
-
-static HttpResponse serve_from_cgi(const std::string& script_path, const HttpRequest& request)
-{
- HttpResponse response;
- response.add_header("Server", "cfws");
-
- // Split URI between the path and the query parameter string
- std::stringstream uri_stream(request.uri());
- std::string segment;
- std::vector<std::string> segment_list;
-
- while (std::getline(uri_stream, segment, '?')) {
- segment_list.push_back(segment);
- }
-
- CGIScript script(script_path);
- script.set_environment("REQUEST_METHOD", "GET");
- script.set_environment("REQUEST_URI", request.uri().c_str());
- script.set_environment("PATH_INFO", segment_list[0].c_str());
- if (segment_list.size() > 1)
- script.set_environment("QUERY_STRING", segment_list[1].c_str());
- script.set_environment("CONTENT_LENGTH", "0");
-
- if (!script.open()) {
- response.set_status_code(HttpStatusCode::InternalServerError);
- response.add_header("Content-Type", "text/plain");
- response.set_content("Failed to open CGI script!");
- return response;
- }
-
- response.set_status_code(HttpStatusCode::OK);
- response.add_headers_and_content(script.read_output());
- return response;
-}
-
-static option long_options[] = {
- { "cgi", required_argument, nullptr, 'c' },
- { "port", required_argument, nullptr, 'p' },
-};
-
-int main(int argc, char** argv)
-{
- int port = 8080;
- bool in_cgi_mode = false;
- std::string cgi_program_name;
-
- int c = 0;
- int option_index = 0;
- while ((c = getopt_long(argc, argv, "c:p:", long_options, &option_index)) != -1) {
- switch (c) {
- case 'c':
- in_cgi_mode = true;
- cgi_program_name = optarg;
- break;
- case 'p':
- port = atoi(optarg);
- if (port == 0) {
- std::cerr << "cfws: Specified port is not a valid number" << std::endl;
- exit(1);
- }
- break;
- default:
- break;
- }
- }
-
- // Check the script path to ensure that it is a valid executable
- // script before attempting to start the server.
- if (in_cgi_mode)
- CGIScript::validate_path(cgi_program_name);
-
- ServerConnection server(port);
- std::cout << "Serving a " << (in_cgi_mode ? "CGI script" : "directory") << " on port " << port << std::endl;
-
- while (true) {
- ClientConnection client = server.accept_client_connection();
- HttpRequest request = client.read_request();
- HttpResponse response;
-
- if (in_cgi_mode) {
- response = serve_from_cgi(cgi_program_name, request);
- } else {
- response = serve_from_filesystem(request);
- }
-
- client.send(response);
- client.close_connection();
- }
-}