From ec894796ed3c36e00635fc08c9bb4cfd842f6d99 Mon Sep 17 00:00:00 2001 From: Brian Ensor Date: Tue, 13 Oct 2015 08:53:54 -0600 Subject: [PATCH 1/7] Create RequestArgument array of header pairs --- .../ESP8266WebServer/src/Parsing.cpp | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/Parsing.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/Parsing.cpp index 216f20c3e4..17dc8191d7 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/Parsing.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/Parsing.cpp @@ -31,7 +31,12 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) { // Read the first line of HTTP request String req = client.readStringUntil('\r'); client.readStringUntil('\n'); - + + if (_currentHeaders) + delete[] _currentHeaders; + _currentHeaders = 0; + _currentHeaderCount = 0; + // First line of HTTP request looks like "GET /path HTTP/1.1" // Retrieve the "/path" part by finding the spaces int addr_start = req.indexOf(' '); @@ -96,6 +101,17 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) { } headerName = req.substring(0, headerDiv); headerValue = req.substring(headerDiv + 2); + + RequestArgument* _newHeaders = new RequestArgument[_currentHeaderCount+1]; + for (int i = 0; i < _currentHeaderCount; i++) { + _newHeaders[i] = _currentHeaders[i]; + } + RequestArgument& arg = _newHeaders[_currentHeaderCount]; + arg.key = headerName; + arg.value = headerValue; + _currentHeaderCount++; + if (_currentHeaders) delete[] _currentHeaders; + _currentHeaders = _newHeaders; #ifdef DEBUG DEBUG_OUTPUT.print("headerName: "); @@ -161,6 +177,17 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) { } headerName = req.substring(0, headerDiv); headerValue = req.substring(headerDiv + 2); + + RequestArgument* _newHeaders = new RequestArgument[_currentHeaderCount+1]; + for (int i = 0; i < _currentHeaderCount; i++) { + _newHeaders[i] = _currentHeaders[i]; + } + RequestArgument& arg = _newHeaders[_currentHeaderCount]; + arg.key = headerName; + arg.value = headerValue; + _currentHeaderCount++; + if (_currentHeaders) delete[] _currentHeaders; + _currentHeaders = _newHeaders; #ifdef DEBUG DEBUG_OUTPUT.print("headerName: "); From 05921b7bae85c67e4b8a0381c76d17736659ec3e Mon Sep 17 00:00:00 2001 From: Brian Ensor Date: Tue, 13 Oct 2015 08:56:16 -0600 Subject: [PATCH 2/7] Add arg-like access functions and variables --- .../libraries/ESP8266WebServer/src/ESP8266WebServer.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.h index 8a640a9350..c11ab71708 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -83,6 +83,12 @@ class ESP8266WebServer String argName(int i); // get request argument name by number int args(); // get arguments count bool hasArg(const char* name); // check if argument exists + + String header(const char* name); // get request header value by name + String header(int i); // get request header value by number + String headerName(int i); // get request header name by number + int headers(); // get header count + bool hasHeader(const char* name); // check if header exists String hostHeader(); // get request host header if available or empty String if not @@ -139,6 +145,9 @@ template size_t streamFile(T &file, const String& contentType){ size_t _currentArgCount; RequestArgument* _currentArgs; HTTPUpload _currentUpload; + + size_t _currentHeaderCount; + RequestArgument* _currentHeaders; size_t _contentLength; String _responseHeaders; From 9b3b9228b736e521bd206b01d52c151be94f3b32 Mon Sep 17 00:00:00 2001 From: Brian Ensor Date: Tue, 13 Oct 2015 08:57:54 -0600 Subject: [PATCH 3/7] Define header access functions --- .../ESP8266WebServer/src/ESP8266WebServer.cpp | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp index f0ab929f36..4d8c5f6fa1 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp @@ -283,6 +283,38 @@ bool ESP8266WebServer::hasArg(const char* name) { return false; } +String ESP8266WebServer::header(const char* name) { + for (int i = 0; i < _currentHeaderCount; ++i) { + if (_currentHeaders[i].key == name) + return _currentHeaders[i].value; + } + return String(); +} + +String ESP8266WebServer::header(int i) { + if (i < _currentHeaderCount) + return _currentHeaders[i].value; + return String(); +} + +String ESP8266WebServer::headerName(int i) { + if (i < _currentHeaderCount) + return _currentHeaders[i].key; + return String(); +} + +int ESP8266WebServer::headers() { + return _currentHeaderCount; +} + +bool ESP8266WebServer::hasHeader(const char* name) { + for (int i = 0; i < _currentHeaderCount; ++i) { + if (_currentHeaders[i].key == name) + return true; + } + return false; +} + String ESP8266WebServer::hostHeader() { return _hostHeader; } From d9e3a351afb6243c1706470b2fb74e41d2945c14 Mon Sep 17 00:00:00 2001 From: Brian Ensor Date: Wed, 14 Oct 2015 17:59:34 -0600 Subject: [PATCH 4/7] Added collectHeaders method and supporting vars --- .../esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.h index c11ab71708..fd630e07d8 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -84,6 +84,7 @@ class ESP8266WebServer int args(); // get arguments count bool hasArg(const char* name); // check if argument exists + void collectHeaders(const char* headerKeys[], const size_t headerKeysCount); // set the request headers to collect String header(const char* name); // get request header value by name String header(int i); // get request header value by number String headerName(int i); // get request header name by number @@ -130,6 +131,7 @@ template size_t streamFile(T &file, const String& contentType){ void _uploadWriteByte(uint8_t b); uint8_t _uploadReadByte(WiFiClient& client); void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength); + bool _collectHeader(const char* headerName); struct RequestArgument { String key; @@ -148,6 +150,8 @@ template size_t streamFile(T &file, const String& contentType){ size_t _currentHeaderCount; RequestArgument* _currentHeaders; + size_t _headerKeysCount; + const char** _headerKeys; size_t _contentLength; String _responseHeaders; From c117d78df345e5f304bacaf803f1a777170b9ddc Mon Sep 17 00:00:00 2001 From: Brian Ensor Date: Wed, 14 Oct 2015 18:01:40 -0600 Subject: [PATCH 5/7] Defined method and freed used memory in destructor --- .../ESP8266WebServer/src/ESP8266WebServer.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp index 4d8c5f6fa1..69b23514fd 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp @@ -41,6 +41,10 @@ ESP8266WebServer::ESP8266WebServer(int port) } ESP8266WebServer::~ESP8266WebServer() { + if (_headerKeys) { + free(_headerKeys); + _headerKeys = 0; + } if (!_firstHandler) return; RequestHandler* handler = _firstHandler; @@ -291,6 +295,14 @@ String ESP8266WebServer::header(const char* name) { return String(); } +void ESP8266WebServer::collectHeaders(const char* headerKeys[], const size_t headerKeysCount) { + _headerKeysCount = headerKeysCount; + _headerKeys = (const char**)malloc(_headerKeysCount*sizeof(char*)); + for (int i = 0; i < _headerKeysCount; i++){ + _headerKeys[i] = headerKeys[i]; + } +} + String ESP8266WebServer::header(int i) { if (i < _currentHeaderCount) return _currentHeaders[i].value; From d44fc5b1308485c5bb0e03b29207b94828154166 Mon Sep 17 00:00:00 2001 From: Brian Ensor Date: Wed, 14 Oct 2015 18:04:05 -0600 Subject: [PATCH 6/7] Defined _collectHeader and updated parser --- .../ESP8266WebServer/src/Parsing.cpp | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/Parsing.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/Parsing.cpp index 17dc8191d7..4705713237 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/Parsing.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/Parsing.cpp @@ -34,7 +34,7 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) { if (_currentHeaders) delete[] _currentHeaders; - _currentHeaders = 0; + _currentHeaders = new RequestArgument[_headerKeysCount]; _currentHeaderCount = 0; // First line of HTTP request looks like "GET /path HTTP/1.1" @@ -102,16 +102,12 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) { headerName = req.substring(0, headerDiv); headerValue = req.substring(headerDiv + 2); - RequestArgument* _newHeaders = new RequestArgument[_currentHeaderCount+1]; - for (int i = 0; i < _currentHeaderCount; i++) { - _newHeaders[i] = _currentHeaders[i]; + if (_collectHeader(headerName.c_str())) { + RequestArgument& arg = _currentHeaders[_currentHeaderCount]; + arg.key = headerName; + arg.value = headerValue; + _currentHeaderCount++; } - RequestArgument& arg = _newHeaders[_currentHeaderCount]; - arg.key = headerName; - arg.value = headerValue; - _currentHeaderCount++; - if (_currentHeaders) delete[] _currentHeaders; - _currentHeaders = _newHeaders; #ifdef DEBUG DEBUG_OUTPUT.print("headerName: "); @@ -178,16 +174,12 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) { headerName = req.substring(0, headerDiv); headerValue = req.substring(headerDiv + 2); - RequestArgument* _newHeaders = new RequestArgument[_currentHeaderCount+1]; - for (int i = 0; i < _currentHeaderCount; i++) { - _newHeaders[i] = _currentHeaders[i]; + if (_collectHeader(headerName.c_str())) { + RequestArgument& arg = _currentHeaders[_currentHeaderCount]; + arg.key = headerName; + arg.value = headerValue; + _currentHeaderCount++; } - RequestArgument& arg = _newHeaders[_currentHeaderCount]; - arg.key = headerName; - arg.value = headerValue; - _currentHeaderCount++; - if (_currentHeaders) delete[] _currentHeaders; - _currentHeaders = _newHeaders; #ifdef DEBUG DEBUG_OUTPUT.print("headerName: "); @@ -214,6 +206,12 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) { return true; } +bool ESP8266WebServer::_collectHeader(const char* headerName) { + for (size_t i = 0; i < _headerKeysCount; i++) { + if (strcmp(headerName, _headerKeys[i]) == 0) return true; + } + return false; +} void ESP8266WebServer::_parseArguments(String data) { #ifdef DEBUG From fab08c5b5dda0d87f8f8fdc32f27a8eb5f932190 Mon Sep 17 00:00:00 2001 From: Brian Ensor Date: Wed, 14 Oct 2015 18:49:41 -0600 Subject: [PATCH 7/7] Safer destructor with _headerKeysCount = 0 --- .../libraries/ESP8266WebServer/src/ESP8266WebServer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp index 69b23514fd..1fd7e727e6 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp @@ -41,10 +41,10 @@ ESP8266WebServer::ESP8266WebServer(int port) } ESP8266WebServer::~ESP8266WebServer() { - if (_headerKeys) { + if (_headerKeys) free(_headerKeys); - _headerKeys = 0; - } + _headerKeys = 0; + _headerKeysCount = 0; if (!_firstHandler) return; RequestHandler* handler = _firstHandler;