Skip to content

Commit 4026366

Browse files
authored
Add files via upload
1 parent b4d0efc commit 4026366

File tree

8 files changed

+297
-124
lines changed

8 files changed

+297
-124
lines changed

https/ConnectionContext.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ class ConnectionContext {
2121
ConnectionContext();
2222
virtual ~ConnectionContext();
2323

24-
virtual SSL* ssl() = 0;
24+
virtual SSL* ssl() = 0; // needed for HTTPS
25+
virtual int __socket() = 0; // needed for HTTP
26+
2527
virtual void signalRequestError() = 0;
2628
virtual void signalClientClose() = 0;
2729
virtual size_t getCacheSize() = 0;
@@ -32,4 +34,4 @@ class ConnectionContext {
3234

3335
} /* namespace httpsserver */
3436

35-
#endif /* HTTPS_CONNECTIONCONTEXT_HPP_ */
37+
#endif /* HTTPS_CONNECTIONCONTEXT_HPP_ */

https/HTTPRequest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,4 @@ void HTTPRequest::discardRequestBody() {
8787
}
8888
}
8989

90-
} /* namespace httpsserver */
90+
} /* namespace httpsserver */

https/HTTPResponse.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
* Author: frank
66
*/
77

8+
// needed for HTTP sockets
9+
#include <Arduino.h>
10+
#include "lwip/sockets.h"
11+
812
#include "HTTPResponse.hpp"
913

1014
namespace httpsserver {
@@ -145,8 +149,14 @@ size_t HTTPResponse::writeBytesInternal(const void * data, int length, bool skip
145149
drainBuffer(true);
146150
}
147151
}
148-
HTTPS_DLOG("[ ] Writing response data to ssl socket");
149-
SSL_write(_con->ssl(), data, length);
152+
153+
if (_con->ssl()) { // HTTPS
154+
HTTPS_DLOG("[ ] Writing response data to ssl socket");
155+
SSL_write(_con->ssl(), data, length);
156+
} else { // HTTP
157+
HTTPS_DLOG("[ ] Writing response data to socket");
158+
send(_con->__socket(), data, length, 0);
159+
}
150160
return length;
151161
} else {
152162
return 0;
@@ -165,11 +175,17 @@ void HTTPResponse::drainBuffer(bool onOverflow) {
165175
HTTPS_DLOG("[ ] Draining response buffer")
166176
// Check for 0 as it may be an overflow reaction without any data that has been written earlier
167177
if(_responseCachePointer > 0) {
168-
SSL_write(_con->ssl(), _responseCache, _responseCachePointer);
178+
179+
if (_con->ssl()) { // HTTPS
180+
SSL_write(_con->ssl(), _responseCache, _responseCachePointer);
181+
} else { // HTTP
182+
send(_con->__socket(), _responseCache, _responseCachePointer, 0);
183+
}
184+
169185
}
170186
delete[] _responseCache;
171187
_responseCache = NULL;
172188
}
173189
}
174190

175-
} /* namespace httpsserver */
191+
} /* namespace httpsserver */

