Add client stream handler
Introduce a new request callback, stream_handler. If set, it replaces all other content-serving mechanisms. The handler is not called in response to HEAD or CONNECT requests, or when following a redirect. Content-related default header fields are not added to the request. In conjunction with a response handler, it provides a minimal interface to implement a WebSocket client.
This commit is contained in:
parent
fc2daf930c
commit
b18a6e8456
26
httplib.h
26
httplib.h
@ -646,6 +646,7 @@ struct Request {
|
||||
|
||||
// for client
|
||||
ResponseHandler response_handler;
|
||||
StreamHandler stream_handler; // EXPERIMENTAL function signature may change
|
||||
ContentReceiverWithProgress content_receiver;
|
||||
Progress progress;
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@ -1180,6 +1181,7 @@ enum class Error {
|
||||
Compression,
|
||||
ConnectionTimeout,
|
||||
ProxyConnection,
|
||||
StreamHandler,
|
||||
|
||||
// For internal use only
|
||||
SSLPeerCouldBeClosed_,
|
||||
@ -2270,6 +2272,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;
|
||||
}
|
||||
@ -7825,10 +7828,12 @@ inline bool ClientImpl::write_request(Stream &strm, Request &req,
|
||||
}
|
||||
}
|
||||
|
||||
if (!req.has_header("Accept")) { req.set_header("Accept", "*/*"); }
|
||||
if (!req.stream_handler && !req.has_header("Accept")) {
|
||||
req.set_header("Accept", "*/*");
|
||||
}
|
||||
|
||||
if (!req.content_receiver) {
|
||||
if (!req.has_header("Accept-Encoding")) {
|
||||
if (!req.stream_handler && !req.has_header("Accept-Encoding")) {
|
||||
std::string accept_encoding;
|
||||
#ifdef CPPHTTPLIB_BROTLI_SUPPORT
|
||||
accept_encoding = "br";
|
||||
@ -7846,7 +7851,7 @@ inline bool ClientImpl::write_request(Stream &strm, Request &req,
|
||||
req.set_header("User-Agent", agent);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
if (req.body.empty()) {
|
||||
if (req.content_provider_) {
|
||||
@ -8078,13 +8083,26 @@ inline bool ClientImpl::process_request(Stream &strm, Request &req,
|
||||
res.status != StatusCode::NotModified_304 &&
|
||||
follow_location_;
|
||||
|
||||
if (req.response_handler && !redirect) {
|
||||
if (!redirect) {
|
||||
if (req.response_handler) {
|
||||
if (!req.response_handler(res)) {
|
||||
error = Error::Canceled;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (req.stream_handler) {
|
||||
// Log early
|
||||
if (logger_) { logger_(req, res); }
|
||||
|
||||
if (!req.stream_handler(strm)) {
|
||||
error = Error::StreamHandler;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
auto out =
|
||||
req.content_receiver
|
||||
? static_cast<ContentReceiverWithProgress>(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user