/* streamer-tools OBS Camera Plugin - HTTP client interface Copyright (C) 2026 CyberCoveLLC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see */ #pragma once // A two-method HTTP interface, injectable so ApiClient can be unit-tested // without a network (mirroring the streamer-tools repo's injectable-deps // convention, per the design doc's Testing section). // // Backends, chosen per platform so no third-party HTTP dependency has to be // built on any of the three CI runners: // - Linux/macOS: libcurl. Already present on both (client-sdk-cpp's own // liblivekit links libcurl on Linux, and macOS ships libcurl in the SDK). // - Windows: WinHTTP, which ships with the OS and handles TLS through // SChannel -- avoiding an OpenSSL or curl build on the Windows runner. #include #include namespace stplugin { struct HttpResponse { /// HTTP status code, or 0 when the request never completed (DNS failure, /// TLS failure, timeout, ...). Callers must check `network_error` first. long status = 0; /// Response body. May be empty, may be arbitrary bytes: never assume it /// parses as JSON. std::string body; /// Empty on success. Non-empty means the request did not complete and /// `status`/`body` are meaningless. std::string network_error; bool ok() const { return network_error.empty(); } }; struct HttpRequest { std::string method = "GET"; std::string url; std::string body; std::string content_type; /// Whole-request timeout. Kept short: this runs on OBS's UI thread when /// the properties dropdown is refreshed, and on the source's own worker /// thread when a token is minted. int timeout_ms = 10000; }; class HttpClient { public: virtual ~HttpClient() = default; virtual HttpResponse send(const HttpRequest &request) = 0; }; /// Percent-encode a string for use in a URL query value. std::string urlEncode(const std::string &value); /// Construct the platform's real HTTP client. Returns nullptr if no backend /// was compiled in. HttpClient *createPlatformHttpClient(); } // namespace stplugin