From 0e056a8325d94d291311f957ada0cf1b4304bf49 Mon Sep 17 00:00:00 2001 From: LeonardoBizzoni Date: Wed, 14 Aug 2024 18:14:02 +0200 Subject: [PATCH] Server initialization and read client message setup --- src/error.h | 2 ++ src/http.h | 2 +- src/listener.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++--- src/listener.h | 24 +++++++++++++++++++----- src/send.cpp | 14 ++++++++------ 5 files changed, 73 insertions(+), 15 deletions(-) diff --git a/src/error.h b/src/error.h index 1c2f2d5..f67be24 100644 --- a/src/error.h +++ b/src/error.h @@ -3,6 +3,8 @@ namespace http { enum class Error { SocketCreation, + SocketBind, + SocketListen, SocketConnection, DNSResolution, ServerNotFound, diff --git a/src/http.h b/src/http.h index c3bf9ae..eec9f75 100644 --- a/src/http.h +++ b/src/http.h @@ -17,7 +17,7 @@ namespace http { std::expected connect(const std::string_view& domain_name, const uint16_t port = 80); std::string build_request(Method method, const Request &req); - std::expected read_raw_response(const int8_t socketfd); + std::expected read_raw_message(const uint8_t socketfd); namespace async { std::future> send(Method method, const Request &req); diff --git a/src/listener.cpp b/src/listener.cpp index 7bdb656..4ff4ff8 100644 --- a/src/listener.cpp +++ b/src/listener.cpp @@ -1,16 +1,56 @@ #include "listener.h" +#include +#include +#include + +#include +#include + +#include "error.h" +#include "http.h" + namespace http { - std::expected Listener::create_on_local(uint16_t port) { + Listener::Listener() : routes({}), socketfd(::socket(AF_INET, SOCK_STREAM, 0)), addr({}) {} + + std::expected Listener::on(uint16_t port, in_addr_t addr, uint16_t backlog) { Listener server; - ++port; + uint32_t opt = 1; + if (server.socketfd < 0 || ::setsockopt(server.socketfd, SOL_SOCKET, + SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)) < 0) { + return ERR(Error::SocketCreation); + } + + server.addr.sin_family = AF_INET; + server.addr.sin_addr.s_addr = htonl(addr); + server.addr.sin_port = htons(port); + + if (::bind(server.socketfd, (struct sockaddr *)&server.addr, sizeof(server.addr)) < 0) { + return ERR(Error::SocketBind); + } + + if (::listen(server.socketfd, backlog) < 0) { + return ERR(Error::SocketListen); + } return server; } + std::expected Listener::serve() { + socklen_t addrsize = sizeof(this->addr); + int8_t clientfd = ::accept(this->socketfd, (struct sockaddr *)&this->addr, &addrsize); + if (clientfd < 0) { + return ERR(Error::SocketConnection); + } - void Listener::serve() { + auto raw_req = read_raw_message(clientfd); + if (raw_req.has_value()) { + std::cout << raw_req.value() << std::endl; + } + ::shutdown(clientfd, SHUT_RDWR); + ::close(clientfd); + return {}; } } // namespace http diff --git a/src/listener.h b/src/listener.h index 489d5a6..00bc6d2 100644 --- a/src/listener.h +++ b/src/listener.h @@ -1,5 +1,7 @@ #pragma once +#include + #include #include #include @@ -14,16 +16,28 @@ namespace http { public: ~Listener() {} - static std::expected create_on_local(uint16_t port); - static std::expected create_on_lan(uint16_t port); + static inline std::expected on_local(uint16_t port, uint16_t backlog = 4096) { + return on(port, INADDR_LOOPBACK, backlog); + } + + static inline std::expected on_LAN(uint16_t port, uint16_t backlog = 4096) { + return on(port, INADDR_ANY, backlog); + } - void serve(); - void serve_async(); + std::expected serve(); + std::expected serve_async(); private: - Listener() : routes({}) {} + Listener(); + + static std::expected on(uint16_t port, in_addr_t addr, + uint16_t backlog = 4096); public: std::unordered_map> routes; + + private: + int8_t socketfd; + struct sockaddr_in addr; }; } // namespace http diff --git a/src/send.cpp b/src/send.cpp index 4be2fd1..ee8ed64 100644 --- a/src/send.cpp +++ b/src/send.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -84,7 +85,7 @@ namespace http { std::string msg = build_request(method, req); ::send((int)maybe_socketfd.value(), msg.c_str(), msg.size(), 0); - auto maybe_response = read_raw_response(maybe_socketfd.value()); + auto maybe_response = read_raw_message(maybe_socketfd.value()); if (!maybe_response.has_value()) { return ERR(maybe_response.error()); } @@ -109,18 +110,19 @@ namespace http { return ss.str(); } - std::expected read_raw_response(const int8_t socketfd) { + std::expected read_raw_message(const uint8_t socketfd) { std::stringstream ss; char buffer[BUFFSIZE] = ""; ssize_t bytes_read = 0; while ((bytes_read = read((int)socketfd, buffer, BUFFSIZE - 1)) > 0) { - if (bytes_read == -1) { - return ERR(Error::InvalidRead); - } - buffer[bytes_read] = '\0'; ss << buffer; + + if (buffer[bytes_read - 2] == '\r' && buffer[bytes_read - 1] == '\n') { + break; + } + ::memset(buffer, 0, BUFFSIZE * sizeof(char)); } return ss.str(); -- 2.52.0