https/HTTPResponse.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,15 @@ class HTTPResponse : public Print {
4646

4747
bool isResponseBuffered();
4848
void finalize();
49+
50+
ConnectionContext * _con;
51+
4952
private:
5053
void printHeader();
5154
void printInternal(const std::string &str, bool skipBuffer = false);
5255
size_t writeBytesInternal(const void * data, int length, bool skipBuffer = false);
5356
void drainBuffer(bool onOverflow = false);
5457

55-
ConnectionContext * _con;
56-
5758
uint16_t _statusCode;
5859
std::string _statusText;
5960
HTTPHeaders _headers;
@@ -68,4 +69,4 @@ class HTTPResponse : public Print {
6869

6970
} /* namespace httpsserver */
7071

71-
#endif /* HTTPS_HTTPRESPONSE_HPP_ */
72+
#endif /* HTTPS_HTTPRESPONSE_HPP_ */

https/HTTPSConnection.cpp

Lines changed: 147 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ HTTPSConnection::~HTTPSConnection() {
3838
*
3939
* The call WILL BLOCK if accept(serverSocketID) blocks. So use select() to check for that in advance.
4040
*/
41-
int HTTPSConnection::initialize(int serverSocketID, SSL_CTX * sslCtx, HTTPHeaders *defaultHeaders) {
41+
int HTTPSConnection::initialize(int serverSocketID, SSL_CTX * sslCtx, HTTPHeaders *defaultHeaders, bool isSSLSocket) {
4242
if (_connectionState == STATE_UNDEFINED) {
4343
_defaultHeaders = defaultHeaders;
4444
_socket = accept(serverSocketID, (struct sockaddr * )&_sockAddr, &_addrLen);
@@ -47,32 +47,45 @@ int HTTPSConnection::initialize(int serverSocketID, SSL_CTX * sslCtx, HTTPHeader
4747
if (_socket >= 0) {
4848
HTTPS_DLOGHEX("[-->] New connection. Socket fid is: ", _socket);
4949

50-
_ssl = SSL_new(sslCtx);
51-
52-
if (_ssl) {
53-
// Bind SSL to the socket
54-
int success = SSL_set_fd(_ssl, _socket);
55-
if (success) {
56-
57-
// Perform the handshake
58-
success = SSL_accept(_ssl);
59-
if (success) {
60-
_connectionState = STATE_INITIAL;
61-
_httpHeaders = new HTTPHeaders();
62-
refreshTimeout();
63-
return _socket;
64-
} else {
65-
HTTPS_DLOG("[ERR] SSL_accept failed. Aborting handshake.");
66-
}
67-
} else {
68-
HTTPS_DLOG("[ERR] SSL_set_fd failed. Aborting handshake.");
69-
}
70-
} else {
71-
HTTPS_DLOG("[ERR] SSL_new failed. Aborting handshake.");
72-
}
50+
if (isSSLSocket) { // HTTPS
51+
52+
_ssl = SSL_new(sslCtx);
53+
54+
if (_ssl) {
55+
// Bind SSL to the socket
56+
int success = SSL_set_fd(_ssl, _socket);
57+
if (success) {
58+
59+
// Perform the handshake
60+
success = SSL_accept(_ssl);
61+
if (success) {
62+
_connectionState = STATE_INITIAL;
63+
_httpHeaders = new HTTPHeaders();
64+
refreshTimeout();
65+
return _socket;
66+
} else {
67+
HTTPS_DLOG("[ERR] SSL_accept failed. Aborting handshake.");
68+
}
69+
} else {
70+
HTTPS_DLOG("[ERR] SSL_set_fd failed. Aborting handshake.");
71+
}
72+
} else {
73+
HTTPS_DLOG("[ERR] SSL_new failed. Aborting handshake.");
74+
}
75+
76+
} else { // HTTP
77+
78+
_connectionState = STATE_INITIAL;
79+
_httpHeaders = new HTTPHeaders();
80+
refreshTimeout();
81+
return _socket;
82+
83+
}
84+
7385
} else {
7486
HTTPS_DLOG("[ERR] Could not accept() new connection");
7587
}
88+
7689
_connectionState = STATE_ERROR;
7790
_clientState = CSTATE_ACTIVE;
7891

@@ -214,41 +227,90 @@ int HTTPSConnection::updateBuffer() {
214227
// start at 0x1000, so we need to use _socket+1 here
215228
select(_socket + 1, &sockfds, NULL, NULL, &timeout);
216229

217-
if (FD_ISSET(_socket, &sockfds) || SSL_pending(_ssl) > 0) {
218-
219-
HTTPS_DLOGHEX("[ ] There is data on the connection socket. fid=", _socket)
220-
221-
// The return code of SSL_read means:
222-
// > 0 : Length of the data that has been read
223-
// < 0 : Error
224-
// = 0 : Connection closed
225-
int readReturnCode = SSL_read(
226-
_ssl,
227-
// Only after the part of the buffer that has not been processed yet
228-
_receiveBuffer + sizeof(char) * _bufferUnusedIdx,
229-
// Only append up to the end of the buffer
230-
HTTPS_CONNECTION_DATA_CHUNK_SIZE - _bufferUnusedIdx
231-
);
232-
233-
if (readReturnCode > 0) {
234-
_bufferUnusedIdx += readReturnCode;
235-
refreshTimeout();
236-
return readReturnCode;
237-
238-
} else if (readReturnCode == 0) {
239-
// The connection has been closed by the client
240-
_clientState = CSTATE_CLOSED;
241-
HTTPS_DLOGHEX("[ x ] Client closed connection, fid=", _socket);
242-
// TODO: If we are in state websocket, we might need to do something here
243-
return 0;
244-
} else {
245-
// An error occured
246-
_connectionState = STATE_ERROR;
247-
HTTPS_DLOGHEX("[ERR] An SSL error occured, fid=", _socket);
248-
closeConnection();
249-
return -1;
250-
}
251-
} // data pending
230+
if (_ssl) { // HTTPS
231+
232+
if (FD_ISSET(_socket, &sockfds) || SSL_pending(_ssl) > 0) {
233+
234+
HTTPS_DLOGHEX("[ ] There is data on the connection socket. fid=", _socket)
235+
236+
int readReturnCode;
237+
238+
// The return code of SSL_read means:
239+
// > 0 : Length of the data that has been read
240+
// < 0 : Error
241+
// = 0 : Connection closed
242+
readReturnCode = SSL_read(
243+
_ssl,
244+
// Only after the part of the buffer that has not been processed yet
245+
_receiveBuffer + sizeof(char) * _bufferUnusedIdx,
246+
// Only append up to the end of the buffer
247+
HTTPS_CONNECTION_DATA_CHUNK_SIZE - _bufferUnusedIdx
248+
);
249+
250+
if (readReturnCode > 0) {
251+
_bufferUnusedIdx += readReturnCode;
252+
refreshTimeout();
253+
return readReturnCode;
254+
255+
} else if (readReturnCode == 0) {
256+
// The connection has been closed by the client
257+
_clientState = CSTATE_CLOSED;
258+
HTTPS_DLOGHEX("[ x ] Client closed connection, fid=", _socket);
259+
// TODO: If we are in state websocket, we might need to do something here
260+
return 0;
261+
} else {
262+
// An error occured
263+
_connectionState = STATE_ERROR;
264+
HTTPS_DLOGHEX("[ERR] An SSL error occured, fid=", _socket);
265+
closeConnection();
266+
return -1;
267+
}
268+
} // data pending
269+
270+
} else { // HTTP
271+
272+
if (FD_ISSET(_socket, &sockfds)) {
273+
274+
HTTPS_DLOGHEX("[ ] There is data on the connection socket. fid=", _socket)
275+
276+
int readReturnCode;
277+
278+
// The return code of SSL_read means:
279+
// > 0 : Length of the data that has been read
280+
// < 0 : Error
281+
// = 0 : Connection closed
282+
283+
readReturnCode = recv(
284+
_socket,
285+
// Only after the part of the buffer that has not been processed yet
286+
_receiveBuffer + sizeof(char) * _bufferUnusedIdx,
287+
// Only append up to the end of the buffer
288+
HTTPS_CONNECTION_DATA_CHUNK_SIZE - _bufferUnusedIdx,
289+
MSG_WAITALL | MSG_DONTWAIT
290+
);
291+
if (readReturnCode > 0) {
292+
_bufferUnusedIdx += readReturnCode;
293+
refreshTimeout();
294+
return readReturnCode;
295+
296+
} else if (readReturnCode == 0) {
297+
// The connection has been closed by the client
298+
_clientState = CSTATE_CLOSED;
299+
HTTPS_DLOGHEX("[ x ] Client closed connection, fid=", _socket);
300+
// TODO: If we are in state websocket, we might need to do something here
301+
return 0;
302+
} else {
303+
// An error occured
304+
_connectionState = STATE_ERROR;
305+
HTTPS_DLOGHEX("[ERR] An recv error occured, fid=", _socket);
306+
closeConnection();
307+
return -1;
308+
}
309+
310+
} // data pending
311+
312+
}
313+
252314
} // buffer can read more
253315
}
254316
return 0;
@@ -272,30 +334,40 @@ size_t HTTPSConnection::readBuffer(byte* buffer, size_t length) {
272334

273335
size_t HTTPSConnection::pendingBufferSize() {
274336
updateBuffer();
275-
return _bufferUnusedIdx - _bufferProcessed + SSL_pending(_ssl);
337+
338+
if (_ssl) // HTTPS
339+
return _bufferUnusedIdx - _bufferProcessed + SSL_pending(_ssl);
340+
else // HTTP
341+
return _bufferUnusedIdx - _bufferProcessed;
276342
}
277343

278344
void HTTPSConnection::serverError() {
279-
_connectionState = STATE_ERROR;
345+
_connectionState = STATE_ERROR;
280346

281-
// TODO: Write 500
282-
Serial.println("Server error");
283-
char staticResponse[] = "HTTP/1.1 500 Internal Server Error\r\nServer: esp32https\r\nConnection:close\r\nContent-Type: text/html\r\nContent-Length:34\r\n\r\n<h1>500 Internal Server Error</h1>";
284-
SSL_write(_ssl, staticResponse, strlen(staticResponse));
347+
// TODO: Write 500
348+
Serial.println("Server error");
349+
char staticResponse[] = "HTTP/1.1 500 Internal Server Error\r\nServer: esp32https\r\nConnection:close\r\nContent-Type: text/html\r\nContent-Length:34\r\n\r\n<h1>500 Internal Server Error</h1>";
350+
if (_ssl) // HTTPS
351+
SSL_write(_ssl, staticResponse, strlen(staticResponse));
352+
else // HTTP
353+
send(_socket, staticResponse, strlen(staticResponse), 0);
285354

286-
closeConnection();
355+
closeConnection();
287356
}
288357

289358

290359
void HTTPSConnection::clientError() {
291-
_connectionState = STATE_ERROR;
292-
293-
// TODO: Write 400
294-
Serial.println("Client error");
295-
char staticResponse[] = "HTTP/1.1 400 Bad Request\r\nServer: esp32https\r\nConnection:close\r\nContent-Type: text/html\r\nContent-Length:26\r\n\r\n<h1>400 Bad Request</h1>";
296-
SSL_write(_ssl, staticResponse, strlen(staticResponse));
297-
298-
closeConnection();
360+
_connectionState = STATE_ERROR;
361+
362+
// TODO: Write 400
363+
Serial.println("Client error");
364+
char staticResponse[] = "HTTP/1.1 400 Bad Request\r\nServer: esp32https\r\nConnection:close\r\nContent-Type: text/html\r\nContent-Length:26\r\n\r\n<h1>400 Bad Request</h1>";
365+
if (_ssl) // HTTPS
366+
SSL_write(_ssl, staticResponse, strlen(staticResponse));
367+
else // HTTP
368+
send(_socket, staticResponse, strlen(staticResponse), 0);
369+
370+
closeConnection();
299371
}
300372

301373
void HTTPSConnection::readLine(int lengthLimit) {
@@ -528,4 +600,4 @@ void HTTPSConnection::loop() {
528600

529601
}
530602

531-
} /* namespace httpsserver */
603+
} /* namespace httpsserver */

https/HTTPSConnection.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class HTTPSConnection : private ConnectionContext {
3737
HTTPSConnection(ResourceResolver * resResolver);
3838
virtual ~HTTPSConnection();
3939

40-
int initialize(int serverSocketID, SSL_CTX * sslCtx, HTTPHeaders *defaultHeaders);
40+
int initialize(int serverSocketID, SSL_CTX * sslCtx, HTTPHeaders *defaultHeaders, bool isSSLSocket);
4141
void loop();
4242
void closeConnection();
4343
bool isClosed();
@@ -52,7 +52,8 @@ class HTTPSConnection : private ConnectionContext {
5252
bool isTimeoutExceeded();
5353
void refreshTimeout();
5454

55-
SSL* ssl() {return _ssl;};
55+
SSL* ssl() {return _ssl;}; // needed for HTTPS
56+
int __socket() {return _socket;}; // needed for HTTP
5657
void signalClientClose();
5758
void signalRequestError();
5859
size_t getCacheSize();
@@ -147,4 +148,4 @@ class HTTPSConnection : private ConnectionContext {
147148

148149
} /* namespace httpsserver */
149150

150-
#endif /* HTTPS_HTTPSCONNECTION_HPP_ */
151+
#endif /* HTTPS_HTTPSCONNECTION_HPP_ */

0 commit comments

Comments
 (0)