Added new api functions, fixed a memory leak (file open, but not closed on failure), reworked the way data is read and sent, now using chunks, minor other fixes

This commit is contained in:
Anatole SCHRAMM 2019-04-04 17:58:13 +02:00
parent bd5afe4592
commit 8f2d2bcf48
6 changed files with 62 additions and 17 deletions

View File

@ -17,6 +17,7 @@ void *CFGFileParser::parseFile()
if(!file) if(!file)
{ {
delete dictioRef; delete dictioRef;
file.close();
return NULL; return NULL;
} }
@ -201,4 +202,3 @@ char *CFGFileParser::addChar(char *pointer, const char character)
return pointer; return pointer;
} }

View File

@ -137,18 +137,11 @@ boolean WEBServerManager::parseQuery(WiFiClient *wifiClient)
free(_httpRequestData.httpResource);_httpRequestData.httpResource = NULL; free(_httpRequestData.httpResource);_httpRequestData.httpResource = NULL;
_httpRequestData.httpResource = parseBuffer;parseBuffer = NULL; _httpRequestData.httpResource = parseBuffer;parseBuffer = NULL;
_httpParserState = HTTP_RESOURCE_PARAM_SECTION; _httpParserState = HTTP_RESOURCE_PARAM_SECTION;
} }
else if(readChar != ' ') else if(readChar == ' ')
{ {
//if(readChar != '/' && readChar != '\\') slashesOrantiSlashesOnly = false; free(_httpRequestData.httpResource);_httpRequestData.httpResource = NULL;
parseBuffer = addChar(parseBuffer, readChar);
_httpParserState = HTTP_RESOURCE_SECTION;
}
else
{
free(_httpRequestData.httpResource);_httpRequestData.httpResource = NULL;
if(slashesOrantiSlashesOnly) if(slashesOrantiSlashesOnly)
{ {
free(parseBuffer);parseBuffer = NULL; free(parseBuffer);parseBuffer = NULL;
@ -159,6 +152,13 @@ boolean WEBServerManager::parseQuery(WiFiClient *wifiClient)
_httpRequestData.httpResource = parseBuffer;parseBuffer = NULL; _httpRequestData.httpResource = parseBuffer;parseBuffer = NULL;
_httpParserState = HTTP_VER_SECTION; _httpParserState = HTTP_VER_SECTION;
}
else
{
if(readChar != '/' && readChar != '\\') slashesOrantiSlashesOnly = false;
parseBuffer = addChar(parseBuffer, readChar);
_httpParserState = HTTP_RESOURCE_SECTION;
} }
break; break;
case HTTP_RESOURCE_PARAM_SECTION: case HTTP_RESOURCE_PARAM_SECTION:
@ -291,7 +291,7 @@ boolean WEBServerManager::sendPageToClientFromSdCard(WiFiClient *wifiClient)
if(_sdCardManager != NULL) if(_sdCardManager != NULL)
{ {
File pageToSend; File pageToSend;
char readChar(0), *filePath(NULL), *header(NULL); char readChar(0), *filePath(NULL), *header(NULL), sendBuffer[2048];
//We check what kind of http verb it is //We check what kind of http verb it is
switch(_httpRequestData.HRM) switch(_httpRequestData.HRM)
@ -324,6 +324,7 @@ boolean WEBServerManager::sendPageToClientFromSdCard(WiFiClient *wifiClient)
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); 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); wifiClient->print(response);
free(response);response = NULL; free(response);response = NULL;
pageToSend.close();
return false; return false;
} }
@ -349,8 +350,13 @@ boolean WEBServerManager::sendPageToClientFromSdCard(WiFiClient *wifiClient)
while(pageToSend.available()) while(pageToSend.available())
{ {
readChar = (char) pageToSend.read();
if(wifiClient->write(sendBuffer, pageToSend.read(sendBuffer,2048)) == 0)
break;
/*readChar = (char) pageToSend.read();
wifiClient->write(readChar); wifiClient->write(readChar);
Serial.print(readChar);*/
} }
pageToSend.close(); pageToSend.close();
@ -397,7 +403,8 @@ WEBServerManager::HttpMIMEType WEBServerManager::getMIMETypeByExtension(const ch
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 if(strcmp(extension,"png") == 0) return IMAGE_PNG;
else return TEXT_PLAIN; else if(strcmp(extension, "mp3") == 0) return AUDIO_MPEG;
else return UNKNOWN_MIME;
} }
char *WEBServerManager::getHTTPHeader(HttpMIMEType httpMIMEType, unsigned long size) char *WEBServerManager::getHTTPHeader(HttpMIMEType httpMIMEType, unsigned long size)
@ -421,7 +428,15 @@ char *WEBServerManager::getHTTPHeader(HttpMIMEType httpMIMEType, unsigned long s
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;
case AUDIO_MPEG:
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","audio/mpeg",size);
break;
case APPLICATION_OCTET_STREAM:
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","application/octet-stream",size);
break;
default: default:
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","application/octet-stream",size);
break;
break; break;
} }

