Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
SC::HttpAsyncClient Struct Reference

Asynchronous HTTP/1.1 client using caller-provided fixed storage. More...

#include <HttpAsyncClient.h>

Classes

struct  Header
 
struct  RequestOptions
 

Public Member Functions

Result init (HttpConnectionBase &storage)
 Initializes the client with caller-provided connection storage The storage must outlive the client and provides buffers, queues and socket state.
 
Result close ()
 Closes any active connection and releases references to the initialized storage.
 
void setResponseDecompression (SyncZLibTransformStream &decoder)
 Enables opt-in gzip/deflate response decompression.
 
void clearResponseDecompression ()
 Disables response decompression for future requests.
 
Result setTransportSetup (Function< Result(HttpAsyncClientTransportSetup &)> &&setup, const void *owner=nullptr)
 Sets an optional transport setup hook invoked after TCP connect and before HTTP request bytes are sent.
 
Result setTransportPreflight (Function< Result(const HttpURLParser &)> &&preflight, const void *owner=nullptr)
 Sets an optional transport policy hook invoked after URL parsing and before DNS or socket activity.
 
Result setExternalConnector (Function< Result(HttpAsyncClientExternalConnection &)> &&connector, const void *owner=nullptr)
 Sets an optional connector that owns DNS and connection establishment for future requests.
 
Result setTransportClose (Function< void()> &&close, const void *owner=nullptr)
 Sets an optional transport teardown hook invoked before HTTP destroys the connected socket streams.
 
Result setTransportShutdown (Function< Result(Function< void(Result)>)> &&shutdown, const void *owner=nullptr)
 Sets an optional asynchronous hook that drains a transport before reconnecting to another origin.
 
Result clearTransportSetup (const void *owner=nullptr)
 Clears the optional transport setup hook and restores default socket transport setup.
 
Result claimTransport (const void *owner)
 Claims the complete transport hook group on a quiescent client without existing hooks or an owner.
 
Result releaseTransport (const void *owner)
 Clears hooks and releases only the matching owner's claim on a quiescent client.
 
Result detachWebSocketTransport (HttpWebSocketTransportView &transport)
 Hands the connected socket streams to a WebSocket owner after a validated 101 response.
 
Result start (AsyncEventLoop &loop, HttpParser::Method method, StringSpan url, bool keepAlive=false)
 Starts a request that must be configured inside onPrepareRequest onPrepareRequest must send the headers before returning, typically by calling HttpAsyncClientRequest::sendHeaders().
 
Result sendRequest (AsyncEventLoop &loop, const RequestOptions &options)
 Starts an auto-sent request described by caller-owned request options.
 
Result get (AsyncEventLoop &loop, StringSpan url, bool keepAlive=false)
 Convenience wrapper for a GET request without a request body.
 
Result head (AsyncEventLoop &loop, StringSpan url, bool keepAlive=false)
 Convenience wrapper for a HEAD request without a request body.
 
Result options (AsyncEventLoop &loop, StringSpan url, bool keepAlive=false)
 Convenience wrapper for an OPTIONS request without a request body.
 
Result deleteRequest (AsyncEventLoop &loop, StringSpan url, bool keepAlive=false)
 Convenience wrapper for a DELETE request without a request body.
 
Result put (AsyncEventLoop &loop, StringSpan url, Span< const char > body, bool keepAlive=false)
 Convenience wrapper for a PUT request with a fixed in-memory body.
 
Result put (AsyncEventLoop &loop, StringSpan url, StringSpan body, bool keepAlive=false)
 
Result post (AsyncEventLoop &loop, StringSpan url, Span< const char > body, bool keepAlive=false)
 Convenience wrapper for a POST request with a fixed in-memory body.
 
Result post (AsyncEventLoop &loop, StringSpan url, StringSpan body, bool keepAlive=false)
 
Result patch (AsyncEventLoop &loop, StringSpan url, Span< const char > body, bool keepAlive=false)
 Convenience wrapper for a PATCH request with a fixed in-memory body.
 
Result patch (AsyncEventLoop &loop, StringSpan url, StringSpan body, bool keepAlive=false)
 
Result postMultipart (AsyncEventLoop &loop, StringSpan url, HttpMultipartWriter &writer, bool keepAlive=false)
 Convenience wrapper for a multipart/form-data POST request.
 
HttpAsyncClientResponse & getResponse ()
 
const HttpAsyncClientResponse & getResponse () const
 

Public Attributes

Function< void(HttpAsyncClientRequest &)> onPrepareRequest
 Called after the request has been created and can still be customized.
 
Function< void(HttpAsyncClientResponse &)> onResponse
 Called after the response headers have been parsed.
 
