Added the WEBServerManager class

This commit is contained in:
anschrammh 2019-03-31 11:01:55 +02:00
parent c512c6b028
commit 30f4900609
2 changed files with 278 additions and 0 deletions

View File

@ -0,0 +1,232 @@
#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<!DOCTYPE HTML>\r\n<html>\r\n<p>Response !!!</p></html>"));
_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;
}

View File

@ -0,0 +1,46 @@
#ifndef WEBSERVERMANAGER_H
#define WEBSERVERMANAGER_H
#include <WiFiServer.h>
#include <WiFiClient.h>
#include "SDCardManager.h"
#include "definition.h"
class WEBServerManager
{
public:
WEBServerManager(unsigned int port = 80, SDCardManager *sdCardManager = NULL);
boolean runServer();
unsigned int getPort() const;
protected:
private:
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};
struct HttpRequestData{
HttpRequestMethod HRM;
HttpVersion HV;
char *httpResource;
char *httpBody;
};
boolean parseQuery(WiFiClient *wifiClient);
char *addChar(char *pointer, const char character);
HttpRequestMethod getHttpVerbEnumValue(const char *parseBuffer);
HttpVersion getHttpVersionEnumValue(const char *parseBuffer);
WiFiServer _wifiServer;
WiFiClient _wifiClient;//One client only, maybe replaced with a fifo in the future
SDCardManager *_sdCardManager;
HttpRequestData _httpRequestData;
ClientStatus _clientState;
HttpParserStatus _httpParserState;
unsigned long _clientTimeout;
unsigned int _port;
};
#endif //WEBSERVERMANAGER_H