diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2ebe7c1..da0cd06 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,10 +1,12 @@ set(SOURCE_FILES main.cpp server.cpp + response.cpp ) set(HEADER_FILES server.h + response.h ) target_sources(birdbadge PRIVATE ${SOURCE_FILES}) diff --git a/src/response.cpp b/src/response.cpp new file mode 100644 index 0000000..146fe53 --- /dev/null +++ b/src/response.cpp @@ -0,0 +1,42 @@ +#include "response.h" + +constexpr static const char* pathDelimiter("/"); + +Response::Response(const std::string_view& path): + status(Status::ok), + body() +{ + std::vector split = splitPath(path); + selfIndentification(split); +} + +void Response::selfIndentification(const std::vector& path) { + if (path.size() == 0) { + status = Status::ok; + } +} + +void Response::writeHeader(std::ostream& out) const { +} + +void Response::writeBody(std::ostream& out) const { +} + +std::vector Response::splitPath(std::string_view path) { + std::vector output; + std::string_view::size_type first = 0; + + while (first < path.size()) { + const std::string_view::size_type second = path.find_first_of(pathDelimiter, first); + + if (first != second) + output.emplace_back(path.substr(first, second - first)); + + if (second == std::string_view::npos) + break; + + first = second + 1; + } + + return output; +} diff --git a/src/response.h b/src/response.h new file mode 100644 index 0000000..61acf1f --- /dev/null +++ b/src/response.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + + +class Response { +public: + enum Status { + ok, + notFound, + error + }; + + Response(const std::string_view& path); + + void writeHeader(std::ostream& out) const; + void writeBody(std::ostream& out) const; + +private: + void selfIndentification(const std::vector& path); + + static std::vector splitPath(std::string_view path); + +private: + Status status; + std::string body; +}; diff --git a/src/server.cpp b/src/server.cpp index c7be2e1..e34dbef 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -11,20 +11,28 @@ constexpr static const char* DOCUMENT_ROOT("DOCUMENT_ROOT"); constexpr static const char* SCRIPT_NAME("SCRIPT_NAME"); constexpr static const char* SCRIPT_FILENAME("SCRIPT_FILENAME"); +constexpr static const char* SERVER_NAME("SERVER_NAME"); + constexpr static const char* status405("Status: 405 Method Not Allowed"); +constexpr static const char* status500("Status: 500 Internal Error"); +constexpr static const char* status200("Status: 200 OK"); constexpr static const char* contentTypeHtml("Content-type: text/html"); constexpr static const char* headerEnd("\n\n"); +constexpr static const char* newLine("\n"); + +constexpr static const char* svgHeader("image/svg+xml;charset=utf-8"); Server::Server(): - requestCount(0) + requestCount(0), + serverName(std::nullopt) {} Server::~Server() { } void Server::handleRequest(FCGX_Request& request) { - ++requestCount; + accountRequest(request); fcgi_streambuf cin_fcgi_streambuf(request.in); fcgi_streambuf cout_fcgi_streambuf(request.out); @@ -39,13 +47,12 @@ void Server::handleRequest(FCGX_Request& request) { return; } + writeHeader(os); try { - printEnv(os, request); + std::string_view sPath = getPath(request); + Response response(sPath); - os << requestCount; } catch (const std::exception e) { - os << contentTypeHtml; - os << headerEnd; os << e.what(); } } @@ -57,3 +64,39 @@ void Server::printEnv(std::ostream& out, FCGX_Request& request) { } } +void Server::writeHeader(std::ostream& out) { + out << status200 << newLine; + out << contentTypeHtml; + out << headerEnd; +} + +void Server::accountRequest(const FCGX_Request& request) { + ++requestCount; + + if (!serverName.has_value()) { + try { + serverName = FCGX_GetParam(SERVER_NAME, request.envp); + std::cout << "received server name " << serverName.value() << std::endl; + } catch (...) { + std::cout << "couldn't parse " << std::endl; + } + } +} + +std::string_view Server::getPath(const FCGX_Request& request) { + std::string_view path; + if (serverName.has_value()) { + const std::string& sn = serverName.value(); + std::string_view scriptFileName(FCGX_GetParam(SCRIPT_FILENAME, request.envp)); + + std::string::size_type snLocation = scriptFileName.find(sn); + if (snLocation != std::string::npos) { + if (snLocation + sn.size() < scriptFileName.size()) { + path = scriptFileName.substr(snLocation + sn.size() + 1); + } + } + } + + return path; +} + diff --git a/src/server.h b/src/server.h index 6d1f30b..3540b45 100644 --- a/src/server.h +++ b/src/server.h @@ -2,10 +2,15 @@ #include #include +#include +#include +#include #include #include +#include "response.h" + class Server { public: Server(); @@ -14,8 +19,15 @@ public: void handleRequest(FCGX_Request& request); private: + void router(const std::vector& path); void printEnv(std::ostream& out, FCGX_Request& request); + void writeHeader(std::ostream& out); + void accountRequest(const FCGX_Request& request); + std::string_view getPath(const FCGX_Request& request); + + private: uint64_t requestCount; + std::optional serverName; };