Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
HttpAsyncServer.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../AsyncStreams/AsyncRequestStreams.h"
5#include "HttpConnection.h"
6
7namespace SC
8{
9namespace TypeTraits
10{
12template <typename Base, typename Derived>
14{
15 static constexpr bool value = __is_base_of(Base, Derived);
16};
17
18} // namespace TypeTraits
19
21struct SC_COMPILER_EXPORT HttpAsyncConnectionBase : public HttpConnection
22{
24 {
25 size_t readQueueSize = 3;
26 size_t writeQueueSize = 3;
27 size_t buffersQueueSize = 6;
28 size_t headerBytesLength = 8 * 1024;
29 size_t streamBytesLength = 512 * 1024;
30 };
31
32 struct SC_COMPILER_EXPORT Memory
33 {
36 Span<AsyncBufferView> allBuffers;
37 Span<char> allHeaders;
38 Span<char> allStreams;
39
42 };
43 ReadableSocketStream readableSocketStream;
44 WritableSocketStream writableSocketStream;
45 SocketDescriptor socket;
46 uint32_t requestCount = 0;
47};
48
50template <int ReadQueue, int WriteQueue, int HeaderBytes, int StreamBytes>
51struct SC_COMPILER_EXPORT HttpAsyncConnection : public HttpAsyncConnectionBase
52{
53 AsyncReadableStream::Request readQueue[ReadQueue];
54 AsyncWritableStream::Request writeQueue[WriteQueue];
55 AsyncBufferView buffers[ReadQueue + WriteQueue];
56
57 char headerStorage[HeaderBytes];
58 char streamStorage[StreamBytes];
59
60 constexpr HttpAsyncConnection()
61 {
62 constexpr const size_t NumSlices = ReadQueue;
63 constexpr const size_t SliceLength = StreamBytes / NumSlices;
64
65 Span<char> memory = streamStorage;
66 for (size_t idx = 0; idx < NumSlices; ++idx)
67 {
68 Span<char> slice;
69 (void)memory.sliceStartLength(idx * SliceLength, SliceLength, slice);
70 buffers[idx] = slice;
71 buffers[idx].setReusable(true);
72 }
73 HttpConnection::setHeaderMemory(headerStorage);
74 HttpConnection::buffersPool.setBuffers(buffers);
75 readableSocketStream.setReadQueue(readQueue);
76 writableSocketStream.setWriteQueue(writeQueue);
77 }
78};
79
92struct SC_COMPILER_EXPORT HttpAsyncServer
93{
95 template <typename T,
98 {
99 return initInternal({clients.data(), clients.sizeInElements(), sizeof(T)});
100 }
101
102 template <typename T,
104 Result resize(Span<T> clients)
105 {
106 return resizeInternal({clients.data(), clients.sizeInElements(), sizeof(T)});
107 }
108
112
119
123
125 [[nodiscard]] bool isStarted() const { return state == State::Started; }
126
127 [[nodiscard]] const HttpConnectionsPool& getConnections() const { return connections; }
128
131
135 void setDefaultKeepAlive(bool enabled) { defaultKeepAlive = enabled; }
136
138 [[nodiscard]] bool getDefaultKeepAlive() const { return defaultKeepAlive; }
139
142 void setMaxRequestsPerConnection(uint32_t maxRequests) { maxRequestsPerConnection = maxRequests; }
143
145 [[nodiscard]] uint32_t getMaxRequestsPerConnection() const { return maxRequestsPerConnection; }
146
147 private:
148 HttpConnectionsPool connections;
149
150 uint32_t maxHeaderSize = 8 * 1024;
151
152 enum class State
153 {
154 Stopped, // Server was not started at all, or it was stopped and wait(ed)ForStopToFinish
155 Started, // Server has been started (successfully)
156 Stopping, // Server has stop() called and needs waitForStopToFinish() call
157 };
158
159 State state = State::Stopped;
160
161 bool defaultKeepAlive = true;
162 uint32_t maxRequestsPerConnection = 0;
163
164 void onNewClient(AsyncSocketAccept::Result& result);
165 void closeAsync(HttpAsyncConnectionBase& requestClient);
166 void deactivateConnection(HttpAsyncConnectionBase& requestClient);
167 void onStreamReceive(HttpAsyncConnectionBase& client, AsyncBufferView::ID bufferID);
168
169 Result waitForStopToFinish();
170 Result initInternal(SpanWithStride<HttpAsyncConnectionBase> connections);
171 Result resizeInternal(SpanWithStride<HttpAsyncConnectionBase> connections);
172
173 void onAsyncRequestStopped(AsyncResult& result);
174
175 Function<void(AsyncResult&)> onAsyncRequestStoppedFunc;
176
177 AsyncEventLoop* eventLoop = nullptr;
178 SocketDescriptor serverSocket;
179 AsyncSocketAccept asyncServerAccept;
180
181 struct EventDataListener;
182 struct EventEndListener;
183};
184} // namespace SC
unsigned short uint16_t
Platform independent (2) bytes unsigned int.
Definition PrimitiveTypes.h:37
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
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:88
Asynchronous I/O (files, sockets, timers, processes, fs events, threads wake-up) (see Async) AsyncEve...
Definition Async.h:1196
Definition AsyncStreams.h:213
Definition AsyncStreams.h:316
Definition HttpAsyncServer.h:24
Definition HttpAsyncServer.h:33
Contains fields used by HttpAsyncServer for each connection.
Definition HttpAsyncServer.h:22
Adds compile-time configurable read and write queues to HttpAsyncConnectionBase.
Definition HttpAsyncServer.h:52
Async Http Server.
Definition HttpAsyncServer.h:93
Result start(AsyncEventLoop &loop, StringSpan address, uint16_t port)
Starts the http server on the given AsyncEventLoop, address and port.
uint32_t getMaxRequestsPerConnection() const
Get the maximum requests per connection.
Definition HttpAsyncServer.h:145
Result stop()
Stops http server asynchronously pushing cancel and close requests to the event loop.
Result init(Span< T > clients)
Initializes the async server with all needed memory buffers.
Definition HttpAsyncServer.h:97
bool getDefaultKeepAlive() const
Get the default keep-alive setting.
Definition HttpAsyncServer.h:138
void setDefaultKeepAlive(bool enabled)
Set default keep-alive behavior for all connections.
Definition HttpAsyncServer.h:135
Function< void(HttpConnection &)> onRequest
Called after enough data from a newly connected client has arrived, causing all headers to be parsed.
Definition HttpAsyncServer.h:130
void setMaxRequestsPerConnection(uint32_t maxRequests)
Set maximum requests per keep-alive connection.
Definition HttpAsyncServer.h:142
bool isStarted() const
Returns true if the server has been started.
Definition HttpAsyncServer.h:125
Result close()
Closes the server, removing references to the memory buffers passed during init.
Http connection abstraction holding both the incoming and outgoing messages in an HTTP transaction.
Definition HttpConnection.h:120
A pool of HttpConnection that can be active or inactive.
Definition HttpConnection.h:209
Uses an SC::AsyncFileWrite to stream data from a socket.
Definition AsyncRequestStreams.h:74
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:165
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
EnableIf conditionally defines a type if a boolean template parameter is true.
Definition TypeTraits.h:25
IsBaseOf evaluates to true if the type Base is a base class of Derived, false otherwise.
Definition HttpAsyncServer.h:14
Uses an SC::AsyncFileWrite to stream data to a socket.
Definition AsyncRequestStreams.h:80