Added new private methods and updated server capabilities

This commit is contained in:
anschrammh 2019-03-31 19:02:40 +02:00
parent 6add78730d
commit 92b648fa67
2 changed files with 158 additions and 3 deletions

View File

@ -17,13 +17,13 @@ boolean WEBServerManager::runServer()
if(_wifiClient)
{
_clientState = NEW;
_clientTimeout = millis();
#ifdef DEBUG
Serial.println("Client connected !!!");
#endif
}
break;
case NEW:
_clientTimeout = millis();
_clientState = NOT_HANDLED;
break;
case NOT_HANDLED:
@ -34,17 +34,21 @@ boolean WEBServerManager::runServer()
Serial.println("Client timed out !!!");
#endif
}
parseQuery(&_wifiClient);
break;
case QUERY_PARSED:
#ifdef DEBUG
Serial.println("Sending response !!!");
#endif
sendPageToClientFromSdCard(&_wifiClient);
_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:
@ -203,6 +207,151 @@ char *WEBServerManager::addChar(char *pointer, const char character)
return pointer;
}
boolean WEBServerManager::sendPageToClientFromSdCard(WiFiClient *wifiClient)
{
if(_sdCardManager != NULL)
{
File pageToSend;
char readChar(0), *filePath(NULL), *header(NULL);
//We check what kind of http verb it is
switch(_httpRequestData.HRM)
{
case GET:
filePath = getFilePathByHttpResource(_httpRequestData.httpResource);
if(filePath == NULL)
{
wifiClient->print(F("HTTP/1.1 500 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<p>Failed to malloc filePath</p>\r\n</html>"));
return false;
}
#ifdef DEBUG
Serial.print("FILE PATH : ");
Serial.println(filePath);
#endif
pageToSend = _sdCardManager->open(filePath);
free(filePath);filePath = NULL;
if(!pageToSend)
{
char *response(NULL);
response = (char *) malloc(sizeof(char) * (strlen("HTTP/1.1 404 Not Found\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Page not found for : </h1>\r\n<h4></h4>\r\n</html>") + strlen(_httpRequestData.httpResource) + 1));
if(response == NULL)
{
wifiClient->print(F("HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Failed to malloc filePath</h1>\r\n</html>"));
return false;
}
sprintf(response, "HTTP/1.1 404 Not Found\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Page not found for : </h1>\r\n<h4>%s</h4>\r\n</html>", _httpRequestData.httpResource);
wifiClient->print(response);
free(response);response = NULL;
return false;
}
#ifdef DEBUG
Serial.print("FILE SIZE : ");
Serial.println(pageToSend.size());
Serial.print("FILE NAME : ");
Serial.println(pageToSend.name());
Serial.print("FILE EXTENSION : ");
Serial.println(getFileExtension(pageToSend.name()));
#endif
header = getHTTPHeader(getMIMETypeByExtension(getFileExtension(pageToSend.name())), pageToSend.size());
if(header == NULL)
{
wifiClient->print(F("HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Failed to malloc filePath</h1>\r\n</html>"));
pageToSend.close();
return false;
}
wifiClient->print(header);
free(header);header = NULL;
while(pageToSend.available())
{
readChar = (char) pageToSend.read();
wifiClient->write(readChar);
}
pageToSend.close();
break;
default://If not supported
wifiClient->print(F("HTTP/1.1 405 Method Not Allowed\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Method Not Allowed</h1>\r\n</html>"));
break;
}
}else
{
//Test if it does correspond to a user defined API call
wifiClient->print(F("HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>SDCardManager is NULL<br \\>Check code</h1>\r\n</html>"));
}
return true;
}
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 return TEXT_PLAIN;
}
char *WEBServerManager::getHTTPHeader(HttpMIMEType httpMIMEType, unsigned long size)
{
char *header = (char *) malloc(sizeof(char) + strlen("HTTP/1.1 200 OK\r\nContent-Type: \r\nContent-Length: \r\n\r\n") + 74/*Longest MIME-TYPE*/ + 10 /*Max unsigned long footprint*/ + 1);
switch(httpMIMEType)
{
case TEXT_HTML:
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","text/html",size);
break;
case TEXT_CSS:
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","text/css",size);
break;
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 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;
default:
break;
}
return header;
}
char *WEBServerManager::getFileExtension(char *name)
{
if(name == NULL)return "";
char *ptr(name);
int index(0);
while(ptr[index] != '\0')
{
if(ptr[++index] == '.')
{
return (name + index +1);
}
}
return "";
}
char *WEBServerManager::getFilePathByHttpResource(const char *res)
{
char *filePath = (char*) malloc( sizeof(char) * (strlen(WWW_DIR)+ strlen(strcmp(res, "/") == 0 ? "/index.web":res) + 1) ); //Do not forget \0
if(filePath == NULL)
return NULL;
sprintf(filePath,"%s%s",WWW_DIR, strcmp(_httpRequestData.httpResource, "/") == 0 ? "/index.web":_httpRequestData.httpResource);
return filePath;
}
WEBServerManager::HttpRequestMethod WEBServerManager::getHttpVerbEnumValue(const char *parseBuffer)
{
//UNDEFINED, GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH

View File

@ -19,6 +19,7 @@ class WEBServerManager
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};
enum HttpMIMEType{TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT};
struct HttpRequestData{
HttpRequestMethod HRM;
@ -27,9 +28,14 @@ class WEBServerManager
char *httpBody;
};
boolean parseQuery(WiFiClient *wifiClient);
boolean sendPageToClientFromSdCard(WiFiClient *wifiClient);
char *addChar(char *pointer, const char character);
HttpRequestMethod getHttpVerbEnumValue(const char *parseBuffer);
HttpVersion getHttpVersionEnumValue(const char *parseBuffer);
char *getFilePathByHttpResource(const char *res);
char *getFileExtension(char *name);
HttpMIMEType getMIMETypeByExtension(const char *extension);
char *getHTTPHeader(HttpMIMEType httpMIMEType, unsigned long size);
WiFiServer _wifiServer;
WiFiClient _wifiClient;//One client only, maybe replaced with a fifo in the future