2026-09-06 21:28:55 -07:00
|
|
|
/*
|
|
|
|
|
streamer-tools OBS Camera Plugin - HTTP client interface
|
|
|
|
|
Copyright (C) 2026 CyberCoveLLC <jknapp85@gmail.com>
|
|
|
|
|
|
2026-09-07 04:44:16 -07:00
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
2026-09-06 21:28:55 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#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 <map>
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
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
|