Sane C++ Libraries
C++ Platform Abstraction Libraries
HttpServer.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "HttpParser.h"
5
6#include "../Containers/ArenaMapKey.h"
7#include "../Foundation/Function.h"
8#include "../Strings/SmallString.h" // Contains Vector<char> export
9
10namespace SC
11{
12struct SC_COMPILER_EXPORT HttpServer;
13struct SC_COMPILER_EXPORT HttpRequest;
14struct SC_COMPILER_EXPORT HttpResponse;
15struct SC_COMPILER_EXPORT HttpRequest;
16
17struct AsyncEventLoop;
18struct SocketDescriptor;
19struct HttpServerClient;
20} // namespace SC
21
24
25namespace SC
26{
27namespace detail
28{
29struct SC_COMPILER_EXPORT HttpHeaderOffset
30{
32
33 uint32_t start = 0;
34 uint32_t length = 0;
35};
36} // namespace detail
37
38#if !DOXYGEN
39SC_COMPILER_EXTERN template struct SC_COMPILER_EXPORT Vector<detail::HttpHeaderOffset>;
40SC_COMPILER_EXTERN template struct SC_COMPILER_EXPORT ArenaMapKey<HttpServerClient>;
41#endif
42} // namespace SC
43
46{
51 [[nodiscard]] bool find(HttpParser::Result result, StringView& res) const;
52
54 const HttpParser& getParser() const { return parser; }
55
57 StringView getURL() const { return url; }
58
59 private:
60 friend struct HttpServer;
61 using HttpHeaderOffset = detail::HttpHeaderOffset; // TODO: hide class implementation
62
63 bool headersEndReceived = false;
64 bool parsedSuccessfully = true;
65
66 HttpParser parser;
67 StringView url;
68 Vector<char> headerBuffer;
69
70 Vector<HttpHeaderOffset> headerOffsets;
71};
72
75{
76 ArenaMapKey<HttpServerClient> getClientKey() const { return key; }
77
79 [[nodiscard]] Result startResponse(int httpCode);
80
82 [[nodiscard]] Result addHeader(StringView headerName, StringView headerValue);
83
85 [[nodiscard]] Result write(Span<const char> data);
86
89 [[nodiscard]] Result end(Span<const char> data);
90
91 HttpServer& getServer() { return *server; }
92
93 private:
94 friend struct HttpServer;
95 [[nodiscard]] bool mustBeFlushed() const { return responseEnded or outputBuffer.size() > highwaterMark; }
96
97 HttpServer* server = nullptr;
98
99 ArenaMapKey<HttpServerClient> key;
100
101 Vector<char> outputBuffer;
102
103 bool responseEnded = false;
104 size_t highwaterMark = 1024;
105};
106
107namespace SC
108{
109SC_COMPILER_EXTERN template struct SC_COMPILER_EXPORT Function<void(HttpRequest&, HttpResponse&)>;
110}
111
122{
123 HttpServer();
124 ~HttpServer();
125 HttpServer(const HttpServer&) = delete;
126 HttpServer& operator=(const HttpServer&) = delete;
127 HttpServer(HttpServer&&) = delete;
128 HttpServer& operator=(HttpServer&&) = delete;
129
136 [[nodiscard]] Result start(AsyncEventLoop& loop, uint32_t maxConcurrentRequests, StringView address, uint16_t port);
137
139 [[nodiscard]] Result stopAsync();
140
142 [[nodiscard]] Result stopSync();
143
145 [[nodiscard]] bool isStarted() const;
146
152
156
160
164
166 [[nodiscard]] uint32_t getMaxConcurrentRequests() const;
167
168 private:
169 struct Internal;
170#if SC_PLATFORM_WINDOWS
171 uint64_t internalRaw[72];
172#else
173 uint64_t internalRaw[32];
174#endif
175 Internal& internal;
176};
177
#define SC_COMPILER_EXPORT
Macro for symbol visibility in non-MSVC compilers.
Definition: Compiler.h:78
#define SC_COMPILER_EXTERN
Define compiler-specific export macros for DLL visibility.
Definition: Compiler.h:74
unsigned long long uint64_t
Platform independent (8) bytes unsigned int.
Definition: PrimitiveTypes.h:42
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition: PrimitiveTypes.h:38
unsigned short uint16_t
Platform independent (2) bytes unsigned int.
Definition: PrimitiveTypes.h:37
A sparse vector keeping objects at a stable memory location.
Definition: ArenaMapKey.h:22
Asynchronous I/O (files, sockets, timers, processes, fs events, threads wake-up) (see Async) AsyncEve...
Definition: Async.h:933
Wraps function pointers, member functions and lambdas without ever allocating.
Definition: Function.h:50
Incremental HTTP request or response parser.
Definition: HttpParser.h:17
Result
One possible Result reported by the parser.
Definition: HttpParser.h:42
@ Method
Http method has been found.
Http request received from a client.
Definition: HttpServer.h:46
const HttpParser & getParser() const
Gets the associated HttpParser.
Definition: HttpServer.h:54
bool find(HttpParser::Result result, StringView &res) const
Finds a specific HttpParser::Result in the list of parsed header.
StringView getURL() const
Gets the request URL.
Definition: HttpServer.h:57
Http response that will be sent to a client.
Definition: HttpServer.h:75
Result startResponse(int httpCode)
Starts the response with a http standard code (200 OK, 404 NOT FOUND etc.)
Result addHeader(StringView headerName, StringView 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.
Async Http server.
Definition: HttpServer.h:122
Result stopAsync()
Stops http server asyncronously pushing cancel and close requests for next SC::AsyncEventLoop::runOnc...
HttpRequest * getRequest(ArenaMapKey< HttpServerClient > key) const
Obtain client request (or a nullptr if it doesn't exists) with the key returned by SC::HttpResponse::...
uint32_t getMaxConcurrentRequests() const
Return maximum number of concurrent requests, corresponding to size of clients arena.
SocketDescriptor * getSocket(ArenaMapKey< HttpServerClient > key) const
Obtain client socket (or a nullptr if it doesn't exists) with the key returned by SC::HttpResponse::g...
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:151
bool isStarted() const
Check if the server is started.
Result start(AsyncEventLoop &loop, uint32_t maxConcurrentRequests, StringView address, uint16_t port)
Starts the http server on the given AsyncEventLoop, address and port.
HttpResponse * getResponse(ArenaMapKey< HttpServerClient > key) const
Obtain client response (or a nullptr if it doesn't exists) with the key returned by SC::HttpResponse:...
An ascii string used as boolean result. SC_TRY macro forwards errors to caller.
Definition: Result.h:11
Low-level OS socket handle.
Definition: SocketDescriptor.h:154
View over a contiguous sequence of items (pointer + size in elements).
Definition: Span.h:20
Non-owning view over a range of characters with UTF Encoding.
Definition: StringView.h:47
A contiguous sequence of heap allocated elements.
Definition: Vector.h:51