]> git.leonardobizzoni.com Git - http-lib/commitdiff
Removed fields from Request in favour of map to allow optional field
authorLeonardoBizzoni <leo2002714@gmail.com>
Thu, 15 Aug 2024 15:01:01 +0000 (17:01 +0200)
committerLeonardoBizzoni <leo2002714@gmail.com>
Thu, 15 Aug 2024 15:01:01 +0000 (17:01 +0200)
Also renamed the `ERR` macro to `Err` and changed `NEW_LINE` from a C
macro to a `constexpr`

src/http.h
src/listener.cpp
src/request.cpp
src/request.h
src/response.cpp
src/send.cpp

index eec9f75d5a03ddcf71929df45af158583f132cbd..87d16f3b11a308d1ab9da072dca5d286ea25ad90 100644 (file)
@@ -8,10 +8,11 @@
 #include "response.h"
 #include "listener.h"
 
-#define ERR(error) std::unexpected(error)
-#define NEW_LINE std::string_view("\r\n")
+#define Err(error) std::unexpected(error)
 
 namespace http {
+  constexpr std::string_view NEW_LINE = "\r\n";
+
   std::expected<Response, Error> send(Method, const Request& req);
 
   std::expected<int8_t, Error> connect(const std::string_view& domain_name, const uint16_t port = 80);
index 4ff4ff88e9fed2749e885867b5e0420a1a669c3d..31bb3fe3d1e9edbde60542e4630d185595a723c9 100644 (file)
@@ -19,7 +19,7 @@ namespace http {
     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);
+      return Err(Error::SocketCreation);
     }
 
     server.addr.sin_family = AF_INET;
