Add client stream handler

Introduce a new callback StreamHandler that replaces all other
content-serving mechanisms, if set. The handler is not called in
response to HEAD or CONNECT requests, or when following a redirect.

In conjunction with a response handler, it provides a minimal interface
to implement a WebSocket client.
This commit is contained in:
Florian Albrechtskirchinger 2025-02-03 11:42:03 +01:00
parent 708f860e3a
commit 2496aa960d
No known key found for this signature in database
GPG Key ID: 9C4E2AE92D3A9595

View File

@ -517,6 +517,9 @@ using Progress = std::function<bool(uint64_t current, uint64_t total)>;
struct Response;
using ResponseHandler = std::function<bool(const Response &response)>;
class Stream;
using StreamHandler = std::function<bool(Stream &strm)>;
struct MultipartFormData {
std::string name;
std::string content;
@ -634,6 +637,7 @@ struct Request {
// for client
ResponseHandler response_handler;
StreamHandler stream_handler;
ContentReceiverWithProgress content_receiver;
Progress progress;
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
@ -1148,6 +1152,7 @@ enum class Error {
Compression,
ConnectionTimeout,
ProxyConnection,
StreamHandler,
// For internal use only
SSLPeerCouldBeClosed_,
@ -2199,6 +2204,7 @@ inline std::string to_string(const Error error) {
case Error::Compression: return "Compression failed";
case Error::ConnectionTimeout: return "Connection timed out";
case Error::ProxyConnection: return "Proxy connection failed";
case Error::StreamHandler: return "Stream handler failed";
case Error::Unknown: return "Unknown";
default: break;
}
@ -8064,10 +8070,23 @@ inline bool ClientImpl::process_request(Stream &strm, Request &req,
res.status != StatusCode::NotModified_304 &&
follow_location_;
if (req.response_handler && !redirect) {
if (!req.response_handler(res)) {
error = Error::Canceled;
return false;
if (!redirect) {
if (req.response_handler) {
if (!req.response_handler(res)) {
error = Error::Canceled;
return false;
}
}
if (req.stream_handler) {
// Log
if (logger_) { logger_(req, res); }
if (!req.stream_handler(strm)) {
error = Error::StreamHandler;
return false;
}
return true;
}
}