4#include "HttpConnection.h"
6#include "HttpURLParser.h"
13struct HttpWebSocketTransportView;
26 SocketDescriptor::Handle nativeSocket = SocketDescriptor::Invalid;
28 Function<void(Result)> complete;
31template <
int ReadQueue,
int WriteQueue,
int HeaderBytes,
int StreamBytes>
33 :
public HttpStaticConnection<ReadQueue, WriteQueue, HeaderBytes, StreamBytes, 8, HttpConnectionBase>
35 static constexpr int ExtraBuffers = 8;
39 this->readableSocketStream.setAutoDestroy(
false);
40 this->writableSocketStream.setAutoDestroy(
false);
74 enum class BodyMode : uint8_t
85 Span<const Header> headers;
87 Span<const char> body;
91 uint64_t bodyLength = 0;
93 BodyMode bodyMode = BodyMode::None;
94 bool keepAlive =
false;
100 keepAlive = newKeepAlive;
106 headers = newHeaders;
112 keepAlive = newKeepAlive;
119 bodyStream =
nullptr;
120 multipartWriter =
nullptr;
122 bodyMode = BodyMode::None;
130 bodyLength = newBody.sizeInBytes();
131 bodyMode = BodyMode::Span;
135 RequestOptions& setBody(StringSpan newBody) {
return setBody(newBody.toCharSpan()); }
139 return setBody(StringSpan::fromNullTerminated(newBody, StringEncoding::Ascii));
145 bodyStream = &newBodyStream;
146 bodyLength = newBodyLength;
147 bodyMode = BodyMode::Stream;
154 multipartWriter = &newMultipartWriter;
155 bodyMode = BodyMode::Multipart;
220 Result
put(
AsyncEventLoop& loop, StringSpan url, Span<const char> body,
bool keepAlive =
false);
221 Result put(
AsyncEventLoop& loop, StringSpan url, StringSpan body,
bool keepAlive =
false)
223 return put(loop, url, body.toCharSpan(), keepAlive);
228 Result post(
AsyncEventLoop& loop, StringSpan url, StringSpan body,
bool keepAlive =
false)
230 return post(loop, url, body.toCharSpan(), keepAlive);
235 Result patch(
AsyncEventLoop& loop, StringSpan url, StringSpan body,
bool keepAlive =
false)
237 return patch(loop, url, body.toCharSpan(), keepAlive);
258 enum class BodyMode : uint8_t
270 bool keepAlive =
false;
271 bool autoSend =
false;
273 Span<const char> bodySpan;
275 BodyMode bodyMode = BodyMode::None;
276 uint64_t contentLength = 0;
278 Span<const Header> headers;
284 enum class State : uint8_t
293 Result startRequest(AsyncEventLoop& loop,
const RequestPreset& preset);
294 Result prepareRequest(
const RequestPreset& preset);
295 Result startPreparedRequest(
const RequestPreset& preset);
296 Result ensureConnected();
297 Result beginSocketConnection();
298 Result beginResponseRead();
299 Result beginRequestSend();
300 Result onResponseBodyStreamRead();
301 Result validateActiveRequest()
const;
303 void completeTransportSetup(Result result);
304 [[nodiscard]] Result rememberConnectedOrigin();
306 void finalizeResponse(
bool finishBodyStream);
307 void closeConnection();
308 void finishResponse();
309 void fail(Result error);
311 void onConnected(AsyncSocketConnect::Result& result);
312 void onReadableError(Result result);
313 void onWritableError(Result result);
314 void onPipelineError(Result result);
315 void onReadableEnd();
316 void onHeadersBufferWritten(AsyncBufferView::ID bufferID);
317 void onResponseData(AsyncBufferView::ID bufferID);
318 void onResponseBodyData(AsyncBufferView::ID bufferID);
319 void onCompressedResponseBodyData(AsyncBufferView::ID bufferID);
320 void onCompressedResponseBodyWritten(AsyncBufferView::ID bufferID);
321 void onCompressedResponseBodyEnd();
322 void onCompressedResponseError(Result result);
324 [[nodiscard]]
bool canReuseConnectionFor(StringSpan protocol, StringSpan host, uint16_t port)
const;
325 [[nodiscard]]
bool responseMustNotHaveBody()
const;
326 [[nodiscard]]
bool responseHasKnownLength()
const;
327 [[nodiscard]] Result prepareResponseDecompression();
328 [[nodiscard]] Result startResponseStreams();
329 void detachResponseDecompression();
331 HttpConnectionBase* connection =
nullptr;
333 AsyncEventLoop* eventLoop =
nullptr;
334 HttpAsyncClientRequest* currentRequest =
nullptr;
336 HttpAsyncClientRequest request;
337 HttpAsyncClientResponse response;
338 AsyncSocketConnect connectAsync;
339 RequestPreset currentPreset;
341 SyncZLibTransformStream* responseDecoder =
nullptr;
342 bool responseDecoderActive =
false;
344 Function<Result(HttpAsyncClientTransportSetup&)> transportSetup;
345 Function<void()> transportClose;
347 State state = State::Idle;
349 StringSpan currentProtocol;
350 char currentProtocolStorage[16] = {0};
352 StringSpan currentHost;
353 char currentHostStorage[256] = {0};
354 uint16_t currentPort = 0;
356 HttpURLParser currentURL;
357 uint32_t requestCount = 0;
359 bool hasOpenConnection =
false;
360 bool responseDelivered =
false;
361 bool responseFinalized =
false;
362 bool webSocketUpgraded =
false;
Asynchronous I/O (files, sockets, timers, processes, fs events, threads wake-up) (see Async) AsyncEve...
Definition Async.h:1486
Async source abstraction emitting data events in caller provided byte buffers.
Definition AsyncStreams.h:228
Definition HttpAsyncClient.h:34
Outgoing HTTP request sent by the client.
Definition HttpConnection.h:428
Incoming HTTP response received by the client.
Definition HttpConnection.h:259
Mutable transport setup view used by HttpAsyncClient after the TCP socket connects.
Definition HttpAsyncClient.h:20
Definition HttpAsyncClient.h:73
Asynchronous HTTP/1.1 client using caller-provided fixed storage.
Definition HttpAsyncClient.h:65
Result deleteRequest(AsyncEventLoop &loop, StringSpan url, bool keepAlive=false)
Convenience wrapper for a DELETE request without a request body.
Result options(AsyncEventLoop &loop, StringSpan url, bool keepAlive=false)
Convenience wrapper for an OPTIONS request without a request body.
void clearResponseDecompression()
Disables response decompression for future requests.
Definition HttpAsyncClient.h:175
Function< void(HttpAsyncClientResponse &)> onResponse
Called after the response headers have been parsed.
Definition HttpAsyncClient.h:250
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 detachWebSocketTransport(HttpWebSocketTransportView &transport)
Hands the connected socket streams to a WebSocket owner after a validated 101 response.
Result head(AsyncEventLoop &loop, StringSpan url, bool keepAlive=false)
Convenience wrapper for a HEAD request without a request body.
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 heade...
Function< void(Result)> onError
Called on connection, protocol or streaming errors.
Definition HttpAsyncClient.h:253
Result postMultipart(AsyncEventLoop &loop, StringSpan url, HttpMultipartWriter &writer, bool keepAlive=false)
Convenience wrapper for a multipart/form-data POST request.
Result close()
Closes any active connection and releases references to the initialized storage.
void clearTransportSetup()
Clears the optional transport setup hook and restores default socket transport setup.
Definition HttpAsyncClient.h:189
Result get(AsyncEventLoop &loop, StringSpan url, bool keepAlive=false)
Convenience wrapper for a GET request without a request body.
Result sendRequest(AsyncEventLoop &loop, const RequestOptions &options)
Starts an auto-sent request described by caller-owned request options.
void setTransportSetup(Function< Result(HttpAsyncClientTransportSetup &)> &&setup)
Sets an optional transport setup hook invoked after TCP connect and before HTTP request bytes are sen...
Definition HttpAsyncClient.h:181
Result init(HttpConnectionBase &storage)
Initializes the client with caller-provided connection storage The storage must outlive the client an...
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.
void setResponseDecompression(SyncZLibTransformStream &decoder)
Enables opt-in gzip/deflate response decompression.
Definition HttpAsyncClient.h:172
Function< void(HttpAsyncClientRequest &)> onPrepareRequest
Called after the request has been created and can still be customized.
Definition HttpAsyncClient.h:247
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.
void setTransportClose(Function< void()> &&close)
Sets an optional transport teardown hook invoked before HTTP destroys the connected socket streams.
Definition HttpAsyncClient.h:186
Shared async transport storage for HTTP client and server endpoints.
Definition HttpConnection.h:73
Definition HttpConnection.h:40
Method
Method of the current request / response.
Definition HttpParser.h:19
Adds compile-time configurable read and write queues to any class subclassing HttpConnectionBase.
Definition HttpConnection.h:654
Parse an URL splitting it into its base components.
Definition HttpURLParser.h:71
Minimal transport handoff shape for later HTTP upgrade integration.
Definition HttpWebSocket.h:58