]> git.leonardobizzoni.com Git - http-lib/commitdiff
Server initialization and read client message setup
authorLeonardoBizzoni <leo2002714@gmail.com>
Wed, 14 Aug 2024 16:14:02 +0000 (18:14 +0200)
committerLeonardoBizzoni <leo2002714@gmail.com>
Wed, 14 Aug 2024 16:14:02 +0000 (18:14 +0200)
src/error.h
src/http.h
src/listener.cpp
src/listener.h
src/send.cpp

index 1c2f2d51c97c81ecf27ded3692308e69823e0995..f67be2451bcea4b800f952c7c357b46a841f6df9 100644 (file)
@@ -3,6 +3,8 @@
 namespace http {
   enum class Error {
     SocketCreation,
+    SocketBind,
+    SocketListen,
     SocketConnection,
     DNSResolution,
     ServerNotFound,
index c3bf9ae3aa0243f37b542e4183700f04c1b4dd0d..eec9f75d5a03ddcf71929df45af158583f132cbd 100644 (file)
@@ -17,7 +17,7 @@ namespace http {
   std::expected<int8_t, Error> connect(const std::string_view& domain_name, const uint16_t port = 80);
 
   std::string build_request(Method method, const Request &req);
-  std::expected<std::string, Error> read_raw_response(const int8_t socketfd);
+  std::expected<std::string, Error> read_raw_message(const uint8_t socketfd);
 
   namespace async {
     std::future<std::expected<Response, Error>> send(Method method, const Request &req);
index 7bdb65650640b9e667839130a73a34c73b4d3da9..4ff4ff88e9fed2749e885867b5e0420a1a669c3d 100644 (file)
@@ -1,16 +1,56 @@
 #include "listener.h"
 
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <cstdio>
+#include <iostream>
+
+#include "error.h"
+#include "http.h"
+
 namespace http {
-  std::expected<Listener, Error> Listener::create_on_local(uint16_t port) {
+  Listener::Listener() : routes({}), socketfd(::socket(AF_INET, SOCK_STREAM, 0)), addr({}) {}
+
+  std::expected<Listener, Error> 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<void, Error> 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
index 489d5a684e8f2e1f558ac8b4c4923cec03683b9e..00bc6d2a83269179bc50c5f0b879d8c6a1e20a10 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once
 
+#include <netinet/in.h>
+
 #include <cstdint>
 #include <expected>
 #include <functional>
@@ -14,16 +16,28 @@ namespace http {
   public:
     ~Listener() {}
 
-    static std::expected<Listener, Error> create_on_local(uint16_t port);
-    static std::expected<Listener, Error> create_on_lan(uint16_t port);
+    static inline std::expected<Listener, Error> on_local(uint16_t port, uint16_t backlog = 4096) {
+      return on(port, INADDR_LOOPBACK, backlog);
+    }
+
+    static inline std::expected<Listener, Error> on_LAN(uint16_t port, uint16_t backlog = 4096) {
+      return on(port, INADDR_ANY, backlog);
+    }
 
-    void serve();
-    void serve_async();
+    std::expected<void, Error> serve();
+    std::expected<void, Error> serve_async();
 
   private:
-    Listener() : routes({}) {}
+    Listener();
+
+    static std::expected<Listener, Error> on(uint16_t port, in_addr_t addr,
+                                            uint16_t backlog = 4096);
 
   public:
     std::unordered_map<std::string, std::function<void(const Request &)>> routes;
+
+  private:
+    int8_t socketfd;
+    struct sockaddr_in addr;
   };
 }  // namespace http
index 4be2fd1748128e2f3f6ba0d5a213ec71fbe5305c..ee8ed6445726e0b035f170ca261ca77d4ac41894 100644 (file)
@@ -2,6 +2,7 @@
 #include <unistd.h>
 
 #include <cstdint>
+#include <cstring>
 #include <expected>
 #include <iostream>
 #include <sstream>
@@ -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<std::string, Error> read_raw_response(const int8_t socketfd) {
+  std::expected<std::string, Error> 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();