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 "HttpConnection.h"
5#include "HttpExport.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
21template <int ReadQueue, int WriteQueue, int HeaderBytes, int StreamBytes>
22struct SC_HTTP_EXPORT HttpAsyncConnection
23 : public HttpStaticConnection<ReadQueue, WriteQueue, HeaderBytes, StreamBytes, 8, HttpConnection>
24{
25};
26
32struct SC_HTTP_EXPORT HttpAsyncServerTransportSetup
33{
34 HttpConnection* connection = nullptr;
35 AsyncEventLoop* eventLoop = nullptr;
36
37 Function<void(Result)> complete;
38 Function<void(Result)> fail;
39};
40
53struct SC_HTTP_EXPORT HttpAsyncServer
54{
56 template <typename T,
57 typename = typename TypeTraits::EnableIf<TypeTraits::IsBaseOf<HttpConnection, T>::value>::type>
58 Result init(Span<T> clients)
59 {
60 return initInternal({clients.data(), clients.sizeInElements(), sizeof(T)});
61 }
62
63 template <typename T,
64 typename = typename TypeTraits::EnableIf<TypeTraits::IsBaseOf<HttpConnection, T>::value>::type>
65 Result resize(Span<T> clients)
66 {
67 return resizeInternal({clients.data(), clients.sizeInElements(), sizeof(T)});
68 }
69
72 Result close();
73
79 Result start(AsyncEventLoop& loop, StringSpan address, uint16_t port);
80
85
91 AsyncWritableStream& writable);
92
95 Result stop();
96
99 void setMaxHeaderSize(uint32_t bytes) { maxHeaderSize = bytes; }
100
102 [[nodiscard]] uint32_t getMaxHeaderSize() const { return maxHeaderSize; }
103
105 Result setTransportSetup(Function<Result(HttpAsyncServerTransportSetup&)>&& setup, const void* owner = nullptr)
106 {
107 SC_TRY(checkTransportMutation(owner));
108 transportSetup = move(setup);
109 return Result(true);
110 }
111
114 Result setTransportClose(Function<void(HttpConnection&)>&& close, const void* owner = nullptr)
115 {
116 SC_TRY(checkTransportMutation(owner));
117 transportClose = move(close);
118 return Result(true);
119 }
120
122 Result setTransportReuse(Function<Result(HttpConnection&)>&& reuse, const void* owner = nullptr)
123 {
124 SC_TRY(checkTransportMutation(owner));
125 transportReuse = move(reuse);
126 return Result(true);
127 }
128
130 Result setTransportShutdown(Function<Result(HttpConnection&, Function<void(Result)>)>&& shutdown,
131 const void* owner = nullptr)
132 {
133 SC_TRY(checkTransportMutation(owner));
134 transportShutdown = move(shutdown);
135 return Result(true);
136 }
137
139 Result clearTransportSetup(const void* owner = nullptr);
140
144 Result claimTransport(const void* owner);
145
148 Result releaseTransport(const void* owner);
149
151 [[nodiscard]] bool isStarted() const { return state == State::Started; }
152
153 [[nodiscard]] const HttpConnectionsPool& getConnections() const { return connections; }
154
156 Function<void(HttpConnection&)> onRequest;
157
159 Function<void(Result)> onError;
160
164 void setDefaultKeepAlive(bool enabled) { defaultKeepAlive = enabled; }
165
167 [[nodiscard]] bool getDefaultKeepAlive() const { return defaultKeepAlive; }
168
171 void setMaxRequestsPerConnection(uint32_t maxRequests) { maxRequestsPerConnection = maxRequests; }
172
174 [[nodiscard]] uint32_t getMaxRequestsPerConnection() const { return maxRequestsPerConnection; }
175
176 private:
177 Result checkTransportMutation(const void* owner) const;
178 Result checkTransportQuiescence() const;
179
180 HttpConnectionsPool connections;
181
182 uint32_t maxHeaderSize = 8 * 1024;
183
184 Function<Result(HttpAsyncServerTransportSetup&)> transportSetup;
185 Function<Result(HttpConnection&)> transportReuse;
186 Function<Result(HttpConnection&, Function<void(Result)>)> transportShutdown;
187 Function<void(HttpConnection&)> transportClose;
188
189 const void* transportOwner = nullptr;
190
191 uint32_t transportCallbackDepth = 0;
192
193 enum class State
194 {
195 Stopped, // Server was not started at all, or it was stopped and wait(ed)ForStopToFinish
196 Started, // Server has been started (successfully)
197 Stopping, // Server has stop() called and needs waitForStopToFinish() call
198 };
199
200 State state = State::Stopped;
201
202 bool defaultKeepAlive = true;
203 uint32_t maxRequestsPerConnection = 0;
204
205 void onNewClient(AsyncSocketAccept::Result& result);
206 void closeAsync(HttpConnection& requestClient);
207 void shutdownTransport(HttpConnection& requestClient);
208 void tryDeactivateConnection(HttpConnection& requestClient);
209 void deactivateConnection(HttpConnection& requestClient);
210 Result beginHttpConnection(HttpConnection& client);
211 Result beginTransportConnection(HttpConnection& client);
212 void onStreamReceive(HttpConnection& client, AsyncBufferView::ID bufferID);
213 void onRequestBodyData(HttpConnection& client, AsyncBufferView::ID bufferID);
214 void onTransportSetupComplete(HttpConnection& client, Result result);
215
216 Result waitForStopToFinish();
217 Result initInternal(SpanWithStride<HttpConnection> connections);
218 Result resizeInternal(SpanWithStride<HttpConnection> connections);
219
220 AsyncEventLoop* eventLoop = nullptr;
221 SocketDescriptor serverSocket;
222 AsyncSocketAccept asyncServerAccept;
223 bool externalListener = false;
224
225 struct EventDataListener;
226 struct EventBodyDataListener;
227 struct EventEndListener;
228 struct EventCloseListener;
229};
230} // namespace SC
Asynchronous I/O (files, sockets, timers, processes, fs events, threads wake-up) (see Async) AsyncEve...
Definition Async.h:1517
Async source abstraction emitting data events in caller provided byte buffers.
Definition AsyncStreams.h:229
Async destination abstraction where bytes can be written to.
Definition AsyncStreams.h:365
Adds compile-time configurable read and write queues to HttpConnection.
Definition HttpAsyncServer.h:24
Mutable transport setup view used by HttpAsyncServer after accepting a TCP socket.
Definition HttpAsyncServer.h:33
Async Http Server.
Definition HttpAsyncServer.h:54
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:174
Result setTransportClose(Function< void(HttpConnection &)> &&close, const void *owner=nullptr)
Sets an optional transport teardown hook invoked before HTTP destroys the installed transport streams...
Definition HttpAsyncServer.h:114
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:58
Result releaseTransport(const void *owner)
Clears hooks and releases only the matching owner's claim after complete server teardown.
Result clearTransportSetup(const void *owner=nullptr)
Clears optional transport setup, reuse, shutdown, and teardown hooks.
bool getDefaultKeepAlive() const
Get the default keep-alive setting.
Definition HttpAsyncServer.h:167
Result startExternal(AsyncEventLoop &loop)
Starts the HTTP state machine without creating a native listener.
void setDefaultKeepAlive(bool enabled)
Set default keep-alive behavior for all connections.
Definition HttpAsyncServer.h:164
Function< void(HttpConnection &)> onRequest
Called after enough data from a newly connected client has arrived, causing all headers to be parsed.
Definition HttpAsyncServer.h:156
Function< void(Result)> onError
Called on accept, parse, protocol, or streaming errors before the affected connection is closed.
Definition HttpAsyncServer.h:159
void setMaxRequestsPerConnection(uint32_t maxRequests)
Set maximum requests per keep-alive connection.
Definition HttpAsyncServer.h:171
bool isStarted() const
Returns true if the server has been started.
Definition HttpAsyncServer.h:151
void setMaxHeaderSize(uint32_t bytes)
Sets the maximum accepted request-header size in bytes.
Definition HttpAsyncServer.h:99
uint32_t getMaxHeaderSize() const
Gets the maximum accepted request-header size in bytes.
Definition HttpAsyncServer.h:102
Result setTransportShutdown(Function< Result(HttpConnection &, Function< void(Result)>)> &&shutdown, const void *owner=nullptr)
Sets an optional asynchronous hook that drains a terminal response before closing its socket.
Definition HttpAsyncServer.h:130
Result setTransportSetup(Function< Result(HttpAsyncServerTransportSetup &)> &&setup, const void *owner=nullptr)
Sets an optional transport setup hook invoked after accepting TCP and before HTTP reads request bytes...
Definition HttpAsyncServer.h:105
Result acceptExternalConnection(HttpConnection &connection, AsyncReadableStream &readable, AsyncWritableStream &writable)
Activates a specific connection slot for externally accepted plaintext streams.
Result setTransportReuse(Function< Result(HttpConnection &)> &&reuse, const void *owner=nullptr)
Sets an optional hook that reopens an alternate writable transport for the next keep-alive response.
Definition HttpAsyncServer.h:122
Result claimTransport(const void *owner)
Claims the transport hook group with a non-null address-stable owner token.
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:489
A pool of HttpConnection that can be active or inactive.
Definition HttpConnection.h:588
Adds compile-time configurable read and write queues to any class subclassing HttpConnectionBase.
Definition HttpConnection.h:656
IsBaseOf evaluates to true if the type Base is a base class of Derived, false otherwise.
Definition HttpAsyncServer.h:14