LCOV - code coverage report
Current view: top level - http/client - http_client_base.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 16 16
Test Date: 2026-02-20 15:38:22 Functions: 100.0 % 15 15

            Line data    Source code
       1              : #ifndef THINGER_HTTP_CLIENT_HTTP_CLIENT_BASE_HPP
       2              : #define THINGER_HTTP_CLIENT_HTTP_CLIENT_BASE_HPP
       3              : 
       4              : #include "../common/http_request.hpp"
       5              : #include "../common/http_response.hpp"
       6              : #include "client_connection.hpp"
       7              : #include "client_response.hpp"
       8              : #include "connection_pool.hpp"
       9              : #include "websocket_client.hpp"
      10              : #include "stream_types.hpp"
      11              : #include "../../util/types.hpp"
      12              : #include "form.hpp"
      13              : #include <memory>
      14              : #include <string>
      15              : #include <chrono>
      16              : #include <map>
      17              : #include <optional>
      18              : 
      19              : namespace thinger::http {
      20              : 
      21              : using headers_map = std::map<std::string, std::string>;
      22              : 
      23              : class http_client_base {
      24              : protected:
      25              :     // Configuration
      26          702 :     std::chrono::seconds timeout_{30};
      27              :     unsigned int max_redirects_{5};
      28              :     bool follow_redirects_{true};
      29              :     std::string user_agent_{"ThingerHTTP/2.0"};
      30              :     bool auto_decompress_{true};
      31              :     bool verify_ssl_{true};
      32              : 
      33              :     // Connection pool for keep-alive
      34              :     connection_pool pool_;
      35              : 
      36              :     // Abstract method - each derived class provides its own io_context
      37              :     virtual boost::asio::io_context& get_io_context() = 0;
      38              : 
      39              :     // Apply default headers
      40              :     void apply_default_headers(const std::shared_ptr<http_request>& request);
      41              : 
      42              :     // Create or get connection for request
      43              :     std::shared_ptr<client_connection> get_or_create_connection(const std::shared_ptr<http_request>& request);
      44              : 
      45              : public:
      46         2106 :     http_client_base() = default;
      47              :     virtual ~http_client_base();
      48              : 
      49              :     // Configuration setters (fluent API)
      50          348 :     http_client_base& timeout(std::chrono::seconds t) { timeout_ = t; return *this; }
      51           38 :     http_client_base& max_redirects(unsigned int max) { max_redirects_ = max; return *this; }
      52           48 :     http_client_base& follow_redirects(bool follow) { follow_redirects_ = follow; return *this; }
      53           22 :     http_client_base& user_agent(const std::string& agent) { user_agent_ = agent; return *this; }
      54           24 :     http_client_base& auto_decompress(bool decompress) { auto_decompress_ = decompress; return *this; }
      55           68 :     http_client_base& verify_ssl(bool verify) { verify_ssl_ = verify; return *this; }
      56              : 
      57              :     // Configuration getters
      58           18 :     std::chrono::seconds get_timeout() const { return timeout_; }
      59           30 :     unsigned int get_max_redirects() const { return max_redirects_; }
      60           36 :     bool get_follow_redirects() const { return follow_redirects_; }
      61           18 :     const std::string& get_user_agent() const { return user_agent_; }
      62           18 :     bool get_auto_decompress() const { return auto_decompress_; }
      63           22 :     bool get_verify_ssl() const { return verify_ssl_; }
      64              : 
      65              :     // Request creation
      66              :     std::shared_ptr<http_request> create_request(method m, const std::string& url);
      67              :     std::shared_ptr<http_request> create_request(method m, const std::string& url, const std::string& unix_socket);
      68              : 
      69              :     // Main HTTP methods - all return awaitable
      70              :     awaitable<client_response> get(const std::string& url, headers_map headers = {});
      71              :     awaitable<client_response> post(const std::string& url, std::string body = {},
      72              :                                     std::string content_type = "application/json", headers_map headers = {});
      73              :     awaitable<client_response> post(const std::string& url, const form& form, headers_map headers = {});
      74              :     awaitable<client_response> put(const std::string& url, std::string body = {},
      75              :                                    std::string content_type = "application/json", headers_map headers = {});
      76              :     awaitable<client_response> patch(const std::string& url, std::string body = {},
      77              :                                      std::string content_type = "application/json", headers_map headers = {});
      78              :     awaitable<client_response> del(const std::string& url, headers_map headers = {});
      79              :     awaitable<client_response> head(const std::string& url, headers_map headers = {});
      80              :     awaitable<client_response> options(const std::string& url, headers_map headers = {});
      81              : 
      82              :     // Unix socket variants
      83              :     awaitable<client_response> get(const std::string& url, const std::string& unix_socket, headers_map headers = {});
      84              :     awaitable<client_response> post(const std::string& url, const std::string& unix_socket,
      85              :                                     std::string body = {}, std::string content_type = "application/json",
      86              :                                     headers_map headers = {});
      87              : 
      88              :     // Generic send with custom request
      89              :     awaitable<client_response> send(std::shared_ptr<http_request> request);
      90              : 
      91              :     // Streaming send - streams response through callback without loading into memory
      92              :     awaitable<stream_result> send_streaming(std::shared_ptr<http_request> request,
      93              :                                             stream_callback callback);
      94              : 
      95              :     // Send and get connection back (for upgrades like WebSocket)
      96              :     awaitable<std::pair<client_response, std::shared_ptr<client_connection>>>
      97              :         send_with_connection(std::shared_ptr<http_request> request);
      98              : 
      99              :     // WebSocket upgrade (simple API)
     100              :     awaitable<std::optional<websocket_client>> upgrade_websocket(
     101              :         const std::string& url,
     102              :         const std::string& subprotocol = "");
     103              : 
     104              :     // WebSocket upgrade with custom request/headers (for builder pattern)
     105              :     awaitable<std::optional<websocket_client>> upgrade_websocket(
     106              :         std::shared_ptr<http_request> request,
     107              :         const std::string& subprotocol = "");
     108              : 
     109              :     // Connection pool management
     110            2 :     void clear_connections() { pool_.clear(); }
     111            8 :     size_t pool_size() const { return pool_.size(); }
     112              : 
     113              : private:
     114              :     // Internal send with redirect handling
     115              :     awaitable<client_response> send_with_redirects(std::shared_ptr<http_request> request,
     116              :                                                    std::shared_ptr<client_connection> connection,
     117              :                                                    unsigned int redirect_count = 0);
     118              : 
     119              :     // Check if URLs have same origin (for security when forwarding headers)
     120              :     static bool is_same_origin(const std::string& url1, const std::string& url2);
     121              : };
     122              : 
     123              : } // namespace thinger::http
     124              : 
     125              : #endif
        

Generated by: LCOV version 2.0-1