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 void setTransportSetup(Function<Result(HttpAsyncServerTransportSetup&)>&& setup) { transportSetup = move(setup); }
106
109 void setTransportClose(Function<void(HttpConnection&)>&& close) { transportClose = move(close); }
110
112 void setTransportReuse(Function<Result(HttpConnection&)>&& reuse) { transportReuse = move(reuse); }
113
115 void setTransportShutdown(Function<Result(HttpConnection&, Function<void(Result)>)>&& shutdown)
116 {
117 transportShutdown = move(shutdown);
118 }
119
122 {
123 transportSetup = {};
124 transportReuse = {};
125 transportShutdown = {};
126 transportClose = {};
127 }
128
130 [[nodiscard]] bool isStarted() const { return state == State::Started; }
131
132 [[nodiscard]] const HttpConnectionsPool& getConnections() const { return connections; }
133
135 Function<void(HttpConnection&)> onRequest;
136
138 Function<void(Result)> onError;
139
143 void setDefaultKeepAlive(bool enabled) { defaultKeepAlive = enabled; }
144
146 [[nodiscard]] bool getDefaultKeepAlive() const { return defaultKeepAlive; }
147
150 void setMaxRequestsPerConnection(uint32_t maxRequests) { maxRequestsPerConnection = maxRequests; }
151
153 [[nodiscard]] uint32_t getMaxRequestsPerConnection() const { return maxRequestsPerConnection; }
154
155 private:
156 HttpConnectionsPool connections;
157
158 uint32_t maxHeaderSize = 8 * 1024;
159
160 Function<Result(HttpAsyncServerTransportSetup&)> transportSetup;
161 Function<Result(HttpConnection&)> transportReuse;
162 Function<Result(HttpConnection&, Function<void(Result)>)> transportShutdown;
163 Function<void(HttpConnection&)> transportClose;
164
165 enum class State
166 {
167 Stopped, // Server was not started at all, or it was stopped and wait(ed)ForStopToFinish
168 Started, // Server has been started (successfully)
169 Stopping, // Server has stop() called and needs waitForStopToFinish() call
170 };
171
172 State state = State::Stopped;
173
174 bool defaultKeepAlive = true;
175 uint32_t maxRequestsPerConnection = 0;
176
177 void onNewClient(AsyncSocketAccept::Result& result);
178 void closeAsync(HttpConnection& requestClient);
179 void shutdownTransport(HttpConnection& requestClient);
180 void tryDeactivateConnection(HttpConnection& requestClient);
181 void deactivateConnection(HttpConnection& requestClient);
182 Result beginHttpConnection(HttpConnection& client);
183 Result beginTransportConnection(HttpConnection& client);
184 void onStreamReceive(HttpConnection& client, AsyncBufferView::ID bufferID);
185 void onRequestBodyData(HttpConnection& client, AsyncBufferView::ID bufferID);
186 void onTransportSetupComplete(HttpConnection& client, Result result);
187
188 Result waitForStopToFinish();
189 Result initInternal(SpanWithStride<HttpConnection> connections);
190 Result resizeInternal(SpanWithStride<HttpConnection> connections);
191
192 AsyncEventLoop* eventLoop = nullptr;
193 SocketDescriptor serverSocket;
194 AsyncSocketAccept asyncServerAccept;
195 bool externalListener = false;
196
197 struct EventDataListener;
198 struct EventBodyDataListener;
199 struct EventEndListener;
200 struct EventCloseListener;
201};
202} // namespace SC
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
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
void setTransportShutdown(Function< Result(HttpConnection &, Function< void(Result)>)> &&shutdown)
Sets an optional asynchronous hook that drains a terminal response before closing its socket.
Definition HttpAsyncServer.h:115
void setTransportSetup(Function< Result(HttpAsyncServerTransportSetup &)> &&setup)
Sets an optional transport setup hook invoked after accepting TCP and before HTTP reads request bytes...
Definition HttpAsyncServer.h:105
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:153
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
bool getDefaultKeepAlive() const
Get the default keep-alive setting.
Definition HttpAsyncServer.h:146
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:143
Function< void(HttpConnection &)> onRequest
Called after enough data from a newly connected client has arrived, causing all headers to be parsed.
Definition HttpAsyncServer.h:135
Function< void(Result)> onError
Called on accept, parse, protocol, or streaming errors before the affected connection is closed.
Definition HttpAsyncServer.h:138
void setMaxRequestsPerConnection(uint32_t maxRequests)
Set maximum requests per keep-alive connection.
Definition HttpAsyncServer.h:150
bool isStarted() const
Returns true if the server has been started.
Definition HttpAsyncServer.h:130
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
void setTransportReuse(Function< Result(HttpConnection &)> &&reuse)
Sets an optional hook that reopens an alternate writable transport for the next keep-alive response.
Definition HttpAsyncServer.h:112
void clearTransportSetup()
Clears optional transport setup, reuse, shutdown, and teardown hooks.
Definition HttpAsyncServer.h:121
void setTransportClose(Function< void(HttpConnection &)> &&close)
Sets an optional transport teardown hook invoked before HTTP destroys the installed transport streams...
Definition HttpAsyncServer.h:109
Result acceptExternalConnection(HttpConnection &connection, AsyncReadableStream &readable, AsyncWritableStream &writable)
Activates a specific connection slot for externally accepted plaintext streams.
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:490
A pool of HttpConnection that can be active or inactive.
Definition HttpConnection.h:589
Adds compile-time configurable read and write queues to any class subclassing HttpConnectionBase.
Definition HttpConnection.h:657
IsBaseOf evaluates to true if the type Base is a base class of Derived, false otherwise.
Definition HttpAsyncServer.h:14