Added custom api logic function mechanism

This commit is contained in:
anschrammh 2019-04-01 23:53:32 +02:00
parent d302ce7e45
commit 7717fa94e3
2 changed files with 69 additions and 11 deletions

View File

@ -8,6 +8,21 @@ WEBServerManager::WEBServerManager(unsigned int port, SDCardManager *sdCardManag
_wifiServer.begin(); _wifiServer.begin();
} }
boolean WEBServerManager::addApiRoutine(const char *uri, boolean (*apiRoutine)(HttpRequestData&, WiFiClient& , void*), void *pData, HttpRequestMethod HRM)
{
return _apiDictionary.add(uri,new ApiRoutine({apiRoutine,pData, HRM}));
}
void WEBServerManager::clearApiRoutine()
{
_apiDictionary.clear();
}
boolean WEBServerManager::removeApiRoutine(const char *uri)
{
_apiDictionary.remove(uri);
}
boolean WEBServerManager::runServer() boolean WEBServerManager::runServer()
{ {
switch(_clientState) switch(_clientState)
@ -39,7 +54,9 @@ boolean WEBServerManager::runServer()
#ifdef DEBUG #ifdef DEBUG
Serial.println("Sending response !!!"); Serial.println("Sending response !!!");
#endif #endif
sendPageToClientFromSdCard(&_wifiClient); //We first check if it s an api call
if(!sendPageToClientFromApiDictio(&_wifiClient))
sendPageToClientFromSdCard(&_wifiClient);
_clientState = RESPONSE_SENT; _clientState = RESPONSE_SENT;
break; break;
case RESPONSE_SENT: case RESPONSE_SENT:
@ -64,10 +81,11 @@ boolean WEBServerManager::runServer()
boolean WEBServerManager::parseQuery(WiFiClient *wifiClient) boolean WEBServerManager::parseQuery(WiFiClient *wifiClient)
{ {
char readChar(0), *parseBuffer(NULL); char readChar(0), *parseBuffer(NULL);
boolean smallTimeout(false);
_httpParserState = INIT; _httpParserState = INIT;
_clientTimeout = millis(); _clientTimeout = millis();
while(wifiClient->available() || millis() - _clientTimeout < 150) while(wifiClient->available() || millis() - _clientTimeout < (smallTimeout ? 100 : 5000))
{ {
if(wifiClient->available()) if(wifiClient->available())
{ {
@ -154,6 +172,7 @@ boolean WEBServerManager::parseQuery(WiFiClient *wifiClient)
break; break;
} }
_clientTimeout = millis(); _clientTimeout = millis();
smallTimeout = true;
} }
} }
@ -300,12 +319,34 @@ boolean WEBServerManager::sendPageToClientFromSdCard(WiFiClient *wifiClient)
return true; return true;
} }
boolean WEBServerManager::sendPageToClientFromApiDictio(WiFiClient *wifiClient)
{
if(_apiDictionary.count() == 0)
return false;
ApiRoutine *ref = _apiDictionary(_httpRequestData.httpResource).getValueRef();
if(ref == NULL)
return false;
if(ref->HRM == UNDEFINED)
{
return (*ref->apiRoutine)(_httpRequestData, *wifiClient, ref->pData);
}else if(ref->HRM == _httpRequestData.HRM)
{
return (*ref->apiRoutine)(_httpRequestData, *wifiClient, ref->pData);
}
else
return false;
}
WEBServerManager::HttpMIMEType WEBServerManager::getMIMETypeByExtension(const char *extension) WEBServerManager::HttpMIMEType WEBServerManager::getMIMETypeByExtension(const char *extension)
{ {
//TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT //TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT
if(strcmp(extension,"web") == 0) return TEXT_HTML; if(strcmp(extension,"web") == 0) return TEXT_HTML;
else if(strcmp(extension,"css") == 0) return TEXT_CSS; else if(strcmp(extension,"css") == 0) return TEXT_CSS;
else if(strcmp(extension,"js") == 0) return TEXT_JAVASCRIPT; else if(strcmp(extension,"js") == 0) return TEXT_JAVASCRIPT;
else if(strcmp(extension,"png") == 0) return IMAGE_PNG;
else return TEXT_PLAIN; else return TEXT_PLAIN;
} }
@ -324,6 +365,9 @@ char *WEBServerManager::getHTTPHeader(HttpMIMEType httpMIMEType, unsigned long s
case TEXT_JAVASCRIPT: case TEXT_JAVASCRIPT:
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","text/javascript",size); sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","text/javascript",size);
break; break;
case IMAGE_PNG:
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","image/png",size);
break;
case TEXT_PLAIN: case TEXT_PLAIN:
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","text/plain",size); sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","text/plain",size);
break; break;

View File

@ -5,22 +5,18 @@
#include <WiFiClient.h> #include <WiFiClient.h>
#include "SDCardManager.h" #include "SDCardManager.h"
#include "definition.h" #include "definition.h"
#include "Dictionary.h"
struct HttpRequestData;
class WEBServerManager class WEBServerManager
{ {
public: 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 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, PARAMETER_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{UNKNOWN_MIME, TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT, APPLICATION_JSON, APPLICATION_X_WWW_FORM_URLENCODED}; enum HttpMIMEType{UNKNOWN_MIME, TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT, APPLICATION_JSON, APPLICATION_X_WWW_FORM_URLENCODED, IMAGE_PNG};
struct HttpRequestData{ struct HttpRequestData{
HttpRequestMethod HRM; HttpRequestMethod HRM;
HttpVersion HV; HttpVersion HV;
@ -28,8 +24,26 @@ class WEBServerManager
char *httpResource; char *httpResource;
char *httpBody; char *httpBody;
}; };
WEBServerManager(unsigned int port = 80, SDCardManager *sdCardManager = NULL);
boolean runServer();
unsigned int getPort() const;
boolean addApiRoutine(const char *uri, boolean (*apiRoutine)(HttpRequestData&, WiFiClient&, void*), void *pData, HttpRequestMethod HRM = UNDEFINED);
void clearApiRoutine();
boolean removeApiRoutine(const char *uri);
protected:
private:
struct ApiRoutine
{
boolean (*apiRoutine)(HttpRequestData&, WiFiClient&, void*);
void *pData;
HttpRequestMethod HRM;
};
boolean parseQuery(WiFiClient *wifiClient); boolean parseQuery(WiFiClient *wifiClient);
boolean sendPageToClientFromSdCard(WiFiClient *wifiClient); boolean sendPageToClientFromSdCard(WiFiClient *wifiClient);
boolean sendPageToClientFromApiDictio(WiFiClient *wifiClient);
char *addChar(char *pointer, const char character); char *addChar(char *pointer, const char character);
HttpRequestMethod getHttpVerbEnumValue(const char *parseBuffer); HttpRequestMethod getHttpVerbEnumValue(const char *parseBuffer);
HttpVersion getHttpVersionEnumValue(const char *parseBuffer); HttpVersion getHttpVersionEnumValue(const char *parseBuffer);
@ -42,8 +56,8 @@ class WEBServerManager
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
SDCardManager *_sdCardManager; SDCardManager *_sdCardManager;
HttpRequestData _httpRequestData; HttpRequestData _httpRequestData;
Dictionary<ApiRoutine> _apiDictionary;
ClientStatus _clientState; ClientStatus _clientState;
HttpParserStatus _httpParserState; HttpParserStatus _httpParserState;