Added new private methods and updated server capabilities
This commit is contained in:
parent
6add78730d
commit
92b648fa67
@ -17,13 +17,13 @@ boolean WEBServerManager::runServer()
|
|||||||
if(_wifiClient)
|
if(_wifiClient)
|
||||||
{
|
{
|
||||||
_clientState = NEW;
|
_clientState = NEW;
|
||||||
_clientTimeout = millis();
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Serial.println("Client connected !!!");
|
Serial.println("Client connected !!!");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NEW:
|
case NEW:
|
||||||
|
_clientTimeout = millis();
|
||||||
_clientState = NOT_HANDLED;
|
_clientState = NOT_HANDLED;
|
||||||
break;
|
break;
|
||||||
case NOT_HANDLED:
|
case NOT_HANDLED:
|
||||||
@ -34,17 +34,21 @@ boolean WEBServerManager::runServer()
|
|||||||
Serial.println("Client timed out !!!");
|
Serial.println("Client timed out !!!");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
parseQuery(&_wifiClient);
|
parseQuery(&_wifiClient);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case QUERY_PARSED:
|
case QUERY_PARSED:
|
||||||
|
#ifdef DEBUG
|
||||||
|
Serial.println("Sending response !!!");
|
||||||
|
#endif
|
||||||
|
sendPageToClientFromSdCard(&_wifiClient);
|
||||||
_clientState = RESPONSE_SENT;
|
_clientState = RESPONSE_SENT;
|
||||||
break;
|
break;
|
||||||
case RESPONSE_SENT:
|
case RESPONSE_SENT:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Serial.println("Client handled !!!");
|
Serial.println("Client handled !!!");
|
||||||
#endif
|
#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;
|
_clientState = HANDLED;
|
||||||
break;
|
break;
|
||||||
case HANDLED:
|
case HANDLED:
|
||||||
@ -203,6 +207,151 @@ char *WEBServerManager::addChar(char *pointer, const char character)
|
|||||||
return pointer;
|
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)
|
WEBServerManager::HttpRequestMethod WEBServerManager::getHttpVerbEnumValue(const char *parseBuffer)
|
||||||
{
|
{
|
||||||
//UNDEFINED, GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH
|
//UNDEFINED, GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH
|
||||||
|
@ -19,6 +19,7 @@ class WEBServerManager
|
|||||||
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, BODY_SECTION, IGNORED, ERROR};
|
||||||
|
enum HttpMIMEType{TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT};
|
||||||
|
|
||||||
struct HttpRequestData{
|
struct HttpRequestData{
|
||||||
HttpRequestMethod HRM;
|
HttpRequestMethod HRM;
|
||||||
@ -27,9 +28,14 @@ class WEBServerManager
|
|||||||
char *httpBody;
|
char *httpBody;
|
||||||
};
|
};
|
||||||
boolean parseQuery(WiFiClient *wifiClient);
|
boolean parseQuery(WiFiClient *wifiClient);
|
||||||
|
boolean sendPageToClientFromSdCard(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);
|
||||||
|
char *getFilePathByHttpResource(const char *res);
|
||||||
|
char *getFileExtension(char *name);
|
||||||
|
HttpMIMEType getMIMETypeByExtension(const char *extension);
|
||||||
|
char *getHTTPHeader(HttpMIMEType httpMIMEType, unsigned long size);
|
||||||
|
|
||||||
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