#include "WEBServerManager.h" #define DEBUG 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) { _wifiServer.begin(); } boolean WEBServerManager::runServer() { switch(_clientState) { case WAITING_FOR_CLIENT: _wifiClient.stopAll(); _wifiClient = _wifiServer.available(); if(_wifiClient) { _clientState = NEW; _clientTimeout = millis(); #ifdef DEBUG Serial.println("Client connected !!!"); #endif } break; case NEW: _clientState = NOT_HANDLED; break; case NOT_HANDLED: if(millis()-_clientTimeout > 500) { _clientState = HANDLED; #ifdef DEBUG Serial.println("Client timed out !!!"); #endif } parseQuery(&_wifiClient); break; case QUERY_PARSED: _clientState = RESPONSE_SENT; break; case RESPONSE_SENT: #ifdef DEBUG Serial.println("Client handled !!!"); #endif _wifiClient.print(F("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\n\r\n

Response !!!

")); _clientState = HANDLED; break; case HANDLED: _wifiClient.stopAll(); _clientState = WAITING_FOR_CLIENT; #ifdef DEBUG Serial.println("Client discarded !!!"); #endif break; default: break; } return true; } boolean WEBServerManager::parseQuery(WiFiClient *wifiClient) { char readChar(0), *parseBuffer(NULL); _httpParserState = INIT; while(wifiClient->available()) { 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) { case INIT: if(readChar >= 65 && readChar <= 90) { 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; } _clientState = QUERY_PARSED; } return true; } unsigned int WEBServerManager::getPort() const { return _port; } char *WEBServerManager::addChar(char *pointer, const char character) { char *tempAddr = NULL; if(pointer == NULL) { tempAddr = (char *) realloc(pointer, 2*sizeof(char)); if(tempAddr == NULL) return NULL; else { pointer = tempAddr; pointer[0] = character; pointer[1] = '\0'; } } else { tempAddr = (char *) realloc(pointer, (strlen(pointer)+2)*sizeof(char)); if(tempAddr == NULL) { free(pointer); return NULL; } else { pointer = tempAddr; pointer[strlen(pointer)+1] = '\0'; pointer[strlen(pointer)] = character; } } return pointer; } WEBServerManager::HttpRequestMethod WEBServerManager::getHttpVerbEnumValue(const char *parseBuffer) { //UNDEFINED, GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH if(strcmp(parseBuffer,"GET") == 0){return GET;} else if(strcmp(parseBuffer,"POST") == 0){return POST;} else if(strcmp(parseBuffer,"HEAD") == 0){return HEAD;} else if(strcmp(parseBuffer,"PUT") == 0){return PUT;} else if(strcmp(parseBuffer,"DELETE") == 0){return DELETE;} else if(strcmp(parseBuffer,"CONNECT") == 0){return CONNECT;} else if(strcmp(parseBuffer,"TRACE") == 0){return TRACE;} else if(strcmp(parseBuffer,"PATCH") == 0){return PATCH;} else if(strcmp(parseBuffer,"OPTIONS") == 0){return OPTIONS;} else return UNDEFINED; } WEBServerManager::HttpVersion WEBServerManager::getHttpVersionEnumValue(const char *parseBuffer) { //HTTP_0_9, HTTP_1_1, HTTP_1_0, HTTP_2_0 if(strcmp(parseBuffer,"1.1") == 0){return HTTP_1_1;} else if(strcmp(parseBuffer,"2.0") == 0){return HTTP_2_0;} else if(strcmp(parseBuffer,"1.0") == 0){return HTTP_1_0;} else if(strcmp(parseBuffer,"0.9") == 0){return HTTP_0_9;} else return UNKNOWN; }