HTTP -> Http

This commit is contained in:
sha512sum 2024-06-27 01:12:31 +00:00
parent 0d77aa7e3c
commit 61a7e85e52
10 changed files with 55 additions and 55 deletions

View file

@ -2,15 +2,15 @@
#include <cserver/engine/basic/task_processor.hpp>
#include <cserver/server/handlers/http_handler_base.hpp>
struct SomeComponent : public cserver::server::handlers::HTTPHandlerBaseWithAdder<SomeComponent> {
struct SomeComponent : public cserver::server::handlers::HttpHandlerBaseWithAdder<SomeComponent> {
static constexpr utempl::ConstexprString kPath = "/v1/some/";
static constexpr utempl::ConstexprString kName = "name";
static constexpr utempl::ConstexprString kHandlerManagerName = "server";
inline constexpr SomeComponent(auto name, auto& context) :
HTTPHandlerBaseWithAdder(name, context) {};
HttpHandlerBaseWithAdder(name, context) {};
inline auto HandleRequestThrow(const cserver::server::http::HTTPRequest& request) -> cserver::Task<cserver::server::http::HTTPResponse> {
co_return cserver::server::http::HTTPResponse{.body = request.url.data()};
inline auto HandleRequestThrow(const cserver::server::http::HttpRequest& request) -> cserver::Task<cserver::server::http::HttpResponse> {
co_return cserver::server::http::HttpResponse{.body = request.url.data()};
};
};

View file

@ -52,16 +52,16 @@ private:
std::unreachable();
}();
} else {
return [] -> server::http::HTTPResponse {
return [] -> server::http::HttpResponse {
std::unreachable();
}();
};
};
template <typename Socket>
inline auto ReadHeaders(Socket&& socket, auto&&...) const -> cserver::Task<server::http::HTTPResponse> {
inline auto ReadHeaders(Socket&& socket, auto&&...) const -> cserver::Task<server::http::HttpResponse> {
std::string serverResponse;
co_await boost::asio::async_read_until(socket, boost::asio::dynamic_buffer(serverResponse), "\r\n\r\n", boost::asio::use_awaitable);
server::http::HTTPResponse response;
server::http::HttpResponse response;
std::istringstream responseStream(std::move(serverResponse));
std::string httpVersion;
responseStream >> httpVersion >> response.statusCode;

View file

@ -7,7 +7,7 @@ namespace cserver::clients::http {
template <typename HttpClient>
struct Request {
HttpClient& client;
server::http::HTTPRequest request;
server::http::HttpRequest request;
Request(HttpClient& client) :
client(client) {
this->AddHeader("User-Agent", "cserver/1");

View file

@ -6,7 +6,7 @@
namespace cserver::clients::http {
template <typename HttpClient, typename Socket>
class Response : public server::http::HTTPResponse {
class Response : public server::http::HttpResponse {
HttpClient& client;
Socket socket;
@ -25,10 +25,10 @@ public:
};
inline constexpr Response(Response&&) = default;
inline constexpr Response(const Response&) = default;
inline constexpr Response(HttpClient& client, Socket socket, server::http::HTTPResponse response) :
inline constexpr Response(HttpClient& client, Socket socket, server::http::HttpResponse response) :
client(client),
socket(std::move(socket)),
HTTPResponse(std::move(response)) {};
HttpResponse(std::move(response)) {};
};
} // namespace cserver::clients::http

View file

@ -7,16 +7,16 @@
namespace cserver::server::handlers {
struct HTTPHandlerBase {
struct HttpHandlerBase {
template <typename T, utempl::ConstexprString name, Options Options>
static consteval auto Adder(const auto& context) {
static consteval auto HttpHandlerAdder(const auto& context) {
return context.TransformComponents([]<typename TT>(const ComponentConfig<T::kHandlerManagerName, TT, Options>) {
return ComponentConfig<T::kHandlerManagerName, typename TT::template AddHandler<ComponentConfig<name, T, Options>>, Options>{};
});
};
template <typename Self>
inline auto HandleRequest(this Self&& self, http::HTTPRequest&& request
) -> Task<http::HTTPResponse> requires requires{self.HandleRequestThrow(std::move(request));} {
inline auto HandleRequest(this Self&& self, http::HttpRequest&& request
) -> Task<http::HttpResponse> requires requires{self.HandleRequestThrow(std::move(request));} {
using T = std::remove_cvref_t<Self>;
try {
co_return co_await std::forward<Self>(self).HandleRequestThrow(std::move(request));
@ -25,11 +25,11 @@ struct HTTPHandlerBase {
} catch(...) {
fmt::println("Error in handler with default name {}: Unknown Error", T::kName);
};
co_return http::HTTPResponse{.statusCode = 500, .statusMessage = "Internal Server Error", .body = "Internal Server Error"};
co_return http::HttpResponse{.statusCode = 500, .statusMessage = "Internal Server Error", .body = "Internal Server Error"};
};
template <typename Self>
inline auto HandleRequestStream(this Self&& self, cserver::server::http::HTTPRequest&& request,
cserver::server::http::HTTPStream& stream) -> Task<void> requires requires{self.HandleRequestStreamThrow(std::move(request), stream);} {
inline auto HandleRequestStream(this Self&& self, cserver::server::http::HttpRequest&& request,
cserver::server::http::HttpStream& stream) -> Task<void> requires requires{self.HandleRequestStreamThrow(std::move(request), stream);} {
using T = std::remove_cvref_t<Self>;
try {
co_await std::forward<Self>(self).HandleRequestStreamThrow(std::move(request), stream);
@ -40,20 +40,20 @@ struct HTTPHandlerBase {
};
co_await stream.Close();
};
inline constexpr HTTPHandlerBase(auto, auto&) {};
inline constexpr HttpHandlerBase(auto, auto&) {};
};
template <typename T>
struct HTTPHandlerAdder {
struct HttpHandlerAdderType {
template <utempl::ConstexprString Name, Options Options>
static consteval auto Adder(const auto& context) {
return HTTPHandlerBase::template Adder<T, Name, Options>(context);
return HttpHandlerBase::template HttpHandlerAdder<T, Name, Options>(context);
};
};
template <typename T>
struct HTTPHandlerBaseWithAdder : HTTPHandlerBase, HTTPHandlerAdder<T> {
inline constexpr HTTPHandlerBaseWithAdder(auto name, auto& context) :
HTTPHandlerBase(name, context),
HTTPHandlerAdder<T>{} {};
struct HttpHandlerBaseWithAdder : HttpHandlerBase, HttpHandlerAdderType<T> {
inline constexpr HttpHandlerBaseWithAdder(auto name, auto& context) :
HttpHandlerBase(name, context),
HttpHandlerAdderType<T>{} {};
};
} // namespace cserver::server::handlers

View file

@ -6,14 +6,14 @@
namespace cserver::server::http {
struct HTTPRequest {
struct HttpRequest {
std::string method = {};
boost::urls::url url = {};
std::unordered_map<std::string, std::string> headers = {};
std::string body = {};
inline auto ToString() const -> std::string {
std::ostringstream stream;
stream << fmt::format("{} {} HTTP/1.1\r\n", this->method, this->url.path());
stream << fmt::format("{} {} Http/1.1\r\n", this->method, this->url.path());
for(const auto& header : this->headers) {
stream << fmt::format("{}: {}\r\n", header.first, header.second);
};

View file

@ -4,65 +4,65 @@
namespace cserver::server::http {
struct HTTPRequestParser : private llhttp_t, public HTTPRequest {
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) {
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;
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));
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);
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);
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);
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);
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);
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);
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);
auto* self = static_cast<HttpRequestParser*>(parser);
self->done = true;
return 0;
};

View file

@ -5,14 +5,14 @@
namespace cserver::server::http {
struct HTTPResponse {
struct HttpResponse {
unsigned short statusCode = 200;
std::string statusMessage = "OK";
std::unordered_map<std::string, std::string> headers = {};
std::string body = {};
inline auto ToString() const -> std::string {
std::ostringstream stream;
stream << fmt::format("HTTP/1.1 {} {}\r\n", this->statusCode, this->statusMessage);
stream << fmt::format("Http/1.1 {} {}\r\n", this->statusCode, this->statusMessage);
for(const auto& header : this->headers) {
stream << fmt::format("{}: {}\r\n", header.first, header.second);
};

View file

@ -5,7 +5,7 @@
namespace cserver::server::http {
struct HTTPStream {
struct HttpStream {
boost::asio::ip::tcp::socket socket;
std::stringstream stream = {};
inline auto SetMethod(std::string method) -> Task<void> {
@ -13,7 +13,7 @@ struct HTTPStream {
co_await boost::asio::async_write(this->socket, boost::asio::buffer(method.data(), method.size()), boost::asio::transfer_all(), boost::asio::use_awaitable);
};
inline auto SetStatus(std::string status) -> Task<void> {
status = fmt::format("HTTP/1.1 {}\r\n", std::move(status));
status = fmt::format("Http/1.1 {}\r\n", std::move(status));
co_await boost::asio::async_write(this->socket, boost::asio::buffer(status.data(), status.size()), boost::asio::transfer_all(), boost::asio::use_awaitable);
};

View file

@ -49,13 +49,13 @@ struct Server : StopBlocker {
Server(std::index_sequence_for<Ts...>{}, name, context) {
};
template<auto I, typename Socket>
auto ProcessHandler(Socket&& socket, http::HTTPRequest request) -> Task<void> {
if constexpr(requires(http::HTTPStream& stream){Get<I>(this->handlers).HandleRequestStream(std::move(request), stream);}) {
http::HTTPStream stream{std::move(socket)};
auto ProcessHandler(Socket&& socket, http::HttpRequest request) -> Task<void> {
if constexpr(requires(http::HttpStream& stream){Get<I>(this->handlers).HandleRequestStream(std::move(request), stream);}) {
http::HttpStream stream{std::move(socket)};
co_await Get<I>(this->handlers).HandleRequestStream(std::move(request), stream);
co_return;
} else {
http::HTTPResponse response = co_await Get<I>(this->handlers).HandleRequest(std::move(request));
http::HttpResponse response = co_await Get<I>(this->handlers).HandleRequest(std::move(request));
response.headers["Content-Length"] = std::to_string(response.body.size());
response.headers["Server"] = "cserver/1";
auto data = response.ToString();
@ -67,7 +67,7 @@ struct Server : StopBlocker {
std::string buffer;
buffer.reserve(socket.available());
co_await boost::asio::async_read_until(socket, boost::asio::dynamic_buffer(buffer), "\r\n\r\n", boost::asio::use_awaitable);
http::HTTPRequest request = http::HTTPRequestParser{buffer};
http::HttpRequest request = http::HttpRequestParser{buffer};
bool flag = false;
co_await [&]<auto... Is>(std::index_sequence<Is...>) -> cserver::Task<void> {
(co_await [&] -> cserver::Task<void> {
@ -76,7 +76,7 @@ struct Server : StopBlocker {
};
}(), ...);
}(std::index_sequence_for<Ts...>());
constexpr std::string_view error404 = "HTTP/1.1 404 Not Found\r\n"
constexpr std::string_view error404 = "Http/1.1 404 Not Found\r\n"
"Content-Length: 0\r\n"
"\r\n";
if(!flag) {