Improved WEBServerManager class
This commit is contained in:
parent
92b648fa67
commit
d302ce7e45
@ -1,8 +1,9 @@
|
|||||||
#include "WEBServerManager.h"
|
#include "WEBServerManager.h"
|
||||||
|
|
||||||
#define DEBUG
|
#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();
|
_wifiServer.begin();
|
||||||
}
|
}
|
||||||
@ -13,6 +14,7 @@ boolean WEBServerManager::runServer()
|
|||||||
{
|
{
|
||||||
case WAITING_FOR_CLIENT:
|
case WAITING_FOR_CLIENT:
|
||||||
_wifiClient.stopAll();
|
_wifiClient.stopAll();
|
||||||
|
|
||||||
_wifiClient = _wifiServer.available();
|
_wifiClient = _wifiServer.available();
|
||||||
if(_wifiClient)
|
if(_wifiClient)
|
||||||
{
|
{
|
||||||
@ -23,20 +25,15 @@ boolean WEBServerManager::runServer()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NEW:
|
case NEW:
|
||||||
_clientTimeout = millis();
|
|
||||||
_clientState = NOT_HANDLED;
|
_clientState = NOT_HANDLED;
|
||||||
break;
|
break;
|
||||||
case NOT_HANDLED:
|
case NOT_HANDLED:
|
||||||
if(millis()-_clientTimeout > 500)
|
clearHttpRequestData();
|
||||||
{
|
|
||||||
_clientState = HANDLED;
|
|
||||||
#ifdef DEBUG
|
|
||||||
Serial.println("Client timed out !!!");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
parseQuery(&_wifiClient);
|
parseQuery(&_wifiClient);
|
||||||
|
#ifdef DEBUG
|
||||||
|
Serial.println("Nothing more from client !!!");
|
||||||
|
#endif
|
||||||
|
_clientState = QUERY_PARSED;
|
||||||
break;
|
break;
|
||||||
case QUERY_PARSED:
|
case QUERY_PARSED:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -67,104 +64,117 @@ boolean WEBServerManager::runServer()
|
|||||||
boolean WEBServerManager::parseQuery(WiFiClient *wifiClient)
|
boolean WEBServerManager::parseQuery(WiFiClient *wifiClient)
|
||||||
{
|
{
|
||||||
char readChar(0), *parseBuffer(NULL);
|
char readChar(0), *parseBuffer(NULL);
|
||||||
_httpParserState = INIT;
|
|
||||||
|
|
||||||
while(wifiClient->available())
|
_httpParserState = INIT;
|
||||||
|
_clientTimeout = millis();
|
||||||
|
while(wifiClient->available() || millis() - _clientTimeout < 150)
|
||||||
{
|
{
|
||||||
readChar = (char)wifiClient->read();
|
if(wifiClient->available())
|
||||||
#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:
|
readChar = (char)wifiClient->read();
|
||||||
if(readChar >= 65 && readChar <= 90)
|
#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);
|
parseBuffer = addChar(parseBuffer, readChar);
|
||||||
_httpParserState = HTTP_VERB_SECTION;
|
break;
|
||||||
}
|
case PARAMETER_SECTION:
|
||||||
else
|
if(readChar == '\n')
|
||||||
_httpParserState = ERROR;
|
{
|
||||||
break;
|
_httpParserState = LINE_BREAK;
|
||||||
case LINE_BREAK:
|
}
|
||||||
_httpParserState = IGNORED;
|
break;
|
||||||
break;
|
case IGNORED:
|
||||||
case HTTP_VERB_SECTION:
|
break;
|
||||||
if(readChar >= 65 && readChar <= 90)
|
case ERROR:
|
||||||
{
|
return false;
|
||||||
parseBuffer = addChar(parseBuffer, readChar);
|
break; //Not necessary
|
||||||
_httpParserState = HTTP_VERB_SECTION;
|
default :
|
||||||
}
|
break;
|
||||||
else if (readChar == ' ')
|
}
|
||||||
{
|
_clientTimeout = millis();
|
||||||
//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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,3 +389,13 @@ WEBServerManager::HttpVersion WEBServerManager::getHttpVersionEnumValue(const ch
|
|||||||
return UNKNOWN;
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -18,12 +18,13 @@ class WEBServerManager
|
|||||||
enum ClientStatus {NOT_HANDLED, HANDLED, NEW, WAITING_FOR_CLIENT, QUERY_PARSED, RESPONSE_SENT};
|
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 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 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 HttpParserStatus {INIT, LINE_BREAK, HTTP_VERB_SECTION, HTTP_RESOURCE_SECTION, HTTP_VER_SECTION, PARAMETER_SECTION, BODY_SECTION, IGNORED, ERROR};
|
||||||
enum HttpMIMEType{TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT};
|
enum HttpMIMEType{UNKNOWN_MIME, TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT, APPLICATION_JSON, APPLICATION_X_WWW_FORM_URLENCODED};
|
||||||
|
|
||||||
struct HttpRequestData{
|
struct HttpRequestData{
|
||||||
HttpRequestMethod HRM;
|
HttpRequestMethod HRM;
|
||||||
HttpVersion HV;
|
HttpVersion HV;
|
||||||
|
HttpMIMEType HMT;
|
||||||
char *httpResource;
|
char *httpResource;
|
||||||
char *httpBody;
|
char *httpBody;
|
||||||
};
|
};
|
||||||
@ -36,6 +37,7 @@ class WEBServerManager
|
|||||||
char *getFileExtension(char *name);
|
char *getFileExtension(char *name);
|
||||||
HttpMIMEType getMIMETypeByExtension(const char *extension);
|
HttpMIMEType getMIMETypeByExtension(const char *extension);
|
||||||
char *getHTTPHeader(HttpMIMEType httpMIMEType, unsigned long size);
|
char *getHTTPHeader(HttpMIMEType httpMIMEType, unsigned long size);
|
||||||
|
void clearHttpRequestData();
|
||||||
|
|
||||||
WiFiServer _wifiServer;
|
WiFiServer _wifiServer;
|
||||||
WiFiClient _wifiClient;//One client only, maybe replaced with a fifo in the future
|
WiFiClient _wifiClient;//One client only, maybe replaced with a fifo in the future
|
||||||
|
Loading…
Reference in New Issue
Block a user