From 86ec0b5386fc2078891a829026844d2ec21ea7db Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Wed, 8 Oct 2025 00:58:42 +0200 Subject: Add http module and implement basic http server --- src/http.hh | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 src/http.hh (limited to 'src/http.hh') diff --git a/src/http.hh b/src/http.hh new file mode 100644 index 0000000..ca3f7d4 --- /dev/null +++ b/src/http.hh @@ -0,0 +1,177 @@ +#ifndef HTTP_HH +#define HTTP_HH + +#include +#include +#include +#include + +class Buffer; + +namespace logger { +class Logger; +} // namespace logger + +namespace looper { +class Looper; +} // namespace looper + +namespace cfg { +class Config; +} // namespace cfg + +namespace http { + +enum class StatusCode : uint16_t { + kOK = 200, + kNoContent = 204, + kNotFound = 404, + kMethodNotAllowed = 405, +}; + +class OpenPort { + public: + virtual ~OpenPort() = default; + + protected: + OpenPort() = default; + OpenPort(OpenPort const&) = delete; + OpenPort& operator=(OpenPort const&) = delete; +}; + +// Returns nullptr in case of error, the error is written to logger. +std::unique_ptr open_port(std::string_view host_port, + logger::Logger& logger); + +class MimeType { + public: + virtual ~MimeType() = default; + + [[nodiscard]] + virtual std::string_view type() const = 0; + [[nodiscard]] + virtual std::string_view subtype() const = 0; + [[nodiscard]] + virtual std::optional parameter( + std::string_view name) const = 0; + [[nodiscard]] + virtual std::string const& string() const = 0; + + class Builder { + public: + virtual ~Builder() = default; + + virtual Builder& parameter(std::string_view name, + std::string_view value) = 0; + + [[nodiscard]] + virtual std::unique_ptr build() const = 0; + + [[nodiscard]] + static std::unique_ptr create(std::string_view type, + std::string_view subtype); + + protected: + Builder() = default; + Builder(Builder const&) = delete; + Builder& operator=(Builder const&) = delete; + }; + + // Short version of Builder::create(type, subtype).build() + [[nodiscard]] + static std::unique_ptr create(std::string_view type, + std::string_view subtype); + + protected: + MimeType() = default; + MimeType(MimeType const&) = delete; + MimeType& operator=(MimeType const&) = delete; +}; + +class Request { + public: + virtual ~Request() = default; + + [[nodiscard]] + virtual std::string_view method() const = 0; + [[nodiscard]] + virtual std::string_view path() const = 0; + + protected: + Request() = default; + Request(Request const&) = delete; + Request& operator=(Request const&) = delete; +}; + +class Response { + public: + virtual ~Response() = default; + + class Builder { + public: + virtual ~Builder() = default; + + virtual Builder& content(std::string_view content) = 0; + virtual Builder& add_header(std::string_view name, + std::string_view value) = 0; + + [[nodiscard]] + virtual std::unique_ptr build() const = 0; + + [[nodiscard]] + static std::unique_ptr create(StatusCode status_code); + + protected: + Builder() = default; + Builder(Builder const&) = delete; + Builder& operator=(Builder const&) = delete; + }; + + // Short version of Builder::create(status_code).build() + [[nodiscard]] + static std::unique_ptr status(StatusCode status_code); + + // Short version of Builder::create(StatusCode::kOK).content(content) + // .add_header("Content-Type", mime_type).build() + [[nodiscard]] + static std::unique_ptr content(std::string_view content, + MimeType const& mime_type); + + // Returns true while there is more data to write. + virtual bool write(Buffer& buffer) = 0; + + protected: + Response() = default; + Response(Response const&) = delete; + Response& operator=(Response const&) = delete; +}; + +class Server { + public: + virtual ~Server() = default; + + class Delegate { + public: + virtual ~Delegate() = default; + + virtual std::unique_ptr handle(Request const& request) = 0; + + protected: + Delegate() = default; + }; + + protected: + Server() = default; + Server(Server const&) = delete; + Server& operator=(Server const&) = delete; +}; + +std::unique_ptr create_server(logger::Logger& logger, + cfg::Config const& cfg, + looper::Looper& looper, + std::unique_ptr open_port, + Server::Delegate& delegate); + +} // namespace http + +#endif // HTTP_HH -- cgit v1.2.3-70-g09d2