cserver/include/cserver/server/http/http_request_parser.hpp
2024-03-13 13:09:35 +00:00

71 lines
2.7 KiB
C++

#pragma once
#include <cserver/server/http/http_request.hpp>
#include <llhttp.h>
namespace cserver::server::http {
struct HTTPRequestParser : private llhttp_t, public HTTPRequest {
bool err = false;
bool done = false;
std::string headerField = {};
std::string headerValue = {};
std::string urlString = {};
inline HTTPRequestParser(std::string_view data) {
llhttp_settings_t settings;
llhttp_settings_init(&settings);
settings.on_method = HTTPRequestParser::OnMethod;
settings.on_url = HTTPRequestParser::OnUrl;
settings.on_url_complete = HTTPRequestParser::OnUrlComplete;
settings.on_header_field = HTTPRequestParser::OnHeaderField;
settings.on_header_value = HTTPRequestParser::OnHeaderValue;
settings.on_headers_complete = HTTPRequestParser::OnHeaderComplete;
settings.on_body = HTTPRequestParser::OnBody;
settings.on_message_complete = HTTPRequestParser::OnMessageComplete;
llhttp_init(this, HTTP_BOTH, &settings);
llhttp_execute(this, data.data(), data.size());
};
static inline auto OnMethod(llhttp_t* parser, const char* data, std::size_t size) -> int {
auto* self = static_cast<HTTPRequest*>(static_cast<HTTPRequestParser*>(parser));
self->method.append(data, size);
return 0;
};
static inline auto OnUrl(llhttp_t* parser, const char* data, std::size_t size) -> int {
auto* self = static_cast<HTTPRequestParser*>(parser);
self->urlString.append(data, size);
return 0;
};
static inline auto OnUrlComplete(llhttp_t* parser) -> int {
auto* self = static_cast<HTTPRequestParser*>(parser);
self->url = boost::urls::url(self->urlString);
return 0;
};
static inline auto OnHeaderField(llhttp_t* parser, const char* data, std::size_t size) -> int {
auto* self = static_cast<HTTPRequestParser*>(parser);
self->headerField.append(data, size);
return 0;
};
static inline auto OnHeaderValue(llhttp_t* parser, const char* data, std::size_t size) -> int {
auto* self = static_cast<HTTPRequestParser*>(parser);
self->headerValue.append(data, size);
return 0;
};
static inline auto OnHeaderComplete(llhttp_t* parser) -> int {
auto* self = static_cast<HTTPRequestParser*>(parser);
self->headers.emplace(std::move(self->headerField), std::move(self->headerValue));
self->headerValue.clear();
self->headerField.clear();
return 0;
};
static inline auto OnBody(llhttp_t* parser, const char* data, std::size_t size) -> int {
auto* self = static_cast<HTTPRequestParser*>(parser);
self->body.append(data, size);
return 0;
};
static inline auto OnMessageComplete(llhttp_t* parser) -> int {
auto* self = static_cast<HTTPRequestParser*>(parser);
self->done = true;
return 0;
};
};
} // namespace cserver::server::http