// Copyright (c) 2026 Juhapekka Piiroinen // All Rights Reserved. // AmoosedWeb project: https://amoosed.com #pragma once #include "AmoosedWeb/Reader.hpp" #include #include #include #include namespace amoosed { // A caller transport runs synchronously on the Reader's worker thread. Its // response owns its bytes until the callback returns; the adapter copies them // before exposing them to the verified Reader. The callback must not call this // host recursively. Cancellation may be signalled from another thread. A // blocked callback must arrange its own wakeup before cancellation can return. struct CallbackRequest { enum class Kind { Range, Suffix, Complete } kind; std::string_view path; std::size_t first = 0, last = 0, max_body = 0; }; struct CallbackResponse { int status = 0; std::string final_url, content_range, etag, content_encoding; std::vector body; }; using HttpCallback = std::function; class CallbackHttpHost final : public HttpHost { public: CallbackHttpHost(std::string origin, HttpCallback callback); void cancel() noexcept override { cancelled_.store(true); } void reset_cancel() noexcept override { cancelled_.store(false); } bool cancelled() const override { return cancelled_.load(); } bool fetch_range(std::string_view path, std::size_t first, std::size_t last, std::size_t max_body, FetchResponse& response, std::string& error) override; bool fetch_suffix(std::string_view path, std::size_t length, std::size_t max_body, FetchResponse& response, std::string& error) override; bool fetch_complete(std::string_view path, std::size_t max_body, FetchResponse& response, std::string& error) override; private: bool fetch(CallbackRequest request, FetchResponse& response, std::string& error); std::string origin_; HttpCallback callback_; std::atomic_bool cancelled_{false}; }; }