6#include "../Async/Async.h"
7#include "../AsyncStreams/AsyncRequestStreams.h"
8#include "../Foundation/StringSpan.h"
9#include "Internal/HttpFixedBufferWriter.h"
10#include "Internal/HttpParsedHeaders.h"
28 static constexpr size_t MaxParts = 8;
35 StringSpan contentType =
"application/octet-stream");
37 [[nodiscard]]
StringSpan getBoundary()
const {
return boundary; }
38 [[nodiscard]]
size_t getNumParts()
const {
return numParts; }
39 [[nodiscard]]
const Part& getPart(
size_t idx)
const {
return parts[idx]; }
40 [[nodiscard]]
size_t getContentLength()
const;
45 char boundaryStorage[71] = {0};
61 void setHeaderMemory(
Span<char> memory) { headerMemory = memory; }
63 [[nodiscard]]
Span<char> getHeaderMemory()
const {
return headerMemory; }
78 [[nodiscard]]
bool getKeepAlive()
const {
return parsedHeaders.parser.connectionKeepAlive; }
107 [[nodiscard]]
bool hasReceivedHeaders()
const {
return parsedHeaders.headersEndReceived; }
108 [[nodiscard]]
Span<char> getUnusedHeaderMemory()
const {
return parsedHeaders.availableHeader; }
110 void attachReadableStream(AsyncReadableStream& stream) { readableStream = &stream; }
111 void setBodyBytesRemaining(uint64_t value) { bodyBytesRemaining = value; }
123 bool stopAtHeadersEnd);
128 HttpParsedHeaders parsedHeaders;
161 friend struct HttpAsyncClient;
196 [[nodiscard]]
bool getKeepAlive()
const {
return forceDisableKeepAlive ? false : keepAlive; }
199 enum class KnownHeader :
uint8_t
209 void setHeaderMemory(Span<char> memory);
210 void setWritableStream(AsyncWritableStream& stream) { writableStream = &stream; }
212 [[nodiscard]]
bool hasHeader(KnownHeader header)
const;
213 [[nodiscard]]
bool hasSentHeaders()
const {
return headersSent; }
214 [[nodiscard]]
bool hasEnded()
const {
return endCalled; }
216 HttpFixedBufferWriter responseHeaders;
217 Span<char> headerMemory;
219 bool headersSent =
false;
220 bool endCalled =
false;
222 bool forceDisableKeepAlive =
false;
223 bool keepAlive =
true;
224 bool connectionHeaderAdded =
false;
225 bool hostHeaderAdded =
false;
226 bool userAgentHeaderAdded =
false;
227 bool contentLengthAdded =
false;
228 bool contentTypeAdded =
false;
229 bool transferEncodingAdded =
false;
272 [[nodiscard]]
StringSpan getURL()
const {
return url; }
273 [[nodiscard]] BodyType getBodyType()
const {
return bodyType; }
274 [[nodiscard]]
uint64_t getContentLength()
const {
return contentLength; }
277 friend struct HttpAsyncClient;
279 void setDefaultHost(
StringSpan value) { defaultHost = value; }
281 [[nodiscard]]
bool hasTransferEncodingHeader()
const {
return hasHeader(KnownHeader::TransferEncoding); }
284 [[nodiscard]]
const HttpMultipartWriter* getMultipartWriter()
const {
return multipartWriter; }
290 BodyType bodyType = BodyType::None;
305 struct SC_COMPILER_EXPORT
ID
307 size_t getIndex()
const {
return index; }
334 State state = State::Inactive;
339template <
typename Type>
349 constexpr SpanWithStride(
void* data,
size_t sizeInElements,
size_t strideInBytes)
350 : data(data), sizeElements(sizeInElements), strideInBytes(strideInBytes)
353 template <
typename U>
355 : data(span.data()), sizeElements(span.sizeInElements()), strideInBytes(sizeof(U))
358 [[nodiscard]]
constexpr size_t sizeInElements()
const {
return sizeElements; }
359 [[nodiscard]]
constexpr bool empty()
const {
return sizeElements == 0; }
361 template <
typename U>
362 SpanWithStride<U> castTo()
364 return {
static_cast<U*
>(
reinterpret_cast<Type*
>(data)), sizeElements, strideInBytes};
367 [[nodiscard]] Type& operator[](
size_t idx)
369 return *
reinterpret_cast<Type*
>(
reinterpret_cast<char*
>(data) + idx * strideInBytes);
372 [[nodiscard]]
const Type& operator[](
size_t idx)
const
374 return *
reinterpret_cast<const Type*
>(
reinterpret_cast<const char*
>(data) + idx * strideInBytes);
380 size_t strideInBytes;
388 size_t readQueueSize = 3;
389 size_t writeQueueSize = 3;
390 size_t buffersQueueSize = 6;
391 size_t headerBytesLength = 8 * 1024;
392 size_t streamBytesLength = 512 * 1024;
426 return connections[connectionID.index];
441 size_t numConnections = 0;
444 size_t highestActiveConnection = 0;
448template <
int ReadQueue,
int WriteQueue,
int HeaderBytes,
int StreamBytes,
int ExtraBuffers,
typename BaseClass>
456 char headerStorage[HeaderBytes];
457 char streamStorage[StreamBytes];
461 constexpr const size_t NumSlices = ReadQueue;
462 constexpr const size_t SliceLength = StreamBytes / NumSlices;
465 for (
size_t idx = 0; idx < NumSlices; ++idx)
469 buffers[idx] = slice;
472 this->setHeaderMemory(headerStorage);
473 this->buffersPool.setBuffers(buffers);
474 this->readableSocketStream.setReadQueue(readQueue);
475 this->writableSocketStream.setWriteQueue(writeQueue);
unsigned char uint8_t
Platform independent (1) byte unsigned int.
Definition PrimitiveTypes.h:36
unsigned long long uint64_t
Platform independent (8) bytes unsigned int.
Definition PrimitiveTypes.h:42
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition PrimitiveTypes.h:38
struct SC_COMPILER_EXPORT Function
Wraps function pointers, member functions and lambdas without ever allocating.
Definition Function.h:19
Definition AsyncStreams.h:52
A Span of bytes memory to be read or written by async streams.
Definition AsyncStreams.h:50
void setReusable(bool reusable)
Tags this AsyncBufferView as reusable after its refCount goes to zero.
Definition AsyncStreams.h:91
Holds a Span of AsyncBufferView (allocated by user) holding available memory for the streams.
Definition AsyncStreams.h:163
Pipes read data from SC::AsyncReadableStream, forwarding them to SC::AsyncWritableStream.
Definition AsyncStreams.h:524
Definition AsyncStreams.h:219
Async source abstraction emitting data events in caller provided byte buffers.
Definition AsyncStreams.h:214
Definition AsyncStreams.h:348
Async destination abstraction where bytes can be written to.
Definition AsyncStreams.h:341
Outgoing HTTP request sent by the client.
Definition HttpConnection.h:250
Incoming HTTP response received by the client.
Definition HttpConnection.h:159
Async Http Server.
Definition HttpAsyncServer.h:39
Shared async transport storage for HTTP client and server endpoints.
Definition HttpConnection.h:51
Definition HttpConnection.h:306
Http connection abstraction holding both the incoming and outgoing messages in an HTTP transaction.
Definition HttpConnection.h:302
void reset()
Prepare this client for re-use, marking it as Inactive.
ID getConnectionID() const
The ID used to find this client in HttpConnectionsPool.
Definition HttpConnection.h:318
Definition HttpConnection.h:387
Definition HttpConnection.h:396
A pool of HttpConnection that can be active or inactive.
Definition HttpConnection.h:385
size_t getNumActiveConnections() const
Returns only the number of active connections.
Definition HttpConnection.h:415
size_t getHighestActiveConnection() const
Returns only the number of active connections.
Definition HttpConnection.h:421
HttpConnection & getConnectionAt(size_t idx)
Returns a connection in the [0, getNumTotalConnections] range.
Definition HttpConnection.h:430
Result init(SpanWithStride< HttpConnection > connectionsStorage)
Initializes the server with memory buffers for connections and headers.
bool activateNew(HttpConnection::ID &connectionID)
Finds an available connection (if any), activates it and returns its ID to use with getConnection(id)
HttpConnection & getConnection(HttpConnection::ID connectionID)
Returns a connection by ID.
Definition HttpConnection.h:424
size_t getNumTotalConnections() const
Returns the total number of connections (active + inactive)
Definition HttpConnection.h:418
Result close()
Closes the server, removing references to the memory buffers passed during init.
bool deactivate(HttpConnection::ID connectionID)
De-activates a connection previously returned by activateNew.
Incoming message from the perspective of the participants of an HTTP transaction.
Definition HttpConnection.h:73
bool getKeepAlive() const
Gets whether the other party requested the connection to stay alive.
Definition HttpConnection.h:78
const AsyncReadableStream & getReadableStream() const
Obtains the readable stream for the message body.
AsyncReadableStream & getReadableStream()
Obtains the readable stream for the message body.
bool isMultipart() const
Checks if the request is a multipart/form-data request.
const HttpParser & getParser() const
Gets the associated HttpParser.
Definition HttpConnection.h:75
bool getHeader(StringSpan headerName, StringSpan &value) const
Gets the value of a specific header (case-insensitive name matching)
size_t getHeadersLength() const
Gets the length of the headers in bytes.
StringSpan getBoundary() const
Gets the multipart boundary string (if isMultipart() returns true)
bool findParserToken(HttpParser::Token token, StringSpan &res) const
Finds a specific HttpParser::Result in the list of parsed header.
Result consumeBodyBytes(size_t bytes)
Decrements the remaining body bytes after consuming data.
uint64_t getBodyBytesRemaining() const
Returns how many body bytes are still expected for this message.
Definition HttpConnection.h:81
Result writeHeaders(const uint32_t maxHeaderSize, Span< const char > readData, AsyncReadableStream &stream, AsyncBufferView::ID bufferID, const char *outOfSpaceError, const char *sizeExceededError, bool stopAtHeadersEnd)
Parses an incoming slice of data eventually copying it to the availableHeader.
Definition HttpConnection.h:20
Definition HttpConnection.h:18
Outgoing message from the perspective of the participants of an HTTP transaction.
Definition HttpConnection.h:171
bool getKeepAlive() const
Gets whether the connection should be kept alive after this response.
Definition HttpConnection.h:196
Result end()
Finalizes the writable stream after sending all in progress writes.
void reset()
Resets this object for it to be re-usable.
Result sendHeaders(Function< void(AsyncBufferView::ID)> callback={})
Start sending response headers, before sending any data.
Result addHeader(StringSpan headerName, StringSpan headerValue)
Writes an http header to this response.
void setKeepAlive(bool keepAlive)
Sets whether to keep the connection alive after this response.
AsyncWritableStream & getWritableStream()
Obtain writable stream for sending content back to connected client.
Definition HttpConnection.h:187
Incremental HTTP request or response parser.
Definition HttpParser.h:15
Token
One possible Token reported by the parser.
Definition HttpParser.h:41
Method
Method of the current request / response.
Definition HttpParser.h:18
Type
Type of the stream to be parsed (Request or Response)
Definition HttpParser.h:58
Incoming HTTP request received by the server.
Definition HttpConnection.h:136
StringSpan getURL() const
Gets the request URL.
Definition HttpConnection.h:138
void reset()
Resets this object for it to be re-usable.
Outgoing HTTP response sent by the server.
Definition HttpConnection.h:236
Result startResponse(int httpCode)
Starts the response with a http standard code (200 OK, 404 NOT FOUND etc.)
Adds compile-time configurable read and write queues to any class subclassing HttpConnectionBase.
Definition HttpConnection.h:450
An ascii string used as boolean result. SC_TRY macro forwards errors to caller.
Definition Result.h:13
Low-level OS socket handle.
Definition Socket.h:153
View over a contiguous sequence of items with a custom stride between elements.
Definition HttpConnection.h:341
constexpr SpanWithStride(void *data, size_t sizeInElements, size_t strideInBytes)
Builds a SpanWithStride from data, size, and stride.
Definition HttpConnection.h:349
constexpr SpanWithStride()
Builds an empty SpanWithStride.
Definition HttpConnection.h:343
View over a contiguous sequence of items (pointer + size in elements).
Definition Span.h:29
constexpr bool sliceStartLength(SizeType offsetInElements, SizeType lengthInElements, Span &destination) const
Creates another Span, starting at an offset in elements from current Span of specified length.
Definition Span.h:121
An read-only view over a string (to avoid including Strings library when parsing is not needed).
Definition StringSpan.h:37
Span< const char > toCharSpan() const
Obtain a const char Span from this StringView.
Definition StringSpan.h:82