Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
HttpConnection.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "HttpParser.h"
5
6#include "../AsyncStreams/AsyncStreams.h"
7#include "../Foundation/StringSpan.h"
8
9namespace SC
10{
13
15struct SC_COMPILER_EXPORT HttpRequest
16{
18 const HttpParser& getParser() const { return parser; }
19
21 StringSpan getURL() const { return url; }
22
24 void reset();
25
26 private:
27 friend struct HttpConnectionsPool;
28 friend struct HttpResponse;
29 friend struct HttpAsyncServer;
30
35 [[nodiscard]] bool findParserToken(HttpParser::Token token, StringSpan& res) const;
36
39 Result writeHeaders(const uint32_t maxHeaderSize, Span<const char> readData, AsyncReadableStream& stream,
40 AsyncBufferView::ID bufferID);
41
43 [[nodiscard]] size_t getHeadersLength() const;
44
45 struct SC_COMPILER_EXPORT HttpHeaderOffset
46 {
47 HttpParser::Token token = HttpParser::Token::Method;
48
49 uint32_t start = 0;
50 uint32_t length = 0;
51 };
52 Span<char> readHeaders;
53 Span<char> availableHeader;
54
55 bool headersEndReceived = false;
56 bool parsedSuccessfully = true;
57
58 HttpParser parser;
59 StringSpan url;
60
61 static constexpr size_t MaxNumHeaders = 64;
62
63 HttpHeaderOffset headerOffsets[MaxNumHeaders];
64 size_t numHeaders = 0;
65};
66
68struct SC_COMPILER_EXPORT HttpResponse
69{
71 Result startResponse(int httpCode);
72
74 Result addHeader(StringSpan headerName, StringSpan headerValue);
75
78
80 void reset();
81
84
86 AsyncWritableStream& getWritableStream() { return *writableStream; }
87
90 void setKeepAlive(bool keepAlive);
91
94 [[nodiscard]] bool getKeepAlive() const { return keepAlive; }
95
97 [[nodiscard]] bool isKeepAliveExplicitlySet() const { return keepAliveExplicitlySet; }
98
99 private:
100 friend struct HttpConnectionsPool;
101 friend struct HttpAsyncServer;
102
104 void grabUnusedHeaderMemory(HttpRequest& request);
105
106 Span<char> responseHeaders;
107 size_t responseHeadersCapacity = 0;
108
109 bool headersSent = false;
110
111 bool keepAlive = true;
112 bool keepAliveExplicitlySet = false;
113 bool connectionHeaderAdded = false;
114
115 AsyncWritableStream* writableStream = nullptr;
116};
117
119struct SC_COMPILER_EXPORT HttpConnection
120{
122
123 struct SC_COMPILER_EXPORT ID
124 {
125 size_t getIndex() const { return index; }
126
127 private:
128 friend struct HttpConnectionsPool;
129 size_t index = 0;
130 };
131
133 void reset();
134
136 void setHeaderMemory(Span<char> memory) { headerMemory = memory; }
137
139 ID getConnectionID() const { return connectionID; }
140
141 HttpRequest request;
142 HttpResponse response;
143
144 AsyncBuffersPool buffersPool;
145 AsyncPipeline pipeline;
146
147 protected:
148 enum class State
149 {
150 Inactive,
151 Active
152 };
153 friend struct HttpConnectionsPool;
154 friend struct HttpAsyncServer;
155
156 State state = State::Inactive;
157 ID connectionID;
158
159 Span<char> headerMemory;
160};
161
163template <typename Type>
164struct SC_COMPILER_EXPORT SpanWithStride
165{
167 constexpr SpanWithStride() : data(nullptr), sizeElements(0), strideInBytes(0) {}
168
173 constexpr SpanWithStride(void* data, size_t sizeInElements, size_t strideInBytes)
174 : data(data), sizeElements(sizeInElements), strideInBytes(strideInBytes)
175 {}
176
177 template <typename U>
178 constexpr SpanWithStride(Span<U> span)
179 : data(span.data()), sizeElements(span.sizeInElements()), strideInBytes(sizeof(U))
180 {}
181
182 [[nodiscard]] constexpr size_t sizeInElements() const { return sizeElements; }
183 [[nodiscard]] constexpr bool empty() const { return sizeElements == 0; }
184
185 template <typename U>
186 SpanWithStride<U> castTo()
187 {
188 return {static_cast<U*>(reinterpret_cast<Type*>(data)), sizeElements, strideInBytes};
189 }
190
191 [[nodiscard]] Type& operator[](size_t idx)
192 {
193 return *reinterpret_cast<Type*>(reinterpret_cast<char*>(data) + idx * strideInBytes);
194 }
195
196 [[nodiscard]] const Type& operator[](size_t idx) const
197 {
198 return *reinterpret_cast<const Type*>(reinterpret_cast<const char*>(data) + idx * strideInBytes);
199 }
200
201 private:
202 void* data;
203 size_t sizeElements;
204 size_t strideInBytes;
205};
206
208struct SC_COMPILER_EXPORT HttpConnectionsPool
209{
212
215
217 [[nodiscard]] size_t getNumActiveConnections() const { return numConnections; }
218
220 [[nodiscard]] size_t getNumTotalConnections() const { return connections.sizeInElements(); }
221
223 [[nodiscard]] size_t getHighestActiveConnection() const { return highestActiveConnection; }
224
227 {
228 return connections[connectionID.index];
229 }
230
232 [[nodiscard]] HttpConnection& getConnectionAt(size_t idx) { return connections[idx]; }
233
235 [[nodiscard]] bool activateNew(HttpConnection::ID& connectionID);
236
238 [[nodiscard]] bool deactivate(HttpConnection::ID connectionID);
239
240 private:
242
243 size_t numConnections = 0;
244 size_t highestActiveConnection = 0;
245};
247
248} // namespace SC
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition PrimitiveTypes.h:38
Definition AsyncStreams.h:52
Holds a Span of AsyncBufferView (allocated by user) holding available memory for the streams.
Definition AsyncStreams.h:160
Pipes read data from SC::AsyncReadableStream, forwarding them to SC::AsyncWritableStream.
Definition AsyncStreams.h:457
Async source abstraction emitting data events in caller provided byte buffers.
Definition AsyncStreams.h:211
Async destination abstraction where bytes can be written to.
Definition AsyncStreams.h:311
Async Http Server.
Definition HttpAsyncServer.h:93
Definition HttpConnection.h:124
Http connection abstraction holding both the incoming and outgoing messages in an HTTP transaction.
Definition HttpConnection.h:120
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:139
void setHeaderMemory(Span< char > memory)
Sets memory for the header.
Definition HttpConnection.h:136
A pool of HttpConnection that can be active or inactive.
Definition HttpConnection.h:209
size_t getNumActiveConnections() const
Returns only the number of active connections.
Definition HttpConnection.h:217
size_t getHighestActiveConnection() const
Returns only the number of active connections.
Definition HttpConnection.h:223
HttpConnection & getConnectionAt(size_t idx)
Returns a connection in the [0, getNumTotalConnections] range.
Definition HttpConnection.h:232
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:226
size_t getNumTotalConnections() const
Returns the total number of connections (active + inactive)
Definition HttpConnection.h:220
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.
Incremental HTTP request or response parser.
Definition HttpParser.h:14
Token
One possible Token reported by the parser.
Definition HttpParser.h:40
Incoming message from the perspective of the participants of an HTTP transaction.
Definition HttpConnection.h:16
const HttpParser & getParser() const
Gets the associated HttpParser.
Definition HttpConnection.h:18
StringSpan getURL() const
Gets the request URL.
Definition HttpConnection.h:21
void reset()
Resets this object for it to be re-usable.
Outgoing message from the perspective of the participants of an HTTP transaction.
Definition HttpConnection.h:69
Result startResponse(int httpCode)
Starts the response with a http standard code (200 OK, 404 NOT FOUND etc.)
Result sendHeaders()
Start sending response headers, before sending any data.
void setKeepAlive(bool keepAlive)
Sets whether to keep the connection alive after this response.
Result addHeader(StringSpan headerName, StringSpan headerValue)
Writes an http header to this response.
Result end()
Finalizes the writable stream after sending all in progress writes.
void reset()
Resets this object for it to be re-usable.
bool isKeepAliveExplicitlySet() const
Returns true if setKeepAlive was explicitly called.
Definition HttpConnection.h:97
AsyncWritableStream & getWritableStream()
Obtain writable stream for sending content back to connected client.
Definition HttpConnection.h:86
bool getKeepAlive() const
Gets whether the connection should be kept alive after this response.
Definition HttpConnection.h:94
An ascii string used as boolean result. SC_TRY macro forwards errors to caller.
Definition Result.h:13
View over a contiguous sequence of items with a custom stride between elements.
Definition HttpConnection.h:165
constexpr SpanWithStride(void *data, size_t sizeInElements, size_t strideInBytes)
Builds a SpanWithStride from data, size, and stride.
Definition HttpConnection.h:173
constexpr SpanWithStride()
Builds an empty SpanWithStride.
Definition HttpConnection.h:167
View over a contiguous sequence of items (pointer + size in elements).
Definition Span.h:29
An read-only view over a string (to avoid including Strings library when parsing is not needed).
Definition StringSpan.h:37