Compare commits
5 Commits
b1f137abf5
...
1db65be493
Author | SHA1 | Date | |
---|---|---|---|
|
1db65be493 | ||
|
e7cf2fa020 | ||
|
ef2f986581 | ||
|
e9625b909c | ||
|
28ad4c0342 |
@ -13,11 +13,12 @@ void *CFGFileParser::parseFile()
|
|||||||
CFGDictionary<CFGParameterValue> *dictioRef = new CFGDictionary<CFGParameterValue>;
|
CFGDictionary<CFGParameterValue> *dictioRef = new CFGDictionary<CFGParameterValue>;
|
||||||
char readChar(0), *parsedParameter(NULL), *parsedValue(NULL);
|
char readChar(0), *parsedParameter(NULL), *parsedValue(NULL);
|
||||||
|
|
||||||
|
if(!_sdCardManager.isMounted()) return NULL;
|
||||||
|
|
||||||
file = _sdCardManager.open(_resource);
|
file = _sdCardManager.open(_resource);
|
||||||
if(!file)
|
if(!file)
|
||||||
{
|
{
|
||||||
delete dictioRef;
|
delete dictioRef;
|
||||||
file.close();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,17 +168,18 @@ void *CFGFileParser::parseFile()
|
|||||||
|
|
||||||
boolean CFGFileParser::save(void *data)
|
boolean CFGFileParser::save(void *data)
|
||||||
{
|
{
|
||||||
if(data == NULL)
|
if(data == NULL) return false;
|
||||||
return false;
|
|
||||||
Dictionary<CFGParameterValue> *ref = (Dictionary<CFGParameterValue> *) data;
|
Dictionary<CFGParameterValue> *ref = (Dictionary<CFGParameterValue> *) data;
|
||||||
int truncateHere(0);
|
uint64_t truncateHere(0);
|
||||||
char readChar(0);
|
char readChar(0);
|
||||||
|
|
||||||
|
if(!_sdCardManager.isMounted()) return NULL;
|
||||||
|
|
||||||
File file = _sdCardManager.open(_resource, FILE_READWRITE);
|
File file = _sdCardManager.open(_resource, FILE_READWRITE);
|
||||||
|
|
||||||
if(!file)
|
if(!file)
|
||||||
{
|
{
|
||||||
file.close();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
#include "definition.h"
|
#include "definition.h"
|
||||||
#include "CFGParameterValue.h"
|
#include "CFGParameterValue.h"
|
||||||
|
|
||||||
|
//Forward class declaration because of cross includes...
|
||||||
|
class SDCardManager;
|
||||||
|
|
||||||
class CFGFileParser : public AbstractParser
|
class CFGFileParser : public AbstractParser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -4,6 +4,7 @@ CFGParameterValue::CFGParameterValue():DictionaryInterface(),_parameter(NULL), _
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CFGParameterValue::CFGParameterValue(const char *parameter, const char *value, boolean quotedParameter, boolean quotedValue):_quotedParameter(quotedParameter), _quotedValue(quotedValue)
|
CFGParameterValue::CFGParameterValue(const char *parameter, const char *value, boolean quotedParameter, boolean quotedValue):_quotedParameter(quotedParameter), _quotedValue(quotedValue)
|
||||||
{
|
{
|
||||||
_parameter = (char *) malloc((strlen(parameter) * sizeof(char)) + 1); //+1 for the string terminating character
|
_parameter = (char *) malloc((strlen(parameter) * sizeof(char)) + 1); //+1 for the string terminating character
|
||||||
@ -12,6 +13,7 @@ CFGParameterValue::CFGParameterValue(const char *parameter, const char *value, b
|
|||||||
strcpy(_parameter, parameter);
|
strcpy(_parameter, parameter);
|
||||||
strcpy(_value, value);
|
strcpy(_value, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFGParameterValue::CFGParameterValue(const char *parameter, const char *value):CFGParameterValue()
|
CFGParameterValue::CFGParameterValue(const char *parameter, const char *value):CFGParameterValue()
|
||||||
{
|
{
|
||||||
_parameter = (char *) malloc((strlen(parameter) * sizeof(char)) + 1); //+1 for the string terminating character
|
_parameter = (char *) malloc((strlen(parameter) * sizeof(char)) + 1); //+1 for the string terminating character
|
||||||
@ -20,6 +22,7 @@ CFGParameterValue::CFGParameterValue(const char *parameter, const char *value):C
|
|||||||
strcpy(_parameter, parameter);
|
strcpy(_parameter, parameter);
|
||||||
strcpy(_value, value);
|
strcpy(_value, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFGParameterValue::CFGParameterValue(const CFGParameterValue &Object)
|
CFGParameterValue::CFGParameterValue(const CFGParameterValue &Object)
|
||||||
{
|
{
|
||||||
_parameter = (char *) malloc((strlen(Object._parameter) * sizeof(char)) + 1); //+1 for the string terminating character
|
_parameter = (char *) malloc((strlen(Object._parameter) * sizeof(char)) + 1); //+1 for the string terminating character
|
||||||
@ -31,6 +34,7 @@ CFGParameterValue::CFGParameterValue(const CFGParameterValue &Object)
|
|||||||
_quotedParameter = Object._quotedParameter;
|
_quotedParameter = Object._quotedParameter;
|
||||||
_quotedValue = Object._quotedValue;
|
_quotedValue = Object._quotedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CFGParameterValue::~CFGParameterValue()
|
CFGParameterValue::~CFGParameterValue()
|
||||||
{
|
{
|
||||||
free(_parameter);
|
free(_parameter);
|
||||||
@ -38,3 +42,12 @@ CFGParameterValue::~CFGParameterValue()
|
|||||||
free(_value);
|
free(_value);
|
||||||
_value = NULL;
|
_value = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CFGParameterValue::setValue(const char *value, bool isQuoted)
|
||||||
|
{
|
||||||
|
_quotedValue = isQuoted;
|
||||||
|
|
||||||
|
free(_value);_value = NULL;
|
||||||
|
_value = (char *) malloc((strlen(value) * sizeof(char)) + 1); //+1 for the string terminating character
|
||||||
|
strcpy(_value, value);
|
||||||
|
}
|
||||||
|
@ -33,6 +33,7 @@ public:
|
|||||||
{
|
{
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
void setValue(const char *value, bool isQuoted);
|
||||||
protected:
|
protected:
|
||||||
private:
|
private:
|
||||||
char *_parameter;
|
char *_parameter;
|
||||||
|
@ -45,3 +45,8 @@ PowerManager::PowerInfo PowerManager::getPowerInfo(const uint16_t nbOfMeasures)
|
|||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PowerManager::setCpuFreq(uint8_t frequency)
|
||||||
|
{
|
||||||
|
return system_update_cpu_freq(frequency);
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include "definition.h"
|
#include "definition.h"
|
||||||
|
#include <user_interface.h>
|
||||||
|
|
||||||
class PowerManager
|
class PowerManager
|
||||||
{
|
{
|
||||||
@ -20,6 +21,7 @@ class PowerManager
|
|||||||
~PowerManager();
|
~PowerManager();
|
||||||
|
|
||||||
PowerManager::PowerInfo getPowerInfo(const uint16_t nbOfMeasures = 5) const;
|
PowerManager::PowerInfo getPowerInfo(const uint16_t nbOfMeasures = 5) const;
|
||||||
|
bool setCpuFreq(uint8_t frequency);
|
||||||
protected:
|
protected:
|
||||||
PowerManager();
|
PowerManager();
|
||||||
private:
|
private:
|
||||||
|
@ -54,3 +54,9 @@ boolean SDCardManager::isMounted()
|
|||||||
{
|
{
|
||||||
return _mounted;
|
return _mounted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CFGDictionary<CFGParameterValue> *SDCardManager::getCFGFile(const char *cfgFile)
|
||||||
|
{
|
||||||
|
CFGFileParser cfgFileParser(*this, cfgFile);
|
||||||
|
return (CFGDictionary<CFGParameterValue> *) cfgFileParser.parseFile();
|
||||||
|
}
|
||||||
|
@ -2,21 +2,29 @@
|
|||||||
#define SDCARDMANAGER_H
|
#define SDCARDMANAGER_H
|
||||||
#include <SD.h>
|
#include <SD.h>
|
||||||
#include "definition.h"
|
#include "definition.h"
|
||||||
|
#include "CFGDictionary.h"
|
||||||
|
#include "CFGParameterValue.h"
|
||||||
|
#include "CFGFileParser.h"
|
||||||
|
|
||||||
class SDCardManager : public SDClass
|
class SDCardManager : public SDClass
|
||||||
{
|
{
|
||||||
friend class SAB;
|
friend class SAB;
|
||||||
public:
|
public:
|
||||||
SDCardManager(const Pin csPin, SPISettings cfg);
|
SDCardManager(const Pin csPin, SPISettings cfg);
|
||||||
|
|
||||||
double getSize(const SizeUnit sizeUnit = GBYTE);
|
double getSize(const SizeUnit sizeUnit = GBYTE);
|
||||||
boolean mountSD();
|
boolean mountSD();
|
||||||
void unMountSD();
|
void unMountSD();
|
||||||
|
|
||||||
boolean isMounted();
|
boolean isMounted();
|
||||||
|
/*
|
||||||
|
* Quick way to retrieve the keys and values of a config file.
|
||||||
|
* If you need to performe other actions on the file, you will have to use the CFGFileParser object instead
|
||||||
|
* Remember to free the returned object ie : delete
|
||||||
|
*/
|
||||||
|
CFGDictionary<CFGParameterValue> *getCFGFile(const char *cfgFile);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SDCardManager();
|
SDCardManager();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Pin _csPin;
|
const Pin _csPin;
|
||||||
SPISettings _spiCfg;
|
SPISettings _spiCfg;
|
||||||
|
@ -14,7 +14,7 @@ class WEBServer : public TCPServer<T>
|
|||||||
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 HttpMIMEType{UNKNOWN_MIME, TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT, APPLICATION_JSON, APPLICATION_X_WWW_FORM_URLENCODED, IMAGE_PNG, IMAGE_JPEG, AUDIO_MPEG, APPLICATION_OCTET_STREAM};
|
enum HttpMIMEType{UNKNOWN_MIME, TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT, APPLICATION_JSON, APPLICATION_X_WWW_FORM_URLENCODED, IMAGE_PNG, IMAGE_JPEG, AUDIO_MPEG, APPLICATION_OCTET_STREAM};
|
||||||
enum HttpParserStatus {HTTP_VERB, HTTP_RESSOURCE, HTTP_VERSION, HTTP_PARAMS, POST_DATA};
|
enum HttpParserStatus {HTTP_VERB, HTTP_RESSOURCE, HTTP_VERSION, HTTP_PARAMS, POST_DATA, HEADER_PARAMS};
|
||||||
enum WEBClientState {ACCEPTED, QUERY_PARSED, RESPONSE_SENT, DONE};
|
enum WEBClientState {ACCEPTED, QUERY_PARSED, RESPONSE_SENT, DONE};
|
||||||
enum HTTP_CODE {_100, _101, _200, _400, _401, _403, _404, _405, _500, _501};
|
enum HTTP_CODE {_100, _101, _200, _400, _401, _403, _404, _405, _500, _501};
|
||||||
|
|
||||||
@ -48,6 +48,18 @@ class WEBServer : public TCPServer<T>
|
|||||||
{
|
{
|
||||||
return _apiDictionary.remove(uri);
|
return _apiDictionary.remove(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Helper function used for the webApi
|
||||||
|
static void injectApiHeader(char *header, const char *contentType, char *content)
|
||||||
|
{
|
||||||
|
char *buffer = (char *)malloc(sizeof(char) * strlen(content) + 1);
|
||||||
|
if(buffer != NULL)
|
||||||
|
{
|
||||||
|
strcpy(buffer, content);
|
||||||
|
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n%s",contentType,strlen(buffer), buffer);
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
protected:
|
protected:
|
||||||
private:
|
private:
|
||||||
virtual T* createNewClient(WiFiClient wc)
|
virtual T* createNewClient(WiFiClient wc)
|
||||||
@ -208,12 +220,12 @@ class WEBServer : public TCPServer<T>
|
|||||||
Serial.println((char *)client->_data);
|
Serial.println((char *)client->_data);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
client->_httpParserState = HttpParserStatus::POST_DATA;
|
client->_httpParserState = HttpParserStatus::HEADER_PARAMS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HttpParserStatus::HTTP_PARAMS: //index.htm?var1=1&var2=2...
|
case HttpParserStatus::HTTP_PARAMS: //index.htm?var1=1&var2=2...
|
||||||
if(!httpParamParser(client))
|
if(!httpRsrcParamParser(client))
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_WEBS
|
#ifdef DEBUG_WEBS
|
||||||
Serial.print("Resrc : ");Serial.println(client->_httpRequestData.httpResource);
|
Serial.print("Resrc : ");Serial.println(client->_httpRequestData.httpResource);
|
||||||
@ -226,9 +238,62 @@ class WEBServer : public TCPServer<T>
|
|||||||
client->_httpParserState = HttpParserStatus::HTTP_VERSION;
|
client->_httpParserState = HttpParserStatus::HTTP_VERSION;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case HttpParserStatus::HEADER_PARAMS: //Here we parse the different header params until we arrive to \r\n\r\n
|
||||||
|
{
|
||||||
|
char *pEndLine = strstr((char *)client->_data, "\r\n");
|
||||||
|
|
||||||
|
if( pEndLine != NULL )
|
||||||
|
{
|
||||||
|
*pEndLine = '\0';
|
||||||
|
|
||||||
|
httpHeaderParamParser(client);
|
||||||
|
|
||||||
|
if(*(pEndLine+2) == '\r') //We got \r\n\r\n -> so we go to the post data section
|
||||||
|
{
|
||||||
|
client->_httpParserState = HttpParserStatus::POST_DATA;
|
||||||
|
client->freeDataBuffer((pEndLine - (char *)client->_data) +3); //client->_data must not be empty...
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Before in the buffer : key1: value1\0\nkey2: value2
|
||||||
|
//After in the buffer : key2: value2\r\n
|
||||||
|
client->freeDataBuffer((pEndLine - (char *)client->_data) + 2);
|
||||||
|
}
|
||||||
|
else //Error : indeed, we should at least have : \r\n. We go to the next step anyway
|
||||||
|
{
|
||||||
|
client->_httpParserState = HttpParserStatus::POST_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case HttpParserStatus::POST_DATA:
|
case HttpParserStatus::POST_DATA:
|
||||||
|
|
||||||
|
switch(client->_httpRequestData.HMT)
|
||||||
|
{
|
||||||
|
case APPLICATION_X_WWW_FORM_URLENCODED:
|
||||||
|
#ifdef DEBUG_WEBS
|
||||||
|
Serial.printf("Post data : APPLICATION_X_WWW_FORM_URLENCODED\n");
|
||||||
|
Serial.printf("Post data : %s\n", client->_data);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//we parse it !
|
||||||
|
if(!httpPostParamParser(client))
|
||||||
|
{
|
||||||
|
//Parsing done!
|
||||||
|
#ifdef DEBUG_WEBS
|
||||||
|
Serial.println("Post params :");
|
||||||
|
for(int i = 0; i < client->_httpRequestData.postParams.count(); i++)
|
||||||
|
{
|
||||||
|
Serial.print(client->_httpRequestData.postParams.getParameter(i));Serial.print(" : ");Serial.println(client->_httpRequestData.postParams.getAt(i)->getString());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
client->_WEBClientState = WEBClientState::QUERY_PARSED;
|
client->_WEBClientState = WEBClientState::QUERY_PARSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
client->_WEBClientState = WEBClientState::QUERY_PARSED;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
sendInfoResponse(HTTP_CODE::_500, client, "WEB server error");
|
sendInfoResponse(HTTP_CODE::_500, client, "WEB server error");
|
||||||
@ -237,7 +302,44 @@ class WEBServer : public TCPServer<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean httpParamParser(T *client)
|
/*
|
||||||
|
* This function parses the header parameters in order to find particular parameters.
|
||||||
|
* For example we look for the "Content-Type" header or for the "Range: bytes=" header
|
||||||
|
*/
|
||||||
|
void httpHeaderParamParser(T *client)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_WEBS
|
||||||
|
Serial.printf("Header param : %s\n",(char *)client->_data);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Here we check if we have interesting params
|
||||||
|
char *contentTypeP = strstr((char *)client->_data, "t-Type: application/x-www-form-urlen");
|
||||||
|
|
||||||
|
if(contentTypeP != NULL)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_WEBS
|
||||||
|
Serial.printf("Data is of type : APPLICATION_X_WWW_FORM_URLENCODED\n");
|
||||||
|
#endif
|
||||||
|
client->_httpRequestData.HMT = APPLICATION_X_WWW_FORM_URLENCODED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Range part for file downloads
|
||||||
|
/*char *startingP = strstr((char *)client->_data, "nge: bytes="), *endP = strchr((char *)client->_data, '-');
|
||||||
|
|
||||||
|
if(startingP != NULL && endP != NULL)
|
||||||
|
{
|
||||||
|
endP = '\0';
|
||||||
|
client->_range = strtoul(startingP + 11,NULL, 10);
|
||||||
|
#ifdef DEBUG_WEBS
|
||||||
|
Serial.printf("Range : %d\n", client->_range);
|
||||||
|
#endif
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is here to parse resources parameters
|
||||||
|
*/
|
||||||
|
boolean httpRsrcParamParser(T *client)
|
||||||
{
|
{
|
||||||
char *pGetParam = strchr((char *)client->_httpRequestData.httpResource, '?');
|
char *pGetParam = strchr((char *)client->_httpRequestData.httpResource, '?');
|
||||||
|
|
||||||
@ -264,7 +366,7 @@ class WEBServer : public TCPServer<T>
|
|||||||
*value = '\0';
|
*value = '\0';
|
||||||
|
|
||||||
client->_httpRequestData.getParams.add(client->_httpRequestData.getParamsDataPointer, new DictionaryHelper::StringEntity(key > value ? NULL : key + 1));
|
client->_httpRequestData.getParams.add(client->_httpRequestData.getParamsDataPointer, new DictionaryHelper::StringEntity(key > value ? NULL : key + 1));
|
||||||
strcpy(client->_httpRequestData.getParamsDataPointer,value+1);
|
memmove(client->_httpRequestData.getParamsDataPointer, value+1, strlen(value+1)+1);
|
||||||
|
|
||||||
#ifdef DEBUG_WEBS
|
#ifdef DEBUG_WEBS
|
||||||
Serial.print("Params pointer : ");Serial.println(client->_httpRequestData.getParamsDataPointer);
|
Serial.print("Params pointer : ");Serial.println(client->_httpRequestData.getParamsDataPointer);
|
||||||
@ -283,13 +385,48 @@ class WEBServer : public TCPServer<T>
|
|||||||
*value = '\0';
|
*value = '\0';
|
||||||
|
|
||||||
client->_httpRequestData.getParams.add(client->_httpRequestData.getParamsDataPointer, new DictionaryHelper::StringEntity(NULL));
|
client->_httpRequestData.getParams.add(client->_httpRequestData.getParamsDataPointer, new DictionaryHelper::StringEntity(NULL));
|
||||||
strcpy(client->_httpRequestData.getParamsDataPointer,value+1);
|
memmove(client->_httpRequestData.getParamsDataPointer, value+1, strlen(value+1)+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //nothing to parse or done
|
else //nothing to parse or done
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean httpPostParamParser(T* client)
|
||||||
|
{
|
||||||
|
if(client->_httpRequestData.postParamsDataPointer == NULL)
|
||||||
|
{
|
||||||
|
client->_httpRequestData.postParamsDataPointer = (char *)client->_data + 1;//We save the starting position of the string to parse and we ignore the \n
|
||||||
|
}
|
||||||
|
|
||||||
|
char *key = strchr(client->_httpRequestData.postParamsDataPointer, '=');
|
||||||
|
char *value = strchr(client->_httpRequestData.postParamsDataPointer, '&');
|
||||||
|
|
||||||
|
if(key == NULL && value == NULL) //Nothing to parse or done
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(key != NULL && value == NULL) //Only one key is present
|
||||||
|
{
|
||||||
|
*key = '\0';
|
||||||
|
client->_httpRequestData.postParams.add(client->_httpRequestData.postParamsDataPointer, new DictionaryHelper::StringEntity(key+1));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(key != NULL && value != NULL)
|
||||||
|
{
|
||||||
|
*key = '\0';
|
||||||
|
*value = '\0';
|
||||||
|
client->_httpRequestData.postParams.add(client->_httpRequestData.postParamsDataPointer, new DictionaryHelper::StringEntity(key+1));
|
||||||
|
memmove(client->_httpRequestData.postParamsDataPointer, value +1, strlen(value+1) + 1);
|
||||||
|
}
|
||||||
|
else if(key == NULL && value != NULL)//Should never happen
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendDataToClient(T *client)
|
void sendDataToClient(T *client)
|
||||||
@ -387,7 +524,7 @@ class WEBServer : public TCPServer<T>
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(client->_fileSentBytes == 0)
|
if(client->_fileSentBytes == 0 /*&& client->_range == 0*/)
|
||||||
{
|
{
|
||||||
char *fileName = (char *) malloc(sizeof(char) * strlen(pageToSend.name()) + 1);
|
char *fileName = (char *) malloc(sizeof(char) * strlen(pageToSend.name()) + 1);
|
||||||
|
|
||||||
@ -411,6 +548,11 @@ class WEBServer : public TCPServer<T>
|
|||||||
client->_client.print(header);
|
client->_client.print(header);
|
||||||
free(header);header = NULL;
|
free(header);header = NULL;
|
||||||
}
|
}
|
||||||
|
/*else if(client->_fileSentBytes == 0 && (!client->_range == 0))
|
||||||
|
{
|
||||||
|
client->_fileSentBytes = client->_range-500;
|
||||||
|
Serial.println("RANGE SET");
|
||||||
|
}*/
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pageToSend.seek(client->_fileSentBytes);
|
pageToSend.seek(client->_fileSentBytes);
|
||||||
@ -438,6 +580,7 @@ class WEBServer : public TCPServer<T>
|
|||||||
break;
|
break;
|
||||||
default: //If not supported
|
default: //If not supported
|
||||||
sendInfoResponse(HTTP_CODE::_500, client, "The method used is not allowed");
|
sendInfoResponse(HTTP_CODE::_500, client, "The method used is not allowed");
|
||||||
|
return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
@ -449,7 +592,9 @@ class WEBServer : public TCPServer<T>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendInfoResponse(HTTP_CODE http_code, T *client, const char *message)
|
/*Static helper methods*/
|
||||||
|
|
||||||
|
static void sendInfoResponse(HTTP_CODE http_code, T *client, const char *message)
|
||||||
{
|
{
|
||||||
uint16_t code(0);
|
uint16_t code(0);
|
||||||
char codeLiteral[100];
|
char codeLiteral[100];
|
||||||
@ -457,39 +602,32 @@ class WEBServer : public TCPServer<T>
|
|||||||
{
|
{
|
||||||
case _400:
|
case _400:
|
||||||
code = 400;
|
code = 400;
|
||||||
strcpy_P(codeLiteral,(PGM_P)F("Bad Request"));
|
strcpy_P(codeLiteral,PSTR("Bad Request"));
|
||||||
break;
|
break;
|
||||||
case _404:
|
case _404:
|
||||||
code = 404;
|
code = 404;
|
||||||
strcpy_P(codeLiteral,(PGM_P)F("Not Found"));
|
strcpy_P(codeLiteral,PSTR("Not Found"));
|
||||||
break;
|
break;
|
||||||
case _403:
|
case _403:
|
||||||
code = 403;
|
code = 403;
|
||||||
strcpy_P(codeLiteral,(PGM_P)F("Forbidden"));
|
strcpy_P(codeLiteral,PSTR("Forbidden"));
|
||||||
break;
|
break;
|
||||||
case _405:
|
case _405:
|
||||||
code = 405;
|
code = 405;
|
||||||
strcpy_P(codeLiteral,(PGM_P)F("Method Not Allowed"));
|
strcpy_P(codeLiteral,PSTR("Method Not Allowed"));
|
||||||
break;
|
break;
|
||||||
case _500:
|
case _500:
|
||||||
code = 500;
|
code = 500;
|
||||||
strcpy_P(codeLiteral,(PGM_P)F("Internal Server Error"));
|
strcpy_P(codeLiteral,PSTR("Internal Server Error"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
code = 000;
|
code = 000;
|
||||||
strcpy_P(codeLiteral,(PGM_P)F("Error Not Defined"));
|
strcpy_P(codeLiteral,PSTR("Error Not Defined"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
client->_client.printf_P(PSTR("HTTP/1.1 %d %s\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Error %d</h1><p>%s</p>\r\n</html>"), code, codeLiteral, strlen(message) + 56 + (code != 0 ? 3:1), code , message);
|
||||||
client->_client.print(F("HTTP/1.1 "));client->_client.print(code);client->_client.print(F(" "));client->_client.print(codeLiteral);client->_client.print(F("\r\nContent-Type: text/html\r\nContent-Length: "));
|
|
||||||
client->_client.print(strlen(message) + 59);
|
|
||||||
client->_client.print(F("\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Error "));client->_client.print(code);client->_client.print(F("</h1><p>"));
|
|
||||||
client->_client.print(message);
|
|
||||||
client->_client.print(F("</p>\r\n</html>"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Static helper methods*/
|
|
||||||
|
|
||||||
static HttpRequestMethod getHttpVerbEnumValue(const char *parseBuffer)
|
static HttpRequestMethod getHttpVerbEnumValue(const char *parseBuffer)
|
||||||
{
|
{
|
||||||
if(parseBuffer == NULL)return HttpRequestMethod::UNDEFINED;
|
if(parseBuffer == NULL)return HttpRequestMethod::UNDEFINED;
|
||||||
@ -523,44 +661,49 @@ class WEBServer : public TCPServer<T>
|
|||||||
else return UNKNOWN_MIME;
|
else return UNKNOWN_MIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *getHTTPHeader(HttpMIMEType httpMIMEType, unsigned long size)
|
static char *getHTTPHeader(HttpMIMEType httpMIMEType, size_t 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);
|
char *header = (char *) malloc(sizeof(char) /*strlen("HTTP/1.1 200 OK\r\nContent-Type: \r\nContent-Length: \r\nCache-Control: max-age=31536000\r\n\r\n")*/* (86 + 74/*Longest MIME-TYPE*/ + 10 /*Max unsigned long footprint*/ + 1));
|
||||||
|
|
||||||
switch(httpMIMEType)
|
switch(httpMIMEType)
|
||||||
{
|
{
|
||||||
case TEXT_HTML:
|
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);
|
injectHeaderLayout(header,"text/html", size);
|
||||||
break;
|
break;
|
||||||
case TEXT_CSS:
|
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);
|
injectHeaderLayout(header,"text/css", size);
|
||||||
break;
|
break;
|
||||||
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);
|
injectHeaderLayout(header,"text/javascript", size);
|
||||||
break;
|
break;
|
||||||
case IMAGE_PNG:
|
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);
|
injectHeaderLayout(header,"image/png", size);
|
||||||
break;
|
break;
|
||||||
case IMAGE_JPEG:
|
case IMAGE_JPEG:
|
||||||
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","image/jpeg",size);
|
injectHeaderLayout(header,"image/jpeg", size);
|
||||||
break;
|
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);
|
injectHeaderLayout(header,"text/plain", size);
|
||||||
break;
|
break;
|
||||||
case AUDIO_MPEG:
|
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);
|
injectHeaderLayout(header,"audio/mpeg", size);
|
||||||
break;
|
break;
|
||||||
case APPLICATION_OCTET_STREAM:
|
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);
|
injectHeaderLayout(header,"application/octet-stream", size);
|
||||||
break;
|
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);
|
injectHeaderLayout(header,"application/octet-stream", size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void injectHeaderLayout(char *header, const char *contentType, size_t size)
|
||||||
|
{
|
||||||
|
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\nCache-Control: max-age=31536000\r\n\r\n",contentType,size);
|
||||||
|
}
|
||||||
|
|
||||||
static char *getFileExtension(char *name)
|
static char *getFileExtension(char *name)
|
||||||
{
|
{
|
||||||
char *p(lastIndexOf(name, '.'));
|
char *p(lastIndexOf(name, '.'));
|
||||||
|
Loading…
Reference in New Issue
Block a user