@@ -27,11 +27,11 @@ namespace http {
     server.addr.sin_port = htons(port);
 
     if (::bind(server.socketfd, (struct sockaddr *)&server.addr, sizeof(server.addr)) < 0) {
-      return ERR(Error::SocketBind);
+      return Err(Error::SocketBind);
     }
 
     if (::listen(server.socketfd, backlog) < 0) {
-      return ERR(Error::SocketListen);
+      return Err(Error::SocketListen);
     }
 
     return server;
@@ -41,7 +41,7 @@ namespace http {
     socklen_t addrsize = sizeof(this->addr);
     int8_t clientfd = ::accept(this->socketfd, (struct sockaddr *)&this->addr, &addrsize);
     if (clientfd < 0) {
-      return ERR(Error::SocketConnection);
+      return Err(Error::SocketConnection);
     }
 
     auto raw_req = read_raw_message(clientfd);
index 5908c2b5579f2dae797b7881f2a006304f29f8ae..0b194345725abe8e4c1ad50b892640eebc83cf50 100644 (file)
@@ -4,7 +4,5 @@
 
 std::ostream &operator<<(std::ostream &os, const http::Request &req) {
   return os << "Request { domain: " << std::quoted(req.domain_name) << ", port: " << req.port
-           << ", host: " << std::quoted(req.host) << ", query: " << std::quoted(req.query)
-           << ", accept: " << std::quoted(req.accept) << ", body: " << std::quoted(req.body)
-           << " }";
+           << ", query: " << std::quoted(req.query) << ", body: " << std::quoted(req.body) << " }";
 }
index 262261bc4977f6fb31cc2c4839a5431fba240bc2..270511316188c62d3af8561a79ab9035f80564a7 100644 (file)
@@ -3,6 +3,7 @@
 #include <cstdint>
 #include <string_view>
 #include <ostream>
+#include <unordered_map>
 
 namespace http {
   struct http_version {
@@ -13,12 +14,12 @@ namespace http {
   struct Request {
     uint16_t port = 80;
     std::string_view domain_name;
-    std::string_view host = domain_name;
     std::string_view query = "/";
-    std::string_view accept = "*/*";
     std::string_view body = "";
 
     http_version version = {.major = 1, .minor = 1};
+
+    std::unordered_map<std::string, std::string> optheaders = {};
   };
 }  // namespace http
 
index cc81be1c3cdb0d64c7ecbaf5a811d3d4c14896d9..4b02413119e7089fb1d7523ef998a732c33c3401 100644 (file)
@@ -8,7 +8,7 @@
 namespace http {
   std::expected<Response, Error> Response::build(std::string_view raw_response) noexcept {
     if (raw_response.empty()) {
-      return ERR(Error::InvalidResponse);
+      return Err(Error::InvalidResponse);
     }
 
     Response resp;
@@ -27,14 +27,14 @@ namespace http {
       resp.version = {.major = (uint8_t)std::stoi(major.data()),
                      .minor = (uint8_t)std::stoi(minor.data())};
     } catch (...) {
-      return ERR(Error::InvalidResponseHTTPVersion);
+      return Err(Error::InvalidResponseHTTPVersion);
     }
 
     try {
       std::string_view status(*++word_iter);
       resp.status = status_map[std::stoi(status.data())];
     } catch (...) {
-      return ERR(Error::InvalidResponseStatusCode);
+      return Err(Error::InvalidResponseStatusCode);
     }
 
     for (std::string_view line; lines_view_iter != lines_view.end() &&
index ee8ed6445726e0b035f170ca261ca77d4ac41894..f4daccab60e7fb1a32d3ee65e63be3605abac656 100644 (file)
@@ -24,7 +24,7 @@ namespace http {
     hints.ai_socktype = SOCK_STREAM;  // TCP only
 
     if (getaddrinfo(domain_name.data(), std::to_string(port).c_str(), &hints, &addr_list)) {
-      return ERR(Error::DNSResolution);
+      return Err(Error::DNSResolution);
     }
 
     int8_t remote_socketfd;
@@ -33,7 +33,7 @@ namespace http {
          socket(it->second.ai_family, it->second.ai_socktype, it->second.ai_protocol);
       if (remote_socketfd < 0) {
        close(remote_socketfd);
-       return ERR(Error::SocketConnection);
+       return Err(Error::SocketConnection);
       }
     } else {
       struct addrinfo *remote = 0;
@@ -65,7 +65,7 @@ namespace http {
 
       if (!remote) {
        freeaddrinfo(addr_list);
-       return ERR(Error::ServerNotFound);
+       return Err(Error::ServerNotFound);
       }
 
       ip_map[domain_name.data()] = *remote;
@@ -79,7 +79,7 @@ namespace http {
     auto maybe_socketfd = connect(req.domain_name, req.port);
 
     if (!maybe_socketfd.has_value()) {
-      return ERR(maybe_socketfd.error());
+      return Err(maybe_socketfd.error());
     }
 
     std::string msg = build_request(method, req);
@@ -87,7 +87,7 @@ namespace http {
 
     auto maybe_response = read_raw_message(maybe_socketfd.value());
     if (!maybe_response.has_value()) {
-      return ERR(maybe_response.error());
+      return Err(maybe_response.error());
     }
 
     close(maybe_socketfd.value());
@@ -98,11 +98,15 @@ namespace http {
     std::stringstream ss;
     ss << method << " " << req.query << " HTTP/" << (int)req.version.major << "."
        << (int)req.version.minor << NEW_LINE;
-    ss << "Host: " << req.host << NEW_LINE;
-    ss << "Accept: " << req.accept << NEW_LINE;
+    ss << "Host: " << req.domain_name << NEW_LINE;
+
+    for (const auto &header : req.optheaders) {
+      ss << header.first << ": " << header.second << NEW_LINE;
+    }
 
     if (!req.body.empty()) {
-      ss << "Content-Length: " << req.body.length() << NEW_LINE << NEW_LINE << req.body;
+      ss << "Content-Length: " << req.body.length() * sizeof(char) << NEW_LINE << NEW_LINE
+        << req.body;
     } else {
       ss << NEW_LINE;
     }