diff --git a/src/app/WEBServerManager.cpp b/src/app/WEBServerManager.cpp index 6ce45a7..f83af6e 100644 --- a/src/app/WEBServerManager.cpp +++ b/src/app/WEBServerManager.cpp @@ -1,8 +1,9 @@ #include "WEBServerManager.h" #define DEBUG +#define DEBUG_RAW -WEBServerManager::WEBServerManager(unsigned int port, SDCardManager *sdCardManager) : _wifiServer(port), _sdCardManager(sdCardManager), _httpRequestData({UNDEFINED, UNKNOWN, NULL,NULL}), _httpParserState(INIT), _clientState(WAITING_FOR_CLIENT), _port(port), _clientTimeout(0) +WEBServerManager::WEBServerManager(unsigned int port, SDCardManager *sdCardManager) : _wifiServer(port), _sdCardManager(sdCardManager), _httpRequestData({UNDEFINED, UNKNOWN, UNKNOWN_MIME, NULL,NULL}), _httpParserState(INIT), _clientState(WAITING_FOR_CLIENT), _port(port), _clientTimeout(0) { _wifiServer.begin(); } @@ -13,6 +14,7 @@ boolean WEBServerManager::runServer() { case WAITING_FOR_CLIENT: _wifiClient.stopAll(); + _wifiClient = _wifiServer.available(); if(_wifiClient) { @@ -23,20 +25,15 @@ boolean WEBServerManager::runServer() } break; case NEW: - _clientTimeout = millis(); _clientState = NOT_HANDLED; break; case NOT_HANDLED: - if(millis()-_clientTimeout > 500) - { - _clientState = HANDLED; - #ifdef DEBUG - Serial.println("Client timed out !!!"); - #endif - } - + clearHttpRequestData(); parseQuery(&_wifiClient); - + #ifdef DEBUG + Serial.println("Nothing more from client !!!"); + #endif + _clientState = QUERY_PARSED; break; case QUERY_PARSED: #ifdef DEBUG @@ -67,104 +64,117 @@ boolean WEBServerManager::runServer() boolean WEBServerManager::parseQuery(WiFiClient *wifiClient) { char readChar(0), *parseBuffer(NULL); - _httpParserState = INIT; - while(wifiClient->available()) + _httpParserState = INIT; + _clientTimeout = millis(); + while(wifiClient->available() || millis() - _clientTimeout < 150) { - readChar = (char)wifiClient->read(); - #ifdef DEBUG - //Serial.print(readChar); - #endif - //INIT, LINE_BREAK, HTTP_VERB_SECTION, HTTP_RESOURCE_SECTION, HTTP_VER_SECTION, BODY_SECTION, IGNORED, ERROR - switch(_httpParserState) + if(wifiClient->available()) { - case INIT: - if(readChar >= 65 && readChar <= 90) - { + readChar = (char)wifiClient->read(); + #ifdef DEBUG_RAW + Serial.print(readChar); + #endif + //INIT, LINE_BREAK, HTTP_VERB_SECTION, HTTP_RESOURCE_SECTION, HTTP_VER_SECTION, BODY_SECTION, IGNORED, ERROR + switch(_httpParserState) + { + case INIT: + if(readChar >= 65 && readChar <= 90) + { + parseBuffer = addChar(parseBuffer, readChar); + _httpParserState = HTTP_VERB_SECTION; + } + else + _httpParserState = ERROR; + break; + case LINE_BREAK: + if(readChar == '\n') + _httpParserState = BODY_SECTION; + else if(readChar != '\r') + _httpParserState = PARAMETER_SECTION; + + break; + case HTTP_VERB_SECTION: + if(readChar >= 65 && readChar <= 90) + { + parseBuffer = addChar(parseBuffer, readChar); + _httpParserState = HTTP_VERB_SECTION; + } + else if (readChar == ' ') + { + //This is the end of the section + _httpRequestData.HRM = getHttpVerbEnumValue(parseBuffer); + free(parseBuffer);parseBuffer = NULL; + _httpParserState = HTTP_RESOURCE_SECTION; + } + else + _httpParserState = ERROR; + break; + case HTTP_RESOURCE_SECTION: + if(readChar != ' ') + { + parseBuffer = addChar(parseBuffer, readChar); + _httpParserState = HTTP_RESOURCE_SECTION; + } + else + { + free(_httpRequestData.httpResource);_httpRequestData.httpResource = NULL; + _httpRequestData.httpResource = parseBuffer;parseBuffer = NULL; + _httpParserState = HTTP_VER_SECTION; + } + break; + case HTTP_VER_SECTION: + if((readChar >= 48 && readChar <= 57) || readChar == '.') + { + parseBuffer = addChar(parseBuffer, readChar); + _httpParserState = HTTP_VER_SECTION; + } + else if(readChar == '\n') + { + _httpRequestData.HV = getHttpVersionEnumValue(parseBuffer); + free(parseBuffer);parseBuffer = NULL; + _httpParserState = LINE_BREAK; + } + break; + case BODY_SECTION: parseBuffer = addChar(parseBuffer, readChar); - _httpParserState = HTTP_VERB_SECTION; - } - else - _httpParserState = ERROR; - break; - case LINE_BREAK: - _httpParserState = IGNORED; - break; - case HTTP_VERB_SECTION: - if(readChar >= 65 && readChar <= 90) - { - parseBuffer = addChar(parseBuffer, readChar); - _httpParserState = HTTP_VERB_SECTION; - } - else if (readChar == ' ') - { - //This is the end of the section - #ifdef DEBUG - Serial.print("HTTP VERB : "); - Serial.println(parseBuffer); - #endif - _httpRequestData.HRM = getHttpVerbEnumValue(parseBuffer); - #ifdef DEBUG - Serial.print("ENUM VALUE :"); - Serial.println(_httpRequestData.HRM); - #endif - free(parseBuffer);parseBuffer = NULL; - _httpParserState = HTTP_RESOURCE_SECTION; - } - else - _httpParserState = ERROR; - break; - case HTTP_RESOURCE_SECTION: - if(readChar != ' ') - { - parseBuffer = addChar(parseBuffer, readChar); - _httpParserState = HTTP_RESOURCE_SECTION; - } - else - { - #ifdef DEBUG - Serial.print("HTTP RESOURCE : "); - Serial.println(parseBuffer); - #endif - free(_httpRequestData.httpResource);_httpRequestData.httpResource = NULL; - _httpRequestData.httpResource = parseBuffer;parseBuffer = NULL; - _httpParserState = HTTP_VER_SECTION; - } - break; - case HTTP_VER_SECTION: - if((readChar >= 48 && readChar <= 57) || readChar == '.') - { - parseBuffer = addChar(parseBuffer, readChar); - _httpParserState = HTTP_VER_SECTION; - } - else if(readChar == '\r' || readChar == '\n') - { - #ifdef DEBUG - Serial.print("HTTP VERSION : "); - Serial.println(parseBuffer); - #endif - _httpRequestData.HV = getHttpVersionEnumValue(parseBuffer); - #ifdef DEBUG - Serial.print("HTTP VERSION ENUM : "); - Serial.println(_httpRequestData.HV); - #endif - free(parseBuffer);parseBuffer = NULL; - _httpParserState = LINE_BREAK; - } - break; - case BODY_SECTION: - break; - case IGNORED: - break; - case ERROR: - return false; - break; //Not necessary - default : - break; + break; + case PARAMETER_SECTION: + if(readChar == '\n') + { + _httpParserState = LINE_BREAK; + } + break; + case IGNORED: + break; + case ERROR: + return false; + break; //Not necessary + default : + break; + } + _clientTimeout = millis(); } - - _clientState = QUERY_PARSED; } + + if(parseBuffer != NULL) + if(strlen(parseBuffer) > 0) + { + _httpRequestData.httpBody = parseBuffer; + parseBuffer = NULL; + } + + #ifdef DEBUG + Serial.print("HTTP VERB : "); + Serial.println(_httpRequestData.HRM); + Serial.print("HTTP RESOURCE : "); + Serial.println(_httpRequestData.httpResource); + Serial.print("HTTP VERSION : "); + Serial.println(_httpRequestData.HV); + Serial.print("BODY CONTENT : "); + Serial.println(_httpRequestData.httpBody); + #endif + return true; } @@ -379,3 +389,13 @@ WEBServerManager::HttpVersion WEBServerManager::getHttpVersionEnumValue(const ch return UNKNOWN; } +void WEBServerManager::clearHttpRequestData() +{ + _httpRequestData.HRM = UNDEFINED; + _httpRequestData.HV = UNKNOWN; + _httpRequestData.HMT = UNKNOWN_MIME; + free(_httpRequestData.httpResource);free(_httpRequestData.httpBody); + _httpRequestData.httpResource = NULL;_httpRequestData.httpBody = NULL; + +} + diff --git a/src/app/WEBServerManager.h b/src/app/WEBServerManager.h index f33d299..6fd9916 100644 --- a/src/app/WEBServerManager.h +++ b/src/app/WEBServerManager.h @@ -18,12 +18,13 @@ class WEBServerManager enum ClientStatus {NOT_HANDLED, HANDLED, NEW, WAITING_FOR_CLIENT, QUERY_PARSED, RESPONSE_SENT}; enum HttpRequestMethod {UNDEFINED, GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH}; enum HttpVersion {UNKNOWN, HTTP_0_9, HTTP_1_1, HTTP_1_0, HTTP_2_0}; - enum HttpParserStatus {INIT, LINE_BREAK, HTTP_VERB_SECTION, HTTP_RESOURCE_SECTION, HTTP_VER_SECTION, BODY_SECTION, IGNORED, ERROR}; - enum HttpMIMEType{TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT}; + enum HttpParserStatus {INIT, LINE_BREAK, HTTP_VERB_SECTION, HTTP_RESOURCE_SECTION, HTTP_VER_SECTION, PARAMETER_SECTION, BODY_SECTION, IGNORED, ERROR}; + enum HttpMIMEType{UNKNOWN_MIME, TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT, APPLICATION_JSON, APPLICATION_X_WWW_FORM_URLENCODED}; struct HttpRequestData{ HttpRequestMethod HRM; HttpVersion HV; + HttpMIMEType HMT; char *httpResource; char *httpBody; }; @@ -36,6 +37,7 @@ class WEBServerManager char *getFileExtension(char *name); HttpMIMEType getMIMETypeByExtension(const char *extension); char *getHTTPHeader(HttpMIMEType httpMIMEType, unsigned long size); + void clearHttpRequestData(); WiFiServer _wifiServer; WiFiClient _wifiClient;//One client only, maybe replaced with a fifo in the future