LCOV - code coverage report
Current view: top level - http/client - client_response.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 70.7 % 41 29
Test Date: 2026-02-20 15:38:22 Functions: 84.6 % 13 11

            Line data    Source code
       1              : #ifndef THINGER_HTTP_CLIENT_RESPONSE_HPP
       2              : #define THINGER_HTTP_CLIENT_RESPONSE_HPP
       3              : 
       4              : #include "../common/http_response.hpp"
       5              : #include <boost/system/error_code.hpp>
       6              : #include <cassert>
       7              : #include <memory>
       8              : #include <nlohmann/json.hpp>
       9              : 
      10              : namespace thinger::http {
      11              : 
      12              : class client_response {
      13              : private:
      14              :     std::shared_ptr<http_response> response_;
      15              :     boost::system::error_code error_;
      16              :     
      17              : public:
      18              :     // Constructors
      19              :     client_response() = default;
      20              :     
      21          767 :     client_response(const boost::system::error_code& ec, 
      22              :                    std::shared_ptr<http_response> res)
      23          767 :         : response_(std::move(res)), error_(ec) {}
      24              :     
      25              :     // Status checks
      26          708 :     bool ok() const { 
      27         1382 :         return !error_ && response_ && static_cast<int>(response_->get_status()) >= 200 && 
      28         1382 :                static_cast<int>(response_->get_status()) < 300; 
      29              :     }
      30              :     
      31              :     bool success() const { return ok(); }
      32              :     
      33              :     operator bool() const { return !error_ && response_; }
      34              :     
      35              :     bool has_error() const { return error_ || !response_; }
      36              :     
      37              :     bool has_network_error() const { return error_.value() != 0; }
      38              :     
      39            0 :     bool has_http_error() const { 
      40            0 :         return !error_ && response_ && static_cast<int>(response_->get_status()) >= 400; 
      41              :     }
      42              :     
      43              :     // Content access
      44           46 :     const std::string& body() const { 
      45           46 :         static const std::string empty;
      46           46 :         return response_ ? response_->get_content() : empty; 
      47              :     }
      48              :     
      49              :     std::string_view text() const { return body(); }
      50              :     
      51          193 :     nlohmann::json json() const {
      52          193 :         if (!response_ || response_->get_content().empty()) {
      53            0 :             return nlohmann::json();
      54              :         }
      55          193 :         auto j = nlohmann::json::parse(response_->get_content(), nullptr, false);
      56          193 :         if (j.is_discarded()) {
      57            0 :             return nlohmann::json();
      58              :         }
      59          193 :         return j;
      60          193 :     }
      61              :     
      62              :     // Status info
      63          164 :     int status() const { 
      64          164 :         return response_ ? static_cast<int>(response_->get_status()) : 0; 
      65              :     }
      66              :     
      67              :     int status_code() const { return status(); }
      68              :     
      69           15 :     bool is_redirect() const {
      70           15 :         return response_ && response_->is_redirect_response();
      71              :     }
      72              :     
      73            7 :     bool is_client_error() const {
      74            7 :         return response_ && status() >= 400 && status() < 500;
      75              :     }
      76              :     
      77            7 :     bool is_server_error() const {
      78            7 :         return response_ && status() >= 500;
      79              :     }
      80              :     
      81              :     // Headers
      82           37 :     std::string header(const std::string& key) const {
      83           37 :         return response_ && response_->has_header(key) ? 
      84          111 :                response_->get_header(key) : "";
      85              :     }
      86              :     
      87            6 :     bool has_header(const std::string& key) const {
      88            6 :         return response_ && response_->has_header(key);
      89              :     }
      90              :     
      91              :     // Error info
      92            0 :     std::string error() const {
      93            0 :         if (error_) {
      94            0 :             return error_.message();
      95            0 :         } else if (!response_) {
      96            0 :             return "No response received";
      97            0 :         } else if (has_http_error()) {
      98            0 :             return "HTTP error " + std::to_string(status());
      99              :         }
     100            0 :         return "";
     101              :     }
     102              :     
     103              :     std::string error_message() const { return error(); }
     104              :     
     105              :     const boost::system::error_code& error_code() const { return error_; }
     106              :     
     107              :     // Advanced access
     108              :     const http_response* operator->() const { return response_.get(); }
     109              :     
     110              :     const http_response& operator*() const {
     111              :         assert(response_ && "Dereferencing empty client_response");
     112              :         return *response_;
     113              :     }
     114              :     
     115              :     std::shared_ptr<http_response> get() const { return response_; }
     116              :     
     117              :     // Content type helpers
     118            8 :     std::string content_type() const {
     119           16 :         return header("Content-Type");
     120              :     }
     121              :     
     122              :     size_t content_length() const {
     123              :         if (!response_) return 0;
     124              :         return response_->get_content_size();
     125              :     }
     126              :     
     127              :     bool is_json() const {
     128              :         auto ct = content_type();
     129              :         return ct.find("application/json") != std::string::npos;
     130              :     }
     131              :     
     132              :     bool is_html() const {
     133              :         auto ct = content_type();
     134              :         return ct.find("text/html") != std::string::npos;
     135              :     }
     136              :     
     137              :     bool is_text() const {
     138              :         auto ct = content_type();
     139              :         return ct.find("text/") == 0;
     140              :     }
     141              : };
     142              : 
     143              : } // namespace thinger::http
     144              : 
     145              : #endif // THINGER_HTTP_CLIENT_RESPONSE_HPP
        

Generated by: LCOV version 2.0-1