View File

@ -16,7 +16,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_RESOURCE_PARAM_SECTION, HTTP_VER_SECTION, PARAMETER_SECTION, BODY_SECTION, IGNORED, ERROR}; enum HttpParserStatus {INIT, LINE_BREAK, HTTP_VERB_SECTION, HTTP_RESOURCE_SECTION, HTTP_RESOURCE_PARAM_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, IMAGE_PNG}; enum HttpMIMEType{UNKNOWN_MIME, TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT, APPLICATION_JSON, APPLICATION_X_WWW_FORM_URLENCODED, IMAGE_PNG, AUDIO_MPEG, APPLICATION_OCTET_STREAM};
struct HttpRequestData{ struct HttpRequestData{
HttpRequestMethod HRM; HttpRequestMethod HRM;
HttpVersion HV; HttpVersion HV;

View File

@ -22,7 +22,10 @@ void setup()
CFGFileParser cfgFileParser(sab.getSdCardManager(), AP_CFG_FILE); CFGFileParser cfgFileParser(sab.getSdCardManager(), AP_CFG_FILE);
CFGDictionary<CFGParameterValue> *cfgDictionary = (CFGDictionary<CFGParameterValue> *) cfgFileParser.parseFile(); CFGDictionary<CFGParameterValue> *cfgDictionary = (CFGDictionary<CFGParameterValue> *) cfgFileParser.parseFile();
Serial.print("AP PASSWORD : ");if((*cfgDictionary)("PASSWORD") != NULL)Serial.println((*cfgDictionary)("PASSWORD")->stringValue()); if(cfgDictionary != NULL)
{
Serial.print("AP PASSWORD : ");if((*cfgDictionary)("PASSWORD") != NULL)Serial.println((*cfgDictionary)("PASSWORD")->stringValue());
}
delete cfgDictionary; delete cfgDictionary;
sab.getScreenManager().addView(&(view_1), &v1p, 0); sab.getScreenManager().addView(&(view_1), &v1p, 0);
@ -38,6 +41,8 @@ void setup()
sab.getWebServerManager().addApiRoutine("/helloServer", &(helloServerApi), NULL); sab.getWebServerManager().addApiRoutine("/helloServer", &(helloServerApi), NULL);
sab.getWebServerManager().addApiRoutine("/view/next", &(nextViewApi), &sab, WEBServerManager::GET); sab.getWebServerManager().addApiRoutine("/view/next", &(nextViewApi), &sab, WEBServerManager::GET);
sab.getWebServerManager().addApiRoutine("/rtc/get/time", &(rtcTimeApi), &sab, WEBServerManager::GET); sab.getWebServerManager().addApiRoutine("/rtc/get/time", &(rtcTimeApi), &sab, WEBServerManager::GET);
sab.getWebServerManager().addApiRoutine("/sdcard/eject", &(sdCardEjectApi), &sab, WEBServerManager::GET);
sab.getWebServerManager().addApiRoutine("/sdcard/insert", &(sdCardInsertApi), &sab, WEBServerManager::GET);
Serial.println("End setup"); Serial.println("End setup");
} }

View File

@ -27,3 +27,26 @@ boolean rtcTimeApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void
return true; return true;
} }
boolean sdCardEjectApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
{
SAB *p = (SAB *)pData;
char buffer[200];
p->getSdCardManager().end();
sprintf(buffer,"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{ \"status\" : \"ok\", \"card\" : \"ejected\" }");
wc->print(buffer);
return true;
}
boolean sdCardInsertApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
{
SAB *p = (SAB *)pData;
char buffer[200];
if(p->getSdCardManager().begin(p->getSdCardConfig().getSPISpeed(), p->getPinConfig().getSPI_sdCard_cs()))
sprintf(buffer,"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{ \"status\" : \"ok\", \"card\" : \"inserted\" }");
else
sprintf(buffer,"HTTP/1.1 500 OK\r\nContent-Type: application/json\r\n\r\n{ \"status\" : \"error\", \"message\" : \"begin failed\" }");
wc->print(buffer);
return true;
}

View File

@ -5,5 +5,7 @@
boolean helloServerApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*); boolean helloServerApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
boolean nextViewApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*); boolean nextViewApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
boolean rtcTimeApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*); boolean rtcTimeApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
boolean sdCardEjectApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
boolean sdCardInsertApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
#endif #endif