#pragma once // Standard Library Includes #include #include #include #include #include #include // Third-Party Library Includes #include struct HttpRequest { std::string method; std::string url; uint8_t http_major = 0; uint8_t http_minor = 0; std::vector> headers; std::vector body; }; using RequestList = std::vector; class HttpRequestParser { enum class State { Idle, Parsing, Completed, Error }; public: HttpRequestParser(); bool in_error_state() const noexcept { return m_state == State::Error; } std::expected parse(std::span data); size_t get_number_of_completed_requests() const noexcept { return m_completed_requests.size(); } void get_completed_requests(RequestList &out_requests) { std::swap(out_requests, m_completed_requests); m_completed_requests = {}; } void reset(); private: static HttpRequestParser &from_llhttp(llhttp_t *parser); void commit_pending_header(); /*1*/ static int on_message_complete(llhttp_t *parser); /*2*/ static int on_url(llhttp_t *parser, const char *ptr, size_t length); /*3*/ static int on_method(llhttp_t *parser, const char *ptr, size_t length); /*4*/ static int on_version(llhttp_t *parser, const char *ptr, size_t length); /*5*/ static int on_header_field(llhttp_t *parser, const char *ptr, size_t length); /*6*/ static int on_header_value(llhttp_t *parser, const char *ptr, size_t length); /*7*/ static int on_body(llhttp_t *parser, const char *ptr, size_t length); llhttp_t m_parser{}; llhttp_settings_t m_settings{}; State m_state{State::Idle}; RequestList m_completed_requests; HttpRequest m_current_request; std::string m_current_header_field; std::string m_current_header_value; enum class HeaderState { None, Field, Value }; HeaderState m_header_state{HeaderState::None}; }; struct HttpResponse { uint8_t http_major = 1; uint8_t http_minor = 1; uint16_t status_code; std::string reason_phrase; std::vector> headers; std::vector body; void serialize_into(std::vector &) const; };