4#include "../AsyncStreams/AsyncStreams.h"
5#include "../Common/Function.h"
6#include "../Common/Result.h"
7#include "../Common/Span.h"
14struct HttpAsyncClient;
15struct HttpAsyncClientRequest;
16struct HttpAsyncClientResponse;
59 uint64_t payloadLength = 0;
60 uint8_t maskKey[4] = {0, 0, 0, 0};
62 [[nodiscard]]
bool isControlFrame()
const;
74 [[nodiscard]]
bool isValid()
const
76 return readableStream !=
nullptr and writableStream !=
nullptr and buffersPool !=
nullptr;
87 StringSpan connection;
88 StringSpan secWebSocketKey;
89 StringSpan secWebSocketVersion;
95 uint32_t statusCode = 0;
98 StringSpan connection;
99 StringSpan secWebSocketAccept;
105 enum class Status : uint8_t
112 Status status = Status::BadRequest;
114 [[nodiscard]]
bool accepted()
const {
return status == Status::Accepted; }
115 [[nodiscard]]
int httpStatusCode()
const;
121 static constexpr size_t ClientKeyLength = 24;
122 static constexpr size_t AcceptKeyLength = 28;
123 static constexpr size_t NonceLength = 16;
125 static Result createClientKey(Span<const uint8_t> nonce, Span<char> storage, StringSpan& key);
126 static Result validateClientKey(StringSpan key);
127 static Result computeAccept(StringSpan clientKey, Span<char> storage, StringSpan& accept,
130 static bool headerContainsToken(StringSpan headerValue, StringSpan token);
137 StringSpan expectedClientKey,
143 static Result writeServerAccept(
HttpResponse& response, StringSpan clientKey, Span<char> acceptStorage,
147 Span<char> acceptStorage,
156 Function<void(Result)> onError;
165 void onClientError(Result result);
166 void fail(Result result);
170 StringSpan clientKey;
179 Function<Result(Span<char>,
bool)> onFramePayload;
182 Result parse(Span<char> data,
size_t& consumedBytes);
185 enum class State : uint8_t
194 Result onHeaderReady();
195 Result finishCurrentFrame();
200 State state = State::HeaderByte0;
202 bool fragmentedMessageInProgress =
false;
204 uint8_t headerByte0 = 0;
206 uint8_t extendedLengthBytesExpected = 0;
207 uint8_t extendedLengthBytesRead = 0;
208 uint8_t maskBytesRead = 0;
210 uint64_t extendedLengthAccumulator = 0;
211 uint64_t payloadBytesRemaining = 0;
212 uint64_t payloadBytesConsumed = 0;
221 Result writePayload(Span<char> payload);
222 Result finishFrame();
228 bool frameInProgress =
false;
229 bool fragmentedMessageInProgress =
false;
231 uint64_t payloadBytesRemaining = 0;
232 uint64_t payloadBytesWritten = 0;
240 void reset(Span<char> messageStorage);
243 Result onFramePayload(Span<char> payload,
bool frameFinished);
245 [[nodiscard]]
size_t getCurrentMessageSize()
const {
return messageSize; }
248 Span<char> messageStorage;
253 size_t messageSize = 0;
255 bool assemblingMessage =
false;
256 bool ignoringFrame =
false;
264 Function<Result(Span<char>)> onPing;
265 Function<Result(Span<char>)> onPong;
266 Function<Result(uint16_t, Span<char>)> onClose;
269 void setAutomaticMaskKey(
const uint8_t maskKey[4]);
271 Result receive(Span<char> data,
size_t& consumedBytes);
274 Span<const char>& encodedFrame);
275 Result sendData(
HttpWebSocketOpcode opcode, Span<const char> payload,
bool fin,
const uint8_t* maskKey,
276 Span<char> storage, Span<const char>& encodedFrame);
277 Result sendPing(Span<const char> payload,
const uint8_t* maskKey, Span<char> storage,
278 Span<const char>& encodedFrame);
279 Result sendPong(Span<const char> payload,
const uint8_t* maskKey, Span<char> storage,
280 Span<const char>& encodedFrame);
281 Result sendClose(uint16_t statusCode, Span<const char> reason,
const uint8_t* maskKey, Span<char> storage,
282 Span<const char>& encodedFrame);
284 [[nodiscard]]
bool hasPendingControlFrame()
const {
return pendingControlFrame.sizeInBytes() > 0; }
285 Result getPendingControlFrame(Span<const char>& frame)
const;
286 void clearPendingControlFrame();
288 [[nodiscard]]
bool hasCloseBeenSent()
const {
return closeSent; }
289 [[nodiscard]]
bool hasCloseBeenReceived()
const {
return closeReceived; }
293 Result onReaderPayload(Span<char> payload,
bool frameFinished);
294 Result handleControlFrame(Span<char> payload);
303 char controlPayload[125] = {0};
304 size_t controlPayloadSize = 0;
305 char automaticControlStorage[2 + 8 + 4 + 125] = {0};
306 Span<const char> pendingControlFrame;
307 uint8_t automaticMaskKey[4] = {0, 0, 0, 0};
309 bool automaticMaskKeySet =
false;
310 bool closeSent =
false;
311 bool closeReceived =
false;
318 Function<void()> onEnd;
319 Function<void(Result)> onError;
324 Result writeFrame(Span<const char> frame);
325 Result flushPendingControlFrame();
327 [[nodiscard]]
bool isAttached()
const {
return transport.isValid(); }
336 Result onEndpointDataFrame(
HttpWebSocketOpcode opcode, Span<char> payload,
bool frameFinished);
337 void fail(Result result);
342 bool dataListenerAdded =
false;
343 bool endListenerAdded =
false;
344 bool closeListenerAdded =
false;
359 Function<Result(
size_t, Span<const char>)> onBroadcastFrame;
361 Result init(Span<HttpWebSocketHubClient> clientStorage);
364 Result leave(
size_t clientIndex);
366 Result broadcastFrame(Span<const char> encodedFrame);
367 Result broadcastText(Span<const char> payload, Span<char> frameStorage);
369 [[nodiscard]]
size_t getNumClients()
const {
return numClients; }
370 [[nodiscard]]
size_t getCapacity()
const {
return clients.sizeInElements(); }
371 [[nodiscard]]
bool isClientActive(
size_t clientIndex)
const;
374 Span<HttpWebSocketHubClient> clients;
375 size_t numClients = 0;
HttpWebSocketEndpointRole
Identifies the local endpoint role to validate masking rules.
Definition HttpWebSocket.h:38
HttpWebSocketSha1Mode
Selects the SHA-1 implementation used by the RFC 6455 opening handshake.
Definition HttpWebSocket.h:45
HttpWebSocketOpcode
WebSocket frame opcode as defined by RFC 6455.
Definition HttpWebSocket.h:26
@ Platform
Use the platform provider, returning an error when no provider is available.
@ SelfContained
Use the allocation-free SHA-1 implementation embedded in Http.
Definition AsyncStreams.h:66
Holds a Span of AsyncBufferView (allocated by user) holding available memory for the streams.
Definition AsyncStreams.h:177
Asynchronous I/O (files, sockets, timers, processes, fs events, threads wake-up) (see Async) AsyncEve...
Definition Async.h:1506
Async source abstraction emitting data events in caller provided byte buffers.
Definition AsyncStreams.h:228
Async destination abstraction where bytes can be written to.
Definition AsyncStreams.h:364
Outgoing HTTP request sent by the client.
Definition HttpConnection.h:428
Incoming HTTP response received by the client.
Definition HttpConnection.h:259
Asynchronous HTTP/1.1 client using caller-provided fixed storage.
Definition HttpAsyncClient.h:85
Http connection abstraction holding both the incoming and outgoing messages in an HTTP transaction.
Definition HttpConnection.h:490
Method
Method of the current request / response.
Definition HttpParser.h:19
Incoming HTTP request received by the server.
Definition HttpConnection.h:233
Outgoing HTTP response sent by the server.
Definition HttpConnection.h:383
Normalized client-side WebSocket opening handshake response data.
Definition HttpWebSocket.h:94
Small client-side helper that upgrades an HttpAsyncClient connection to a WebSocket transport.
Definition HttpWebSocket.h:154
Optional stream pump that binds a WebSocket transport to an endpoint lifecycle.
Definition HttpWebSocket.h:316
Small frame-lifecycle helper for ping / pong, close, and explicit fixed-buffer send backpressure.
Definition HttpWebSocket.h:261
Incremental WebSocket frame reader operating on caller-owned mutable byte slices.
Definition HttpWebSocket.h:177
Incremental WebSocket frame writer operating on caller-owned header storage and payload buffers.
Definition HttpWebSocket.h:217
Outcome of validating a WebSocket opening handshake.
Definition HttpWebSocket.h:104
Dependency-free RFC 6455 opening handshake helpers.
Definition HttpWebSocket.h:120
Fixed-slot WebSocket hub client entry.
Definition HttpWebSocket.h:349
Optional caller-buffered message assembly helper for applications that want complete messages.
Definition HttpWebSocket.h:237
Normalized server-side WebSocket opening handshake data.
Definition HttpWebSocket.h:82
Small fixed-capacity broadcast helper for server-side WebSocket fan-out.
Definition HttpWebSocket.h:358
Minimal transport handoff shape for later HTTP upgrade integration.
Definition HttpWebSocket.h:67