2828
2929using namespace asyncsrv ;
3030
31- enum { PARSE_REQ_START ,
32- PARSE_REQ_HEADERS ,
33- PARSE_REQ_BODY ,
34- PARSE_REQ_END ,
35- PARSE_REQ_FAIL };
31+ enum { PARSE_REQ_START = 0 ,
32+ PARSE_REQ_HEADERS = 1 ,
33+ PARSE_REQ_BODY = 2 ,
34+ PARSE_REQ_END = 3 ,
35+ PARSE_REQ_FAIL = 4 };
3636
3737AsyncWebServerRequest::AsyncWebServerRequest (AsyncWebServer* s, AsyncClient* c)
38- : _client(c), _server(s), _handler(NULL ), _response(NULL ), _temp(), _parseState(0 ), _version(0 ), _method(HTTP_ANY ), _url(), _host(), _contentType(), _boundary(), _authorization(), _reqconntype(RCT_HTTP ), _authMethod(AsyncAuthType::AUTH_NONE ), _isMultipart(false ), _isPlainPost(false ), _expectingContinue(false ), _contentLength(0 ), _parsedLength(0 ), _multiParseState(0 ), _boundaryPosition(0 ), _itemStartIndex(0 ), _itemSize(0 ), _itemName(), _itemFilename(), _itemType(), _itemValue(), _itemBuffer(0 ), _itemBufferIndex(0 ), _itemIsFile(false ), _tempObject(NULL ) {
38+ : _client(c), _server(s), _handler(NULL ), _response(NULL ), _temp(), _parseState(PARSE_REQ_START ), _version(0 ), _method(HTTP_ANY ), _url(), _host(), _contentType(), _boundary(), _authorization(), _reqconntype(RCT_HTTP ), _authMethod(AsyncAuthType::AUTH_NONE ), _isMultipart(false ), _isPlainPost(false ), _expectingContinue(false ), _contentLength(0 ), _parsedLength(0 ), _multiParseState(0 ), _boundaryPosition(0 ), _itemStartIndex(0 ), _itemSize(0 ), _itemName(), _itemFilename(), _itemType(), _itemValue(), _itemBuffer(0 ), _itemBufferIndex(0 ), _itemIsFile(false ), _tempObject(NULL ) {
3939 c->onError ([](void * r, AsyncClient* c, int8_t error) { (void )c; AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onError (error); }, this );
4040 c->onAck ([](void * r, AsyncClient* c, size_t len, uint32_t time) { (void )c; AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onAck (len, time); }, this );
4141 c->onDisconnect ([](void * r, AsyncClient* c) { AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onDisconnect (); delete c; }, this );
@@ -67,13 +67,31 @@ AsyncWebServerRequest::~AsyncWebServerRequest() {
6767}
6868
6969void AsyncWebServerRequest::_onData (void * buf, size_t len) {
70+ // SSL/TLS handshake detection
71+ #ifndef ASYNC_TCP_SSL_ENABLED
72+ if (_parseState == PARSE_REQ_START && len && ((uint8_t *)buf)[0 ] == 0x16 ) { // 0x16 indicates a Handshake message (SSL/TLS).
73+ _parseState = PARSE_REQ_FAIL ;
74+ _client->close ();
75+ #ifdef ESP32
76+ log_d (" SSL/TLS handshake detected: closing connection" );
77+ #endif
78+ return ;
79+ }
80+ #endif
81+
7082 size_t i = 0 ;
7183 while (true ) {
7284
7385 if (_parseState < PARSE_REQ_BODY ) {
7486 // Find new line in buf
7587 char * str = (char *)buf;
7688 for (i = 0 ; i < len; i++) {
89+ // Check for null characters in header
90+ if (!str[i]) {
91+ _parseState = PARSE_REQ_FAIL ;
92+ _client->close (true );
93+ return ;
94+ }
7795 if (str[i] == ' \n ' ) {
7896 break ;
7997 }
@@ -246,6 +264,8 @@ bool AsyncWebServerRequest::_parseReqHead() {
246264 _method = HTTP_HEAD ;
247265 } else if (m == T_OPTIONS ) {
248266 _method = HTTP_OPTIONS ;
267+ } else {
268+ return false ;
249269 }
250270
251271 String g;
@@ -257,6 +277,9 @@ bool AsyncWebServerRequest::_parseReqHead() {
257277 _url = urlDecode (u);
258278 _addGetParams (g);
259279
280+ if (!_url.length ())
281+ return false ;
282+
260283 if (!_temp.startsWith (T_HTTP_1_0 ))
261284 _version = 1 ;
262285
@@ -566,8 +589,12 @@ void AsyncWebServerRequest::_parseLine() {
566589 _parseState = PARSE_REQ_FAIL ;
567590 _client->close ();
568591 } else {
569- _parseReqHead ();
570- _parseState = PARSE_REQ_HEADERS ;
592+ if (_parseReqHead ()) {
593+ _parseState = PARSE_REQ_HEADERS ;
594+ } else {
595+ _parseState = PARSE_REQ_FAIL ;
596+ _client->close ();
597+ }
571598 }
572599 return ;
573600 }
0 commit comments