Function< void(Result)> onError
 Called on connection, protocol or streaming errors.
 

Detailed Description

Asynchronous HTTP/1.1 client using caller-provided fixed storage.

HttpAsyncClient processes a single request at a time and can sequentially reuse the same connection when keep-alive is enabled and the next request targets the same host and port.

Use the convenience wrappers (get, head, put, post, patch, deleteRequest, options, postMultipart) when the request body is already available in memory. Use start() when the request must be customized inside onPrepareRequest, for example to stream the request body with HttpAsyncClientRequest::setBody(AsyncReadableStream&, uint64_t) or to write it manually through HttpAsyncClientRequest::getWritableStream().

onResponse is called after response headers have been parsed. The response body is then read incrementally from HttpAsyncClientResponse::getReadableStream(), and the readable stream eventEnd signals the end of the response body.

Example without a streamed request body:

client.onResponse = [this, &ctx](HttpAsyncClientResponse& response)
{
ctx.collector.attach(response,
[this, &ctx](HttpAsyncClientResponse& completedResponse)
{
ctx.collector.detach();
SC_TEST_EXPECT(completedResponse.getParser().statusCode == 200);
SC_TEST_EXPECT(StringView(ctx.collector.view()) == "hello");
SC_TEST_EXPECT(ctx.httpServer.stop());
});
};
client.onError = [this](Result result) { SC_TEST_EXPECT(result); };
SC_TEST_EXPECT(client.get(loop, url.view()));

Example streaming the request body:

client.onPrepareRequest = [this, &bodyStream](HttpAsyncClientRequest& request)
{
request.setBody(bodyStream, 11);
SC_TEST_EXPECT(request.sendHeaders());
};
client.onResponse = [this, &ctx](HttpAsyncClientResponse& response)
{
ctx.collector.attach(response,
[this, &ctx](HttpAsyncClientResponse& completedResponse)
{
ctx.collector.detach();
SC_TEST_EXPECT(completedResponse.getParser().statusCode == 201);
String content;
SC_TEST_EXPECT(ctx.fs.read("client-put-stream.txt", content));
SC_TEST_EXPECT(content == "ChunkedBody");
SC_TEST_EXPECT(ctx.fs.removeFile("client-put-stream.txt"));
SC_TEST_EXPECT(ctx.httpServer.stop());
});
};
client.onError = [this](Result result) { SC_TEST_EXPECT(result); };
SC_TEST_EXPECT(client.start(loop, HttpParser::Method::HttpPUT, url.view()));

Member Function Documentation

◆ claimTransport()

Result SC::HttpAsyncClient::claimTransport ( const void * owner)

Claims the complete transport hook group on a quiescent client without existing hooks or an owner.

The non-null token must remain address-stable until release and completion of adapter callbacks. Serialize configuration on the owning loop thread; mutation/release inside transport callbacks is rejected.

◆ clearResponseDecompression()

void SC::HttpAsyncClient::clearResponseDecompression ( )
inline

Disables response decompression for future requests.

◆ clearTransportSetup()

Result SC::HttpAsyncClient::clearTransportSetup ( const void * owner = nullptr)

Clears the optional transport setup hook and restores default socket transport setup.

◆ close()

Result SC::HttpAsyncClient::close ( )

Closes any active connection and releases references to the initialized storage.

◆ deleteRequest()

Result SC::HttpAsyncClient::deleteRequest ( AsyncEventLoop & loop,
StringSpan url,
bool keepAlive = false )

Convenience wrapper for a DELETE request without a request body.

◆ detachWebSocketTransport()

Result SC::HttpAsyncClient::detachWebSocketTransport ( HttpWebSocketTransportView & transport)

Hands the connected socket streams to a WebSocket owner after a validated 101 response.

◆ get()

Result SC::HttpAsyncClient::get ( AsyncEventLoop & loop,
StringSpan url,
bool keepAlive = false )

Convenience wrapper for a GET request without a request body.

◆ head()

Result SC::HttpAsyncClient::head ( AsyncEventLoop & loop,
StringSpan url,
bool keepAlive = false )

Convenience wrapper for a HEAD request without a request body.

◆ init()

Result SC::HttpAsyncClient::init ( HttpConnectionBase & storage)

Initializes the client with caller-provided connection storage The storage must outlive the client and provides buffers, queues and socket state.

◆ options()

Result SC::HttpAsyncClient::options ( AsyncEventLoop & loop,
StringSpan url,
bool keepAlive = false )

Convenience wrapper for an OPTIONS request without a request body.

◆ patch()

