LCOV - code coverage report
Current view: top level - http/server - response_observer.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 94.7 % 38 36
Test Date: 2026-11-10 10:38:07 Functions: 100.0 % 7 7

            Line data    Source code
       1              : #include "response_observer.hpp"
       2              : #include "request.hpp"
       3              : #include "../../util/logger.hpp"
       4              : 
       5              : namespace thinger::http {
       6              : 
       7         1170 : response_observer::response_observer(std::shared_ptr<request> req, std::shared_ptr<const response_hook> hook)
       8         1170 :     : request_(std::move(req)), hook_(std::move(hook)) {
       9         1170 :     request_->set_peer_ip(request_->get_peer_ip());
      10         1170 : }
      11              : 
      12         1459 : response_observer::~response_observer() {
      13         1170 :     if (reported_) return;
      14          289 :     if (!ended_) {
      15          289 :         info_.outcome = response_outcome::aborted;
      16          289 :         info_.duration = std::chrono::steady_clock::now() - start_;
      17              :     }
      18          289 :     report();
      19         2932 : }
      20              : 
      21          884 : void response_observer::head(http_response::status status, bool streamed) {
      22              :     // The last head is the response that ends (e.g. the 502 replacing a stream aborted in memory)
      23          884 :     info_.status = status;
      24          884 :     info_.streamed = streamed;
      25          884 : }
      26              : 
      27          881 : void response_observer::ended(response_outcome outcome) {
      28          881 :     if (ended_) return;
      29          881 :     ended_ = true;
      30          881 :     info_.outcome = aborted_.load(std::memory_order_relaxed) ? response_outcome::aborted : outcome;
      31          881 :     info_.duration = std::chrono::steady_clock::now() - start_;
      32          881 :     done();
      33              : }
      34              : 
      35         1170 : void response_observer::handled() {
      36         1170 :     if (handled_) return;
      37         1170 :     handled_ = true;
      38         1170 :     done();
      39              : }
      40              : 
      41         2051 : void response_observer::done() {
      42              :     // What each side wrote is seen by the one reporting
      43         4102 :     if (pending_.fetch_sub(1, std::memory_order_acq_rel) == 1) report();
      44         2051 : }
      45              : 
      46         1170 : void response_observer::report() noexcept {
      47         1170 :     reported_ = true;
      48              :     try {
      49         1170 :         (*hook_)(*request_, info_);
      50            6 :     } catch (const std::exception& e) {
      51            6 :         LOG_ERROR("error in the response hook: {}", e.what());
      52            6 :     } catch (...) {
      53            0 :         LOG_ERROR("unknown error in the response hook");
      54            0 :     }
      55         1170 :     if (on_reported_) on_reported_();
      56         1170 : }
      57              : 
      58              : } // namespace thinger::http
        

Generated by: LCOV version 2.0-1