diff --git a/src/app/WEBServerManager.cpp b/src/app/WEBServerManager.cpp index f83af6e..141707d 100644 --- a/src/app/WEBServerManager.cpp +++ b/src/app/WEBServerManager.cpp @@ -8,6 +8,21 @@ WEBServerManager::WEBServerManager(unsigned int port, SDCardManager *sdCardManag _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() { switch(_clientState) @@ -39,7 +54,9 @@ boolean WEBServerManager::runServer() #ifdef DEBUG Serial.println("Sending response !!!"); #endif - sendPageToClientFromSdCard(&_wifiClient); + //We first check if it s an api call + if(!sendPageToClientFromApiDictio(&_wifiClient)) + sendPageToClientFromSdCard(&_wifiClient); _clientState = RESPONSE_SENT; break; case RESPONSE_SENT: @@ -64,10 +81,11 @@ boolean WEBServerManager::runServer() boolean WEBServerManager::parseQuery(WiFiClient *wifiClient) { char readChar(0), *parseBuffer(NULL); + boolean smallTimeout(false); _httpParserState = INIT; _clientTimeout = millis(); - while(wifiClient->available() || millis() - _clientTimeout < 150) + while(wifiClient->available() || millis() - _clientTimeout < (smallTimeout ? 100 : 5000)) { if(wifiClient->available()) { @@ -154,6 +172,7 @@ boolean WEBServerManager::parseQuery(WiFiClient *wifiClient) break; } _clientTimeout = millis(); + smallTimeout = true; } } @@ -300,12 +319,34 @@ boolean WEBServerManager::sendPageToClientFromSdCard(WiFiClient *wifiClient) 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) { //TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT if(strcmp(extension,"web") == 0) return TEXT_HTML; else if(strcmp(extension,"css") == 0) return TEXT_CSS; else if(strcmp(extension,"js") == 0) return TEXT_JAVASCRIPT; + else if(strcmp(extension,"png") == 0) return IMAGE_PNG; else return TEXT_PLAIN; } @@ -324,6 +365,9 @@ char *WEBServerManager::getHTTPHeader(HttpMIMEType httpMIMEType, unsigned long s 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); 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: sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","text/plain",size); break; diff --git a/src/app/WEBServerManager.h b/src/app/WEBServerManager.h index 6fd9916..23bcc93 100644 --- a/src/app/WEBServerManager.h +++ b/src/app/WEBServerManager.h @@ -5,22 +5,18 @@ #include #include "SDCardManager.h" #include "definition.h" +#include "Dictionary.h" + +struct HttpRequestData; 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, 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{ HttpRequestMethod HRM; HttpVersion HV; @@ -28,8 +24,26 @@ class WEBServerManager char *httpResource; 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 sendPageToClientFromSdCard(WiFiClient *wifiClient); + boolean sendPageToClientFromApiDictio(WiFiClient *wifiClient); char *addChar(char *pointer, const char character); HttpRequestMethod getHttpVerbEnumValue(const char *parseBuffer); HttpVersion getHttpVersionEnumValue(const char *parseBuffer); @@ -42,8 +56,8 @@ class WEBServerManager WiFiServer _wifiServer; WiFiClient _wifiClient;//One client only, maybe replaced with a fifo in the future SDCardManager *_sdCardManager; - HttpRequestData _httpRequestData; + Dictionary _apiDictionary; ClientStatus _clientState; HttpParserStatus _httpParserState;