Result SC::HttpAsyncClient::patch ( AsyncEventLoop & loop,
StringSpan url,
Span< const char > body,
bool keepAlive = false )

Convenience wrapper for a PATCH request with a fixed in-memory body.

◆ post()

Result SC::HttpAsyncClient::post ( AsyncEventLoop & loop,
StringSpan url,
Span< const char > body,
bool keepAlive = false )

Convenience wrapper for a POST request with a fixed in-memory body.

◆ postMultipart()

Result SC::HttpAsyncClient::postMultipart ( AsyncEventLoop & loop,
StringSpan url,
HttpMultipartWriter & writer,
bool keepAlive = false )

Convenience wrapper for a multipart/form-data POST request.

◆ put()

Result SC::HttpAsyncClient::put ( AsyncEventLoop & loop,
StringSpan url,
Span< const char > body,
bool keepAlive = false )

Convenience wrapper for a PUT request with a fixed in-memory body.

◆ releaseTransport()

Result SC::HttpAsyncClient::releaseTransport ( const void * owner)

Clears hooks and releases only the matching owner's claim on a quiescent client.

A live idle keep-alive connection is not quiescent. Clear alone retains ownership.

◆ sendRequest()

Result SC::HttpAsyncClient::sendRequest ( AsyncEventLoop & loop,
const RequestOptions & options )

Starts an auto-sent request described by caller-owned request options.

Warning
Header/body/multipart storage must remain valid until the request has been sent.

◆ setExternalConnector()

Result SC::HttpAsyncClient::setExternalConnector ( Function< Result(HttpAsyncClientExternalConnection &)> && connector,
const void * owner = nullptr )
inline

Sets an optional connector that owns DNS and connection establishment for future requests.

When configured, Http invokes it after URL parsing and before any socket activity. The connector must install ready plaintext streams and complete the request asynchronously or synchronously.

◆ setResponseDecompression()

void SC::HttpAsyncClient::setResponseDecompression ( SyncZLibTransformStream & decoder)
inline

Enables opt-in gzip/deflate response decompression.

The caller owns the transform and must initialize its read/write queues with the client's buffer pool before starting a request. When a response declares Content-Encoding: gzip or deflate, onResponse observes the decoded body through HttpAsyncClientResponse::getReadableStream().

◆ setTransportClose()

Result SC::HttpAsyncClient::setTransportClose ( Function< void()> && close,
const void * owner = nullptr )
inline

Sets an optional transport teardown hook invoked before HTTP destroys the connected socket streams.

An adapter that installs alternate transport streams must release its listeners and state from this hook.

◆ setTransportPreflight()

Result SC::HttpAsyncClient::setTransportPreflight ( Function< Result(const HttpURLParser &)> && preflight,
const void * owner = nullptr )
inline

Sets an optional transport policy hook invoked after URL parsing and before DNS or socket activity.

This hook can reject URL forms that a transport adapter cannot represent safely. It must not retain the parser.

◆ setTransportSetup()

Result SC::HttpAsyncClient::setTransportSetup ( Function< Result(HttpAsyncClientTransportSetup &)> && setup,
const void * owner = nullptr )
inline

Sets an optional transport setup hook invoked after TCP connect and before HTTP request bytes are sent.

The hook can leave the socket streams active for plain HTTP, or install alternate active streams and complete later. This keeps TLS and other transport adapters outside the core Http library.

◆ setTransportShutdown()

Result SC::HttpAsyncClient::setTransportShutdown ( Function< Result(Function< void(Result)>)> && shutdown,
const void * owner = nullptr )
inline

Sets an optional asynchronous hook that drains a transport before reconnecting to another origin.

The hook must call complete exactly once after pending transport output has reached the underlying stream. Returning an error rejects the reconnect synchronously and means complete will not be called. The completion callback becomes invalid when the transport close hook runs and must then be discarded without invocation.

◆ start()

Result SC::HttpAsyncClient::start ( AsyncEventLoop & loop,
HttpParser::Method method,
StringSpan url,
bool keepAlive = false )

Starts a request that must be configured inside onPrepareRequest onPrepareRequest must send the headers before returning, typically by calling HttpAsyncClientRequest::sendHeaders().

Member Data Documentation

◆ onError

Function<void(Result)> SC::HttpAsyncClient::onError

Called on connection, protocol or streaming errors.

◆ onPrepareRequest

Function<void(HttpAsyncClientRequest&)> SC::HttpAsyncClient::onPrepareRequest

Called after the request has been created and can still be customized.

◆ onResponse

Function<void(HttpAsyncClientResponse&)> SC::HttpAsyncClient::onResponse

Called after the response headers have been parsed.


The documentation for this struct was generated from the following file: