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 % 17 17
Test Date: 2026-04-21 17:49:55 Functions: 100.0 % 16 16

            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          809 :     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              :     std::string unix_socket_;
      33              :     size_t max_content_size_{8 * 1048576};  // 8 MB default; buffered-mode responses above this are rejected
      34              : 
      35              :     // Connection pool for keep-alive
      36              :     connection_pool pool_;
      37              : 
      38              :     // Abstract method - each derived class provides its own io_context
      39              :     virtual boost::asio::io_context& get_io_context() = 0;
      40              : 
      41              :     // Apply default headers
      42              :     void apply_default_headers(const std::shared_ptr<http_request>& request);
      43              : 
      44              :     // Create or get connection for request
      45              :     std::shared_ptr<client_connection> get_or_create_connection(const std::shared_ptr<http_request>& request);
      46              : 
      47              : public:
      48         2427 :     http_client_base() = default;
      49              :     virtual ~http_client_base();
      50              : 
      51              :     // Configuration setters (fluent API)
      52          401 :     http_client_base& timeout(std::chrono::seconds t) { timeout_ = t; return *this; }
      53           38 :     http_client_base& max_redirects(unsigned int max) { max_redirects_ = max; return *this; }
      54           48 :     http_client_base& follow_redirects(bool follow) { follow_redirects_ = follow; return *this; }
      55           22 :     http_client_base& user_agent(const std::string& agent) { user_agent_ = agent; return *this; }
      56           24 :     http_client_base& auto_decompress(bool decompress) { auto_decompress_ = decompress; return *this; }
      57           68 :     http_client_base& verify_ssl(bool verify) { verify_ssl_ = verify; return *this; }
      58           45 :     http_client_base& unix_socket(const std::string& path) { unix_socket_ = path; return *this; }
      59              :     http_client_base& max_content_size(size_t size) { max_content_size_ = size; return *this; }
      60              : 
      61              :     // Configuration getters
      62           18 :     std::chrono::seconds get_timeout() const { return timeout_; }
      63           30 :     unsigned int get_max_redirects() const { return max_redirects_; }
      64           36 :     bool get_follow_redirects() const { return follow_redirects_; }
      65           18 :     const std::string& get_user_agent() const { return user_agent_; }
      66           18 :     bool get_auto_decompress() const { return auto_decompress_; }
      67           22 :     bool get_verify_ssl() const { return verify_ssl_; }
      68              :     size_t get_max_content_size() const { return max_content_size_; }
      69              : 
      70              :     // Request creation
      71              :     std::shared_ptr<http_request> create_request(method m, const std::string& url);
      72              : 
      73              :     // Main HTTP methods - all return awaitable
      74              :     awaitable<client_response> get(const std::string& url, headers_map headers = {});
      75              :     awaitable<client_response> post(const std::string& url, std::string body = {},
      76              :                                     std::string content_type = "application/json", headers_map headers = {});
      77              :     awaitable<client_response> post(const std::string& url, const form& form, headers_map headers = {});
      78              :     awaitable<client_response> put(const std::string& url, std::string body = {},
      79              :                                    std::string content_type = "application/json", headers_map headers = {});
      80              :     awaitable<client_response> patch(const std::string& url, std::string body = {},
      81              :                                      std::string content_type = "application/json", headers_map headers = {});
      82              :     awaitable<client_response> del(const std::string& url, headers_map headers = {});
      83              :     awaitable<client_response> head(const std::string& url, headers_map headers = {});
      84              :     awaitable<client_response> options(const std::string& url, headers_map headers = {});
      85              : 
      86              :     // Generic send with custom request
      87              :     awaitable<client_response> send(std::shared_ptr<http_request> request);
      88              : 
      89              :     // Streaming send - streams response through callback without loading into memory
      90              :     awaitable<stream_result> send_streaming(std::shared_ptr<http_request> request,
      91              :                                             stream_callback callback);
      92              : 
      93              :     // Send and get connection back (for upgrades like WebSocket)
      94              :     awaitable<std::pair<client_response, std::shared_ptr<client_connection>>>
      95              :         send_with_connection(std::shared_ptr<http_request> request);
      96              : 
      97              :     // WebSocket upgrade (simple API)
      98              :     awaitable<std::optional<websocket_client>> upgrade_websocket(
      99              :         const std::string& url,
     100              :         const std::string& subprotocol = "");
     101              : 
     102              :     // WebSocket upgrade with custom request/headers (for builder pattern)
     103              :     awaitable<std::optional<websocket_client>> upgrade_websocket(
     104              :         std::shared_ptr<http_request> request,
     105              :         const std::string& subprotocol = "");
     106              : 
     107              :     // Connection pool management
     108            2 :     void clear_connections() { pool_.clear(); }
     109            8 :     size_t pool_size() const { return pool_.size(); }
     110              : 
     111              : private:
     112              :     // Internal send with redirect handling
     113              :     awaitable<client_response> send_with_redirects(std::shared_ptr<http_request> request,
     114              :                                                    std::shared_ptr<client_connection> connection,
     115              :                                                    unsigned int redirect_count = 0);
     116              : 
     117              :     // Check if URLs have same origin (for security when forwarding headers)
     118              :     static bool is_same_origin(const std::string& url1, const std::string& url2);
     119              : };
     120              : 
     121              : } // namespace thinger::http
     122              : 
     123              : #endif
        

Generated by: LCOV version 2.0-1