Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
HttpServer.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "HttpParser.h"
5
6#include "../Async/Async.h"
7#include "../Foundation/Function.h"
8#include "../Foundation/StringSpan.h"
9#include "../Memory/Buffer.h"
10
11namespace SC
12{
13struct SC_COMPILER_EXPORT HttpServer;
14struct SC_COMPILER_EXPORT HttpServerClient;
15namespace detail
16{
17struct SC_COMPILER_EXPORT HttpHeaderOffset
18{
19 HttpParser::Token token = HttpParser::Token::Method;
20
21 uint32_t start = 0;
22 uint32_t length = 0;
23};
24} // namespace detail
25
28
30struct SC_COMPILER_EXPORT HttpRequest
31{
36 [[nodiscard]] bool find(HttpParser::Token token, StringSpan& res) const;
37
39 const HttpParser& getParser() const { return parser; }
40
42 StringSpan getURL() const { return url; }
43
44 void reset();
45
46 private:
47 friend struct HttpServer;
48 using HttpHeaderOffset = detail::HttpHeaderOffset; // TODO: hide class implementation
49
50 bool headersEndReceived = false;
51 bool parsedSuccessfully = true;
52
53 HttpParser parser;
54 StringSpan url;
55
56 Span<char> readHeaders;
57 Span<char> availableHeader;
58
59 static constexpr size_t MaxNumHeaders = 64;
60 HttpHeaderOffset headerOffsets[MaxNumHeaders];
61 size_t numHeaders = 0;
62};
63
65struct SC_COMPILER_EXPORT HttpResponse
66{
68 Result startResponse(int httpCode);
69
71 Result addHeader(StringSpan headerName, StringSpan headerValue);
72
75
79 Result end();
80
81 void reset()
82 {
83 responseEnded = false;
84 outputBuffer.clear();
85 }
86
87 private:
88 friend struct HttpServer;
89 [[nodiscard]] bool mustBeFlushed() const { return responseEnded or outputBuffer.size() > highwaterMark; }
90
91 HttpServer* server = nullptr;
92
93 size_t key;
94
95 Buffer outputBuffer;
96
97 bool responseEnded = false;
98 size_t highwaterMark = 1024;
99};
100
101struct SC_COMPILER_EXPORT HttpServerClient
102{
103 enum class State
104 {
105 Free,
106 Used
107 };
108 State state = State::Free;
109
110 HttpRequest request;
111 HttpResponse response;
112
113 void setFree()
114 {
115 request.reset();
116 response.reset();
117 state = State::Free;
118 }
119
120 SocketDescriptor socket;
121 char debugName[16] = {0};
122 AsyncSocketReceive asyncReceive;
123 AsyncSocketSend asyncSend;
124};
125#if !DOXYGEN
126SC_COMPILER_EXTERN template struct SC_COMPILER_EXPORT Function<void(HttpRequest&, HttpResponse&)>;
127SC_COMPILER_EXTERN template struct SC_COMPILER_EXPORT Span<HttpServerClient>;
128#endif
138struct SC_COMPILER_EXPORT HttpServer
139{
140 struct Memory
141 {
142 IGrowableBuffer& headersMemory;
143
145 };
152 Result start(AsyncEventLoop& loop, StringSpan address, uint16_t port, Memory& memory);
153
156
159
161 [[nodiscard]] bool isStarted() const { return started; }
162
168
169 private:
170 void onNewClient(AsyncSocketAccept::Result& result);
171 void onReceive(AsyncSocketReceive::Result& result);
172 void onAfterSend(AsyncSocketSend::Result& result);
173 void closeAsync(HttpServerClient& requestClient);
174
175 Result parse(HttpRequest& request, const uint32_t maxHeaderSize, Span<const char> readData);
176
177 IGrowableBuffer* headersMemory = nullptr;
178
180 size_t numClients = 0;
181
182 SocketDescriptor serverSocket;
183 AsyncSocketAccept asyncServerAccept;
184
185 uint32_t maxHeaderSize = 8 * 1024;
186
187 bool started = false;
188 bool stopping = false;
189
190 AsyncEventLoop* eventLoop = nullptr;
191};
193
194} // namespace SC
#define SC_COMPILER_EXTERN
Define compiler-specific export macros for DLL visibility.
Definition Compiler.h:74
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
Asynchronous I/O (files, sockets, timers, processes, fs events, threads wake-up) (see Async) AsyncEve...
Definition Async.h:1198
Helper holding CompletionData for a specific AsyncRequest-derived class.
Definition Async.h:288
Starts a socket accept operation, obtaining a new socket from a listening socket.
Definition Async.h:469
Definition Async.h:609
Starts a socket receive operation, receiving bytes from a remote endpoint.
Definition Async.h:599
Starts a socket send operation, sending bytes to a remote endpoint.
Definition Async.h:523
Wraps function pointers, member functions and lambdas without ever allocating.
Definition Function.h:19
Incremental HTTP request or response parser.
Definition HttpParser.h:17
Token
One possible Token reported by the parser.
Definition HttpParser.h:42
Http request received from a client.
Definition HttpServer.h:31
const HttpParser & getParser() const
Gets the associated HttpParser.
Definition HttpServer.h:39
StringSpan getURL() const
Gets the request URL.
Definition HttpServer.h:42
bool find(HttpParser::Token token, StringSpan &res) const
Finds a specific HttpParser::Result in the list of parsed header.
Http response that will be sent to a client.
Definition HttpServer.h:66
Result startResponse(int httpCode)
Starts the response with a http standard code (200 OK, 404 NOT FOUND etc.)
Result addHeader(StringSpan headerName, StringSpan headerValue)
Writes an http header to this response.
Result write(Span< const char > data)
Appends some data to the response.
Result end(Span< const char > data)
Finalizes response appending some data.
Definition HttpServer.h:102
Definition HttpServer.h:141
Async Http server.
Definition HttpServer.h:139
Result stopAsync()
Stops http server asynchronously pushing cancel and close requests for next SC::AsyncEventLoop::runOn...
Result start(AsyncEventLoop &loop, StringSpan address, uint16_t port, Memory &memory)
Starts the http server on the given AsyncEventLoop, address and port.
Result stopSync()
Stops http server synchronously waiting for SC::AsyncEventLoop::runNoWait to cancel or close all requ...
Function< void(HttpRequest &, HttpResponse &)> onRequest
Called after enough data from a newly connected client has arrived, causing all headers to be parsed.
Definition HttpServer.h:167
bool isStarted() const
Check if the server is started.
Definition HttpServer.h:161
An ascii string used as boolean result. SC_TRY macro forwards errors to caller.
Definition Result.h:12
Low-level OS socket handle.
Definition Socket.h:153
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