ESP32 HTTPS Server

HTTPConnection.hpp
1 #ifndef SRC_HTTPCONNECTION_HPP_
2 #define SRC_HTTPCONNECTION_HPP_
3
4 #include <Arduino.h>
5
6 #include <string>
7 #include <mbedtls/base64.h>
8 #include <hwcrypto/sha.h>
9 #include <functional>
10
11 // Required for sockets
12 #include "lwip/netdb.h"
13 #undef read
14 #include "lwip/sockets.h"
15
16 #include "HTTPSServerConstants.hpp"
17 #include "ConnectionContext.hpp"
18
19 #include "HTTPHeaders.hpp"
20 #include "HTTPHeader.hpp"
21
22 #include "ResourceResolver.hpp"
23 #include "ResolvedResource.hpp"
24
25 #include "ResourceNode.hpp"
26 #include "HTTPRequest.hpp"
27 #include "HTTPResponse.hpp"
28
29 #include "WebsocketHandler.hpp"
30 #include "WebsocketNode.hpp"
31
32 namespace httpsserver {
33
37 class HTTPConnection : private ConnectionContext {
38 public:
39 HTTPConnection(ResourceResolver * resResolver);
40 virtual ~HTTPConnection();
41
42 virtual int initialize(int serverSocketID, HTTPHeaders *defaultHeaders);
43 virtual void closeConnection();
44 virtual bool isSecure();
45
46 void loop();
47 bool isClosed();
48 bool isError();
49
50 protected:
51 friend class HTTPRequest;
52 friend class HTTPResponse;
53 friend class WebsocketInputStreambuf;
54
55 virtual size_t writeBuffer(byte* buffer, size_t length);
56 virtual size_t readBytesToBuffer(byte* buffer, size_t length);
57 virtual bool canReadData();
58 virtual size_t pendingByteCount();
59
60 // Timestamp of the last transmission action
61 unsigned long _lastTransmissionTS;
62
63 // Timestamp of when the shutdown was started
64 unsigned long _shutdownTS;
65
66 // Internal state machine of the connection:
67 //
68 // O --- > STATE_UNDEFINED -- initialize() --> STATE_INITIAL -- get / http/1.1 --> STATE_REQUEST_FINISHED --.
69 // | | | |
70 // | | | | Host: ...\r\n
71 // STATE_ERROR <- on error-----------------------<---------------------------------------< | Foo: bar\r\n
72 // ^ | | | \r\n
73 // | shutdown .--> STATE_CLOSED | | | \r\n
74 // | fails | | | |
75 // | | close() | | |
76 // STATE_CLOSING <---- STATE_WEBSOCKET <-. | | |
77 // ^ | | | |
78 // `---------- close() ---------- STATE_BODY_FINISHED <-- Body received or GET -- STATE_HEADERS_FINISHED <-´
79 //
80 enum {
81 // The order is important, to be able to use state <= STATE_HEADERS_FINISHED etc.
82
83 // The connection has not been established yet
84 STATE_UNDEFINED,
85 // The connection has just been created
86 STATE_INITIAL,
87 // The request line has been parsed
88 STATE_REQUEST_FINISHED,
89 // The headers have been parsed
90 STATE_HEADERS_FINISHED,
91 // The body has been parsed/the complete request has been processed (GET has body of length 0)
92 STATE_BODY_FINISHED,
93 // The connection is in websocket mode
94 STATE_WEBSOCKET,
95 // The connection is about to close (and waiting for the client to send close notify)
96 STATE_CLOSING,
97 // The connection has been closed
98 STATE_CLOSED,
99 // An error has occured
100 STATE_ERROR
101 } _connectionState;
102
103 enum {
104 CSTATE_UNDEFINED,
105 CSTATE_ACTIVE,
106 CSTATE_CLOSED
107 } _clientState;
108
109 private:
110 void raiseError(uint16_t code, std::string reason);
111 void readLine(int lengthLimit);
112
113 bool isTimeoutExceeded();
114 void refreshTimeout();
115
116 int updateBuffer();
117 size_t pendingBufferSize();
118
119 void signalClientClose();
120 void signalRequestError();
121 size_t readBuffer(byte* buffer, size_t length);
122 size_t getCacheSize();
123 bool checkWebsocket();
124
125 // The receive buffer
126 char _receiveBuffer[HTTPS_CONNECTION_DATA_CHUNK_SIZE];
127
128 // First index on _receive_buffer that has not been processed yet (anything before may be discarded)
129 int _bufferProcessed;
130 // The index on the receive_buffer that is the first one which is empty at the end.
131 int _bufferUnusedIdx;
132
133 // Socket address, length etc for the connection
134 struct sockaddr _sockAddr;
135 socklen_t _addrLen;
136 int _socket;
137
138 // Resource resolver used to resolve resources
139 ResourceResolver * _resResolver;
140
141 // The parser line. The struct is used to read the next line up to the \r\n in readLine()
142 struct {
143 std::string text = "";
144 bool parsingFinished = false;
145 } _parserLine;
146
147 // HTTP properties: Method, Request, Headers
148 std::string _httpMethod;
149 std::string _httpResource;
150 HTTPHeaders * _httpHeaders;
151
152 // Default headers that are applied to every response
153 HTTPHeaders * _defaultHeaders;
154
155 // Should we use keep alive
156 bool _isKeepAlive;
157
158 //Websocket connection
159 WebsocketHandler * _wsHandler;
160
161 };
162
163 void handleWebsocketHandshake(HTTPRequest * req, HTTPResponse * res);
164
165 std::string websocketKeyResponseHash(std::string const &key);
166
167 void validationMiddleware(HTTPRequest * req, HTTPResponse * res, std::function<void()> next);
168
169 } /* namespace httpsserver */
170
171 #endif /* SRC_HTTPCONNECTION_HPP_ */
httpsserver::handleWebsocketHandshake
void handleWebsocketHandshake(HTTPRequest *req, HTTPResponse *res)
Definition: HTTPConnection.cpp:624
httpsserver::HTTPRequest
Represents the request stream for an HTTP request.
Definition: HTTPRequest.hpp:21
httpsserver::HTTPResponse
Represents the response stream of an HTTP request.
Definition: HTTPResponse.hpp:25
httpsserver::validationMiddleware
void validationMiddleware(HTTPRequest *req, HTTPResponse *res, std::function< void()> next)
Definition: HTTPConnection.cpp:598
httpsserver::HTTPConnection::isError
bool isError()
Definition: HTTPConnection.cpp:88
httpsserver::HTTPHeaders
Groups and manages a set of HTTPHeader instances.
Definition: HTTPHeaders.hpp:18
httpsserver::WebsocketHandler
Definition: WebsocketHandler.hpp:34
httpsserver::ResourceResolver
This class is used internally to resolve a string URL to the corresponding HTTPNode.
Definition: ResourceResolver.hpp:22
httpsserver::WebsocketInputStreambuf
Definition: WebsocketInputStreambuf.hpp:21
httpsserver::ConnectionContext
Internal class to handle the state of a connection.
Definition: ConnectionContext.hpp:17
httpsserver::HTTPConnection
Represents a single open connection for the plain HTTPServer, without TLS.
Definition: HTTPConnection.hpp:37
httpsserver::HTTPConnection::isClosed
bool isClosed()
Definition: HTTPConnection.cpp:81
httpsserver::websocketKeyResponseHash
std::string websocketKeyResponseHash(std::string const &key)
Definition: HTTPConnection.cpp:636
httpsserver::HTTPConnection::initialize
virtual int initialize(int serverSocketID, HTTPHeaders *defaultHeaders)
Definition: HTTPConnection.cpp:33
httpsserver
Definition: ConnectionContext.cpp:3