[DEV] HTTP start to be ok and websocket start to be implemented ...
This commit is contained in:
parent
97acf584f8
commit
83c9cf69b0
509
enet/Http.cpp
509
enet/Http.cpp
@ -11,6 +11,13 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static std::string escapeChar(const std::string& _value) {
|
||||
return _value;
|
||||
}
|
||||
static std::string unEscapeChar(const std::string& _value) {
|
||||
return _value;
|
||||
}
|
||||
|
||||
static std::map<enet::HTTPAnswerCode, std::string> protocolName = {
|
||||
{enet::HTTPAnswerCode::c100_continue, "Continue"},
|
||||
{enet::HTTPAnswerCode::c101_switchingProtocols, "Switching Protocols"},
|
||||
@ -69,12 +76,13 @@ enet::Http::Http(enet::Tcp _connection, bool _isServer) :
|
||||
m_connection(std::move(_connection)),
|
||||
m_headerIsSend(false),
|
||||
m_thread(nullptr),
|
||||
m_threadRunning(false),
|
||||
m_keepAlive(false) {
|
||||
setSendHeaderProperties("User-Agent", "e-net (ewol network interface)");
|
||||
m_threadRunning(false) {
|
||||
//setSendHeaderProperties("User-Agent", "e-net (ewol network interface)");
|
||||
/*
|
||||
if (m_keepAlive == true) {
|
||||
setSendHeaderProperties("Connection", "Keep-Alive");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
enet::Http::~Http() {
|
||||
@ -97,7 +105,7 @@ void enet::Http::threadCallback() {
|
||||
if (len > 0) {
|
||||
ENET_INFO("Call client with datas ...");
|
||||
if (m_observer != nullptr) {
|
||||
m_observer(*this, m_temporaryBuffer);
|
||||
m_observer(m_temporaryBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -144,25 +152,7 @@ void enet::Http::stop(bool _inThreadStop){
|
||||
}
|
||||
ENET_DEBUG("disconnect [STOP]");
|
||||
}
|
||||
|
||||
void enet::Http::setSendHeaderProperties(const std::string& _key, const std::string& _val) {
|
||||
auto it = m_header.m_map.find(_key);
|
||||
if (it == m_header.m_map.end()) {
|
||||
m_header.m_map.insert(make_pair(_key, _val));
|
||||
} else {
|
||||
it->second = _val;
|
||||
}
|
||||
}
|
||||
|
||||
std::string enet::Http::getSendHeaderProperties(const std::string& _key) {
|
||||
ENET_TODO("get header key=" << _key);
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string enet::Http::getReceiveHeaderProperties(const std::string& _key) {
|
||||
ENET_TODO("get header key=" << _key);
|
||||
return "";
|
||||
}
|
||||
/*
|
||||
void enet::Http::writeAnswerHeader(enum enet::HTTPAnswerCode _value) {
|
||||
std::string out;
|
||||
out = "HTTP/1.1 ";
|
||||
@ -177,6 +167,172 @@ void enet::Http::writeAnswerHeader(enum enet::HTTPAnswerCode _value) {
|
||||
ENET_WARNING("Write header :" << out);
|
||||
write(out, false);
|
||||
}
|
||||
*/
|
||||
namespace etk {
|
||||
template <>
|
||||
bool from_string<enum enet::HTTPAnswerCode>(enum enet::HTTPAnswerCode& _variableRet, const std::string& _value) {
|
||||
_variableRet = enet::HTTPAnswerCode::c000_unknow;
|
||||
for (auto &it : protocolName) {
|
||||
if (etk::to_string(int32_t(it.first)) == _value) {
|
||||
_variableRet = it.first;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
template <>
|
||||
std::string to_string<enum enet::HTTPAnswerCode>(const enum enet::HTTPAnswerCode& _value) {
|
||||
return etk::to_string(int32_t(_value));
|
||||
}
|
||||
template <>
|
||||
bool from_string<enum enet::HTTPReqType>(enum enet::HTTPReqType& _variableRet, const std::string& _value) {
|
||||
_variableRet = enet::HTTPReqType::GET;
|
||||
if (_value == "GET") {
|
||||
_variableRet = enet::HTTPReqType::GET;
|
||||
return true;
|
||||
} else if (_value == "HEAD") {
|
||||
_variableRet = enet::HTTPReqType::HEAD;
|
||||
return true;
|
||||
} else if (_value == "POST") {
|
||||
_variableRet = enet::HTTPReqType::POST;
|
||||
return true;
|
||||
} else if (_value == "PUT") {
|
||||
_variableRet = enet::HTTPReqType::PUT;
|
||||
return true;
|
||||
} else if (_value == "DELETE") {
|
||||
_variableRet = enet::HTTPReqType::DELETE;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
template <>
|
||||
std::string to_string<enum enet::HTTPReqType>(const enum enet::HTTPReqType& _value) {
|
||||
switch (_value) {
|
||||
case enet::HTTPReqType::GET: return "GET";
|
||||
case enet::HTTPReqType::HEAD: return "HEAD";
|
||||
case enet::HTTPReqType::POST: return "POST";
|
||||
case enet::HTTPReqType::PUT: return "PUT";
|
||||
case enet::HTTPReqType::DELETE: return "DELETE";
|
||||
}
|
||||
return "UNKNOW";
|
||||
}
|
||||
template <>
|
||||
bool from_string<enum enet::HTTPProtocol>(enum enet::HTTPProtocol& _variableRet, const std::string& _value) {
|
||||
_variableRet = enet::HTTPProtocol::http_0_1;
|
||||
if (_value == "HTTP/0.1") { _variableRet = enet::HTTPProtocol::http_0_1; return true; }
|
||||
if (_value == "HTTP/0.2") { _variableRet = enet::HTTPProtocol::http_0_2; return true; }
|
||||
if (_value == "HTTP/0.3") { _variableRet = enet::HTTPProtocol::http_0_3; return true; }
|
||||
if (_value == "HTTP/0.4") { _variableRet = enet::HTTPProtocol::http_0_4; return true; }
|
||||
if (_value == "HTTP/0.5") { _variableRet = enet::HTTPProtocol::http_0_5; return true; }
|
||||
if (_value == "HTTP/0.6") { _variableRet = enet::HTTPProtocol::http_0_6; return true; }
|
||||
if (_value == "HTTP/0.7") { _variableRet = enet::HTTPProtocol::http_0_7; return true; }
|
||||
if (_value == "HTTP/0.8") { _variableRet = enet::HTTPProtocol::http_0_8; return true; }
|
||||
if (_value == "HTTP/0.9") { _variableRet = enet::HTTPProtocol::http_0_9; return true; }
|
||||
if (_value == "HTTP/0.10") { _variableRet = enet::HTTPProtocol::http_0_10; return true; }
|
||||
if (_value == "HTTP/1.0") { _variableRet = enet::HTTPProtocol::http_1_0; return true; }
|
||||
if (_value == "HTTP/1.1") { _variableRet = enet::HTTPProtocol::http_1_1; return true; }
|
||||
if (_value == "HTTP/1.2") { _variableRet = enet::HTTPProtocol::http_1_2; return true; }
|
||||
if (_value == "HTTP/1.3") { _variableRet = enet::HTTPProtocol::http_1_3; return true; }
|
||||
if (_value == "HTTP/1.4") { _variableRet = enet::HTTPProtocol::http_1_4; return true; }
|
||||
if (_value == "HTTP/1.5") { _variableRet = enet::HTTPProtocol::http_1_5; return true; }
|
||||
if (_value == "HTTP/1.6") { _variableRet = enet::HTTPProtocol::http_1_6; return true; }
|
||||
if (_value == "HTTP/1.7") { _variableRet = enet::HTTPProtocol::http_1_7; return true; }
|
||||
if (_value == "HTTP/1.8") { _variableRet = enet::HTTPProtocol::http_1_8; return true; }
|
||||
if (_value == "HTTP/1.9") { _variableRet = enet::HTTPProtocol::http_1_9; return true; }
|
||||
if (_value == "HTTP/1.10") { _variableRet = enet::HTTPProtocol::http_1_10; return true; }
|
||||
if (_value == "HTTP/2.0") { _variableRet = enet::HTTPProtocol::http_2_0; return true; }
|
||||
if (_value == "HTTP/2.1") { _variableRet = enet::HTTPProtocol::http_2_1; return true; }
|
||||
if (_value == "HTTP/2.2") { _variableRet = enet::HTTPProtocol::http_2_2; return true; }
|
||||
if (_value == "HTTP/2.3") { _variableRet = enet::HTTPProtocol::http_2_3; return true; }
|
||||
if (_value == "HTTP/2.4") { _variableRet = enet::HTTPProtocol::http_2_4; return true; }
|
||||
if (_value == "HTTP/2.5") { _variableRet = enet::HTTPProtocol::http_2_5; return true; }
|
||||
if (_value == "HTTP/2.6") { _variableRet = enet::HTTPProtocol::http_2_6; return true; }
|
||||
if (_value == "HTTP/2.7") { _variableRet = enet::HTTPProtocol::http_2_7; return true; }
|
||||
if (_value == "HTTP/2.8") { _variableRet = enet::HTTPProtocol::http_2_8; return true; }
|
||||
if (_value == "HTTP/2.9") { _variableRet = enet::HTTPProtocol::http_2_9; return true; }
|
||||
if (_value == "HTTP/2.10") { _variableRet = enet::HTTPProtocol::http_2_10; return true; }
|
||||
if (_value == "HTTP/3.0") { _variableRet = enet::HTTPProtocol::http_3_0; return true; }
|
||||
if (_value == "HTTP/3.1") { _variableRet = enet::HTTPProtocol::http_3_1; return true; }
|
||||
if (_value == "HTTP/3.2") { _variableRet = enet::HTTPProtocol::http_3_2; return true; }
|
||||
if (_value == "HTTP/3.3") { _variableRet = enet::HTTPProtocol::http_3_3; return true; }
|
||||
if (_value == "HTTP/3.4") { _variableRet = enet::HTTPProtocol::http_3_4; return true; }
|
||||
if (_value == "HTTP/3.5") { _variableRet = enet::HTTPProtocol::http_3_5; return true; }
|
||||
if (_value == "HTTP/3.6") { _variableRet = enet::HTTPProtocol::http_3_6; return true; }
|
||||
if (_value == "HTTP/3.7") { _variableRet = enet::HTTPProtocol::http_3_7; return true; }
|
||||
if (_value == "HTTP/3.8") { _variableRet = enet::HTTPProtocol::http_3_8; return true; }
|
||||
if (_value == "HTTP/3.9") { _variableRet = enet::HTTPProtocol::http_3_9; return true; }
|
||||
if (_value == "HTTP/3.10") { _variableRet = enet::HTTPProtocol::http_3_10; return true; }
|
||||
return false;
|
||||
}
|
||||
template <>
|
||||
std::string to_string<enum enet::HTTPProtocol>(const enum enet::HTTPProtocol& _value) {
|
||||
switch (_value) {
|
||||
case enet::HTTPProtocol::http_0_1: return "HTTP/0.1";
|
||||
case enet::HTTPProtocol::http_0_2: return "HTTP/0.2";
|
||||
case enet::HTTPProtocol::http_0_3: return "HTTP/0.3";
|
||||
case enet::HTTPProtocol::http_0_4: return "HTTP/0.4";
|
||||
case enet::HTTPProtocol::http_0_5: return "HTTP/0.5";
|
||||
case enet::HTTPProtocol::http_0_6: return "HTTP/0.6";
|
||||
case enet::HTTPProtocol::http_0_7: return "HTTP/0.7";
|
||||
case enet::HTTPProtocol::http_0_8: return "HTTP/0.8";
|
||||
case enet::HTTPProtocol::http_0_9: return "HTTP/0.9";
|
||||
case enet::HTTPProtocol::http_0_10: return "HTTP/0.10";
|
||||
case enet::HTTPProtocol::http_1_0: return "HTTP/1.0";
|
||||
case enet::HTTPProtocol::http_1_1: return "HTTP/1.1";
|
||||
case enet::HTTPProtocol::http_1_2: return "HTTP/1.2";
|
||||
case enet::HTTPProtocol::http_1_3: return "HTTP/1.3";
|
||||
case enet::HTTPProtocol::http_1_4: return "HTTP/1.4";
|
||||
case enet::HTTPProtocol::http_1_5: return "HTTP/1.5";
|
||||
case enet::HTTPProtocol::http_1_6: return "HTTP/1.6";
|
||||
case enet::HTTPProtocol::http_1_7: return "HTTP/1.7";
|
||||
case enet::HTTPProtocol::http_1_8: return "HTTP/1.8";
|
||||
case enet::HTTPProtocol::http_1_9: return "HTTP/1.9";
|
||||
case enet::HTTPProtocol::http_1_10: return "HTTP/1.10";
|
||||
case enet::HTTPProtocol::http_2_0: return "HTTP/2.0";
|
||||
case enet::HTTPProtocol::http_2_1: return "HTTP/2.1";
|
||||
case enet::HTTPProtocol::http_2_2: return "HTTP/2.2";
|
||||
case enet::HTTPProtocol::http_2_3: return "HTTP/2.3";
|
||||
case enet::HTTPProtocol::http_2_4: return "HTTP/2.4";
|
||||
case enet::HTTPProtocol::http_2_5: return "HTTP/2.5";
|
||||
case enet::HTTPProtocol::http_2_6: return "HTTP/2.6";
|
||||
case enet::HTTPProtocol::http_2_7: return "HTTP/2.7";
|
||||
case enet::HTTPProtocol::http_2_8: return "HTTP/2.8";
|
||||
case enet::HTTPProtocol::http_2_9: return "HTTP/2.9";
|
||||
case enet::HTTPProtocol::http_2_10: return "HTTP/2.10";
|
||||
case enet::HTTPProtocol::http_3_0: return "HTTP/3.0";
|
||||
case enet::HTTPProtocol::http_3_1: return "HTTP/3.1";
|
||||
case enet::HTTPProtocol::http_3_2: return "HTTP/3.2";
|
||||
case enet::HTTPProtocol::http_3_3: return "HTTP/3.3";
|
||||
case enet::HTTPProtocol::http_3_4: return "HTTP/3.4";
|
||||
case enet::HTTPProtocol::http_3_5: return "HTTP/3.5";
|
||||
case enet::HTTPProtocol::http_3_6: return "HTTP/3.6";
|
||||
case enet::HTTPProtocol::http_3_7: return "HTTP/3.7";
|
||||
case enet::HTTPProtocol::http_3_8: return "HTTP/3.8";
|
||||
case enet::HTTPProtocol::http_3_9: return "HTTP/3.9";
|
||||
case enet::HTTPProtocol::http_3_10: return "HTTP/3.10";
|
||||
}
|
||||
return "HTTP/0.1";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void enet::Http::setRequestHeader(const enet::HttpRequest& _req) {
|
||||
m_requestHeader = _req;
|
||||
if (m_requestHeader.getKey("User-Agent") == "") {
|
||||
m_requestHeader.setKey("User-Agent", "e-net (ewol network interface)");
|
||||
}
|
||||
std::string value = m_requestHeader.generate();
|
||||
write(value, false);
|
||||
}
|
||||
|
||||
void enet::Http::setAnswerHeader(const enet::HttpAnswer& _req) {
|
||||
m_answerHeader = _req;
|
||||
if (m_requestHeader.getKey("User-Agent") == "") {
|
||||
m_requestHeader.setKey("User-Agent", "e-net (ewol network interface)");
|
||||
}
|
||||
std::string value = m_answerHeader.generate();
|
||||
write(value, false);
|
||||
}
|
||||
|
||||
void enet::Http::getHeader() {
|
||||
ENET_VERBOSE("Read HTTP Header [START]");
|
||||
@ -219,41 +375,113 @@ void enet::Http::getHeader() {
|
||||
it.resize(it.size()-1);
|
||||
}
|
||||
}
|
||||
headerEnded = false;
|
||||
m_header.m_map.clear();
|
||||
for (auto element : list) {
|
||||
if (headerEnded == false) {
|
||||
headerEnded = true;
|
||||
m_header.setReq(element);
|
||||
//parse first element:
|
||||
std::vector<std::string> listLineOne = etk::split(list[0], ' ');
|
||||
if (listLineOne.size() < 2) {
|
||||
ENET_ERROR("can not parse answear : " << listLineOne);
|
||||
// answer bad request and close connection ...
|
||||
|
||||
return;
|
||||
}
|
||||
if ( listLineOne.size() >= 3
|
||||
&& ( listLineOne[0] == "GET"
|
||||
|| listLineOne[0] == "POST"
|
||||
|| listLineOne[0] == "HEAD"
|
||||
|| listLineOne[0] == "DELETE"
|
||||
|| listLineOne[0] == "PUT" ) ) {
|
||||
// HTTP CALL
|
||||
if (m_isServer == false) {
|
||||
// can not have call in client mode
|
||||
ENET_ERROR("can not parse call in client mode ..." << listLineOne);
|
||||
m_answerHeader.setErrorCode(enet::HTTPAnswerCode::c400_badRequest);
|
||||
m_answerHeader.setHelp("Call a client with a request from server ...");
|
||||
setAnswerHeader(m_answerHeader);
|
||||
stop(true);
|
||||
return;
|
||||
}
|
||||
// get type call:
|
||||
enum enet::HTTPReqType valueType;
|
||||
etk::from_string(valueType, listLineOne[0]);
|
||||
m_requestHeader.setType(valueType);
|
||||
// get URI:
|
||||
m_requestHeader.setUri(listLineOne[1]);
|
||||
// Get http version:
|
||||
enum enet::HTTPProtocol valueProtocol;
|
||||
etk::from_string(valueProtocol, listLineOne[2]);
|
||||
m_requestHeader.setProtocol(valueProtocol);
|
||||
} else if ( listLineOne.size() >= 3
|
||||
&& etk::start_with(listLineOne[0],"HTTP/") == true) {
|
||||
// HTTP answer
|
||||
if (m_isServer == true) {
|
||||
// can not have anser ==> need to be a get ot something like this ...
|
||||
ENET_ERROR("can not parse answer in server mode ..." << listLineOne);
|
||||
m_answerHeader.setErrorCode(enet::HTTPAnswerCode::c400_badRequest);
|
||||
m_answerHeader.setHelp("Call a client with a request from server ...");
|
||||
setAnswerHeader(m_answerHeader);
|
||||
stop(true);
|
||||
return;
|
||||
}
|
||||
// Get http version:
|
||||
enum enet::HTTPProtocol valueProtocol;
|
||||
etk::from_string(valueProtocol, listLineOne[0]);
|
||||
m_answerHeader.setProtocol(valueProtocol);
|
||||
|
||||
enum HTTPAnswerCode valueErrorCode;
|
||||
etk::from_string(valueErrorCode, listLineOne[1]);
|
||||
m_answerHeader.setErrorCode(valueErrorCode);
|
||||
|
||||
// get comment:
|
||||
std::string comment;
|
||||
for (size_t iii=2; iii<listLineOne.size(); ++iii) {
|
||||
if (comment.size() != 0) {
|
||||
comment += " ";
|
||||
}
|
||||
comment += listLineOne[iii];
|
||||
}
|
||||
m_answerHeader.setHelp(comment);
|
||||
} else {
|
||||
size_t found = element.find(":");
|
||||
// can not have anser ==> need to be a get ot something like this ...
|
||||
ENET_ERROR("Un understand message ..." << listLineOne);
|
||||
m_answerHeader.setErrorCode(enet::HTTPAnswerCode::c400_badRequest);
|
||||
m_answerHeader.setHelp("Un understand message ...");
|
||||
setAnswerHeader(m_answerHeader);
|
||||
stop(true);
|
||||
return;
|
||||
}
|
||||
for (size_t iii=1; iii<list.size(); ++iii) {
|
||||
size_t found = list[iii].find(":");
|
||||
if (found == std::string::npos) {
|
||||
// nothing
|
||||
continue;
|
||||
}
|
||||
ENET_VERBOSE("header : key='" << std::string(element, 0, found) << "' value='" << std::string(element, found+2) << "'");
|
||||
m_header.m_map.insert(make_pair(unEscapeChar(std::string(element, 0, found)), unEscapeChar(std::string(element, found+2))));
|
||||
std::string key = unEscapeChar(std::string(list[iii], 0, found));
|
||||
std::string value = unEscapeChar(std::string(list[iii], found+2));
|
||||
ENET_VERBOSE("header : key='" << key << "' value='" << value << "'");
|
||||
if (m_isServer == false) {
|
||||
m_answerHeader.setKey(key,value);
|
||||
} else {
|
||||
m_requestHeader.setKey(key,value);
|
||||
}
|
||||
}
|
||||
for (auto &it : m_header.m_map) {
|
||||
if (it.first == "Connection") {
|
||||
if (it.second == "close") {
|
||||
if ( key == "Connection"
|
||||
&& value == "close") {
|
||||
ENET_DEBUG("connection closed by remote :");
|
||||
m_connection.unlink();
|
||||
}
|
||||
}
|
||||
if (m_isServer == false) {
|
||||
if (m_observerAnswer != nullptr) {
|
||||
m_observerAnswer(m_answerHeader);
|
||||
}
|
||||
} else {
|
||||
ENET_TODO("manage connection type : '" << it.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_header.display();
|
||||
if (m_observerRequest != nullptr) {
|
||||
m_observerRequest(*this, m_header);
|
||||
m_observerRequest(m_requestHeader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
bool enet::Http::get(const std::string& _address) {
|
||||
m_receiveData.clear();
|
||||
m_header.m_map.clear();
|
||||
std::string req = "GET http://" + m_connection.getName();
|
||||
if (_address != "") {
|
||||
@ -280,15 +508,7 @@ bool enet::Http::get(const std::string& _address) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string enet::Http::escapeChar(const std::string& _value) {
|
||||
return _value;
|
||||
}
|
||||
std::string enet::Http::unEscapeChar(const std::string& _value) {
|
||||
return _value;
|
||||
}
|
||||
|
||||
bool enet::Http::post(const std::string& _address, const std::map<std::string, std::string>& _values) {
|
||||
m_receiveData.clear();
|
||||
m_header.m_map.clear();
|
||||
// First create body :
|
||||
std::string body;
|
||||
@ -302,7 +522,6 @@ bool enet::Http::post(const std::string& _address, const std::map<std::string, s
|
||||
}
|
||||
|
||||
bool enet::Http::post(const std::string& _address, const std::string& _contentType, const std::string& _data) {
|
||||
m_receiveData.clear();
|
||||
m_header.m_map.clear();
|
||||
std::string req = "POST http://" + m_connection.getName();
|
||||
if (_address != "") {
|
||||
@ -329,68 +548,154 @@ bool enet::Http::post(const std::string& _address, const std::string& _contentTy
|
||||
//return receiveData();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
std::string enet::Http::dataString() {
|
||||
std::string data;
|
||||
for (auto element : m_receiveData) {
|
||||
if (element == '\0') {
|
||||
return data;
|
||||
}
|
||||
data += element;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
*/
|
||||
|
||||
int32_t enet::Http::write(const void* _data, int32_t _len) {
|
||||
return m_connection.write(_data, _len);
|
||||
}
|
||||
|
||||
void enet::HttpHeader::setReq(const std::string& _req) {
|
||||
// parse base answear:
|
||||
std::vector<std::string> list = etk::split(_req, ' ');
|
||||
if (list.size() < 2) {
|
||||
ENET_ERROR("can not parse answear : " << list);
|
||||
return;
|
||||
}
|
||||
m_req = list[0];
|
||||
m_what = list[1];
|
||||
if ( m_req == "GET"
|
||||
|| m_req == "POST") {
|
||||
// HTTP CALL
|
||||
|
||||
} else if (etk::start_with(m_req,"HTTP/")==true) {
|
||||
// HTTP answer
|
||||
int32_t ret = etk::string_to_int32_t(m_what);
|
||||
switch (ret/100) {
|
||||
case 1:
|
||||
// information message
|
||||
break;
|
||||
case 2:
|
||||
// OK
|
||||
break;
|
||||
case 3:
|
||||
// Redirect
|
||||
ENET_WARNING("Rediret request");
|
||||
break;
|
||||
case 4:
|
||||
// client Error
|
||||
ENET_WARNING("Client error");
|
||||
break;
|
||||
case 5:
|
||||
// server error
|
||||
ENET_WARNING("Server error");
|
||||
break;
|
||||
}
|
||||
void enet::HttpHeader::setKey(const std::string& _key, const std::string& _value) {
|
||||
auto it = m_map.find(_key);
|
||||
if (it == m_map.end()) {
|
||||
m_map.insert(make_pair(_key, _value));
|
||||
} else {
|
||||
it->second = _value;
|
||||
}
|
||||
}
|
||||
|
||||
void enet::HttpHeader::rmKey(const std::string& _key) {
|
||||
auto it = m_map.find(_key);
|
||||
if (it != m_map.end()) {
|
||||
m_map.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void enet::HttpHeader::display() const {
|
||||
ENET_INFO("header :");
|
||||
std::string enet::HttpHeader::getKey(const std::string& _key) const {
|
||||
auto it = m_map.find(_key);
|
||||
if (it != m_map.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string enet::HttpHeader::generateKeys() const {
|
||||
std::string out;
|
||||
for (auto &it : m_map) {
|
||||
ENET_INFO(" key='" << it.first << "' value='" << it.second << "'");
|
||||
if ( it.first != ""
|
||||
&& it.second != "") {
|
||||
out += escapeChar(it.first) + " : " + escapeChar(it.second) + "\r\n";
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
enet::HttpHeader::HttpHeader():
|
||||
m_protocol(enet::HTTPProtocol::http_1_0) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
enet::HttpAnswer::HttpAnswer(enum HTTPAnswerCode _code, const std::string& _help):
|
||||
m_what(_code),
|
||||
m_helpMessage(_help) {
|
||||
|
||||
}
|
||||
|
||||
void enet::HttpAnswer::display() const {
|
||||
ENET_PRINT("display header 'Answer' ");
|
||||
ENET_PRINT(" protocol=" << m_protocol);
|
||||
ENET_PRINT(" Code=" << int32_t(m_what));
|
||||
ENET_PRINT(" message=" << m_helpMessage);
|
||||
ENET_PRINT(" Options:");
|
||||
for (auto &it : m_map) {
|
||||
if ( it.first != ""
|
||||
&& it.second != "") {
|
||||
ENET_PRINT(" '" + it.first + "' = '" + it.second + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string enet::HttpAnswer::generate() const {
|
||||
std::string out;
|
||||
out += etk::to_string(m_protocol);
|
||||
out += " ";
|
||||
out += etk::to_string(int32_t(m_what));
|
||||
out += " ";
|
||||
if (m_helpMessage != "") {
|
||||
out += escapeChar(m_helpMessage);
|
||||
} else {
|
||||
auto it = protocolName.find(m_what);
|
||||
if (it != protocolName.end()) {
|
||||
out += escapeChar(it->second);
|
||||
} else {
|
||||
out += "???";
|
||||
}
|
||||
}
|
||||
out += "\r\n";
|
||||
out += generateKeys();
|
||||
out += "\r\n\r\n";
|
||||
return out;
|
||||
}
|
||||
enet::HttpServer::HttpServer(enet::Tcp _connection) :
|
||||
enet::Http(std::move(_connection), true) {
|
||||
|
||||
}
|
||||
|
||||
enet::HttpClient::HttpClient(enet::Tcp _connection) :
|
||||
enet::Http(std::move(_connection), false) {
|
||||
|
||||
}
|
||||
// -----------------------------------------------------------------------------------------
|
||||
|
||||
enet::HttpRequest::HttpRequest(enum enet::HTTPReqType _type):
|
||||
m_req(_type),
|
||||
m_uri() {
|
||||
|
||||
}
|
||||
|
||||
void enet::HttpRequest::display() const {
|
||||
ENET_PRINT("display header 'Request' ");
|
||||
ENET_PRINT(" type=" << m_req);
|
||||
ENET_PRINT(" protocol=" << m_protocol);
|
||||
ENET_PRINT(" uri=" << m_uri);
|
||||
ENET_PRINT(" Options:");
|
||||
for (auto &it : m_map) {
|
||||
if ( it.first != ""
|
||||
&& it.second != "") {
|
||||
ENET_PRINT(" '" + it.first + "' = '" + it.second + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string enet::HttpRequest::generate() const {
|
||||
std::string out;
|
||||
out += etk::to_string(m_req);
|
||||
out += " ";
|
||||
out += m_uri;
|
||||
out += " ";
|
||||
out += etk::to_string(m_protocol);
|
||||
out += "\r\n";
|
||||
out += generateKeys();
|
||||
out += "\r\n\r\n";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& enet::operator <<(std::ostream& _os, enum enet::HTTPProtocol _obj) {
|
||||
_os << "enet::HTTPProtocol::" <<etk::to_string(_obj);
|
||||
return _os;
|
||||
}
|
||||
|
||||
std::ostream& enet::operator <<(std::ostream& _os, enum enet::HTTPAnswerCode _obj) {
|
||||
_os << "enet::HTTPAnswerCode::" << etk::to_string(_obj);
|
||||
return _os;
|
||||
}
|
||||
|
||||
std::ostream& enet::operator <<(std::ostream& _os, enum enet::HTTPReqType _obj) {
|
||||
_os << "enet::HTTPReqType::" << etk::to_string(_obj);
|
||||
return _os;
|
||||
}
|
228
enet/Http.h
228
enet/Http.h
@ -13,6 +13,7 @@
|
||||
|
||||
namespace enet {
|
||||
enum class HTTPAnswerCode {
|
||||
c000_unknow = 0,
|
||||
//1xx: Information
|
||||
c100_continue = 100, //!< The server has received the request headers, and the client should proceed to send the request body
|
||||
c101_switchingProtocols, //!< The requester has asked the server to switch protocols
|
||||
@ -62,40 +63,97 @@ namespace enet {
|
||||
c505_httpVersionNotSupported, //!< The server does not support the HTTP protocol version used in the request
|
||||
c511_networkAuthenticationRequired, //!< The client needs to authenticate to gain network access
|
||||
};
|
||||
std::ostream& operator <<(std::ostream& _os, enum enet::HTTPAnswerCode _obj);
|
||||
|
||||
enum class HTTPProtocol {
|
||||
http_0_1,
|
||||
http_0_2,
|
||||
http_0_3,
|
||||
http_0_4,
|
||||
http_0_5,
|
||||
http_0_6,
|
||||
http_0_7,
|
||||
http_0_8,
|
||||
http_0_9,
|
||||
http_0_10,
|
||||
http_1_0,
|
||||
http_1_1,
|
||||
http_1_2,
|
||||
http_1_3,
|
||||
http_1_4,
|
||||
http_1_5,
|
||||
http_1_6,
|
||||
http_1_7,
|
||||
http_1_8,
|
||||
http_1_9,
|
||||
http_1_10,
|
||||
http_2_0,
|
||||
http_2_1,
|
||||
http_2_2,
|
||||
http_2_3,
|
||||
http_2_4,
|
||||
http_2_5,
|
||||
http_2_6,
|
||||
http_2_7,
|
||||
http_2_8,
|
||||
http_2_9,
|
||||
http_2_10,
|
||||
http_3_0,
|
||||
http_3_1,
|
||||
http_3_2,
|
||||
http_3_3,
|
||||
http_3_4,
|
||||
http_3_5,
|
||||
http_3_6,
|
||||
http_3_7,
|
||||
http_3_8,
|
||||
http_3_9,
|
||||
http_3_10,
|
||||
};
|
||||
std::ostream& operator <<(std::ostream& _os, enum enet::HTTPProtocol _obj);
|
||||
class HttpHeader {
|
||||
private:
|
||||
protected:
|
||||
// key, val
|
||||
std::map<std::string, std::string> m_map;
|
||||
enum HTTPProtocol m_protocol;
|
||||
public:
|
||||
void addKey(const std::string& _key, const std::string& _value);
|
||||
void setKey(const std::string& _key, const std::string& _value);
|
||||
void rmKey(const std::string& _key);
|
||||
std::string getKey(const std::string& _key);
|
||||
enum HTTPProtocol getProtocol() {
|
||||
std::string getKey(const std::string& _key) const;
|
||||
protected:
|
||||
std::string generateKeys() const;
|
||||
public:
|
||||
enum HTTPProtocol getProtocol() const {
|
||||
return m_protocol;
|
||||
}
|
||||
void setProtocol(enum HTTPProtocol _protocol) {
|
||||
m_protocol = _protocol;
|
||||
}
|
||||
HttpHeader();
|
||||
virtual ~HttpHeader() = default;
|
||||
virtual std::string generate() const = 0;
|
||||
};
|
||||
|
||||
class HttpAnswer : public HttpHeader {
|
||||
private:
|
||||
|
||||
enet::HTTPAnswerCode m_what;
|
||||
int64_t m_messageSize; // parameter
|
||||
std::string m_helpMessage;
|
||||
public:
|
||||
HttpAnswer();
|
||||
HttpAnswer(const std::string& _value);
|
||||
get(const std::string& _uri);
|
||||
setSize(int64_t _messageSize=-1);
|
||||
HttpAnswer(enum HTTPAnswerCode _code = enet::HTTPAnswerCode::c400_badRequest, const std::string& _help="");
|
||||
void display() const;
|
||||
std::string generate();
|
||||
std::string generate() const;
|
||||
void setErrorCode(enum HTTPAnswerCode _value) {
|
||||
m_what = _value;
|
||||
}
|
||||
enum HTTPAnswerCode getErrorCode() {
|
||||
return m_what;
|
||||
}
|
||||
void setHelp(const std::string& _value) {
|
||||
m_helpMessage = _value;
|
||||
}
|
||||
const std::string& getHelp() {
|
||||
return m_helpMessage;
|
||||
}
|
||||
};
|
||||
enum class HTTPReqType {
|
||||
GET,
|
||||
@ -104,19 +162,28 @@ namespace enet {
|
||||
PUT,
|
||||
DELETE,
|
||||
};
|
||||
class HttpRequest : public HttpHeader{
|
||||
std::ostream& operator <<(std::ostream& _os, enum enet::HTTPReqType _obj);
|
||||
class HttpRequest : public HttpHeader {
|
||||
private:
|
||||
// key, val
|
||||
std::map<std::string, std::string> m_parameters;
|
||||
enum HTTPReqType m_req;
|
||||
std::string m_uri;
|
||||
enum HTTPProtocol m_protocol;
|
||||
bool m_keepAlive;
|
||||
public:
|
||||
HttpRequest(enum HTTPReqType _type,
|
||||
HttpRequest(enum enet::HTTPReqType _type=enet::HTTPReqType::GET);
|
||||
void display() const;
|
||||
std::string generate();
|
||||
|
||||
std::string generate() const;
|
||||
void setType(enum enet::HTTPReqType _value) {
|
||||
m_req = _value;
|
||||
}
|
||||
enum enet::HTTPReqType getType() const{
|
||||
return m_req;
|
||||
}
|
||||
void setUri(const std::string& _value) {
|
||||
m_uri = _value;
|
||||
}
|
||||
const std::string& getUri() const {
|
||||
return m_uri;
|
||||
}
|
||||
};
|
||||
class Http {
|
||||
public:
|
||||
@ -128,26 +195,32 @@ namespace enet {
|
||||
bool getServerState() {
|
||||
return m_isServer;
|
||||
}
|
||||
private:
|
||||
bool isServer() {
|
||||
return m_isServer;
|
||||
}
|
||||
protected:
|
||||
enet::HttpRequest m_requestHeader;
|
||||
void setRequestHeader(const enet::HttpRequest& _req);
|
||||
public:
|
||||
const enet::HttpRequest& getRequestHeader() {
|
||||
return m_requestHeader;
|
||||
}
|
||||
protected:
|
||||
enet::HttpAnswer m_answerHeader;
|
||||
void setAnswerHeader(const enet::HttpAnswer& _req);
|
||||
public:
|
||||
const enet::HttpAnswer& getAnswerHeader() {
|
||||
return m_answerHeader;
|
||||
}
|
||||
protected:
|
||||
enet::Tcp m_connection;
|
||||
bool m_headerIsSend;
|
||||
std::thread* m_thread;
|
||||
bool m_threadRunning;
|
||||
std::vector<uint8_t> m_temporaryBuffer;
|
||||
private:
|
||||
bool m_keepAlive;
|
||||
void threadCallback();
|
||||
public:
|
||||
void setKeepAlive(bool _keepAlive) {
|
||||
m_keepAlive = true;
|
||||
}
|
||||
bool getKeepAlive() {
|
||||
return m_keepAlive;
|
||||
}
|
||||
private:
|
||||
|
||||
HttpHeader m_header;
|
||||
std::vector<uint8_t> m_receiveData;
|
||||
void getHeader();
|
||||
public:
|
||||
void start();
|
||||
@ -155,18 +228,8 @@ namespace enet {
|
||||
bool isAlive() {
|
||||
return m_connection.getConnectionStatus() == enet::Tcp::status::link;
|
||||
}
|
||||
void setSendHeaderProperties(const std::string& _key, const std::string& _val);
|
||||
std::string getSendHeaderProperties(const std::string& _key);
|
||||
std::string getReceiveHeaderProperties(const std::string& _key);
|
||||
bool get(const std::string& _address);
|
||||
bool post(const std::string& _address, const std::map<std::string, std::string>& _values);
|
||||
bool post(const std::string& _address, const std::string& _contentType, const std::string& _data);
|
||||
std::string dataString();
|
||||
void writeAnswerHeader(enum enet::HTTPAnswerCode _value);
|
||||
std::string escapeChar(const std::string& _value);
|
||||
std::string unEscapeChar(const std::string& _value);
|
||||
public:
|
||||
using Observer = std::function<void(enet::Http& _interface, std::vector<uint8_t>&)>; //!< Define an Observer: function pointer
|
||||
using Observer = std::function<void(std::vector<uint8_t>&)>; //!< Define an Observer: function pointer
|
||||
Observer m_observer;
|
||||
/**
|
||||
* @brief Connect an function member on the signal with the shared_ptr object.
|
||||
@ -175,32 +238,23 @@ namespace enet {
|
||||
* @param[in] _args Argument optinnal the user want to add.
|
||||
*/
|
||||
template<class CLASS_TYPE>
|
||||
void connect(CLASS_TYPE* _class, void (CLASS_TYPE::*_func)(enet::Http& _interface, std::vector<uint8_t>&)) {
|
||||
m_observer = [=](enet::Http& _interface, std::vector<uint8_t>& _value){
|
||||
(*_class.*_func)(_interface,_value);
|
||||
void connect(CLASS_TYPE* _class, void (CLASS_TYPE::*_func)(std::vector<uint8_t>&)) {
|
||||
m_observer = [=](std::vector<uint8_t>& _value){
|
||||
(*_class.*_func)(_value);
|
||||
};
|
||||
}
|
||||
void connect(Observer _func) {
|
||||
m_observer = _func;
|
||||
}
|
||||
public:
|
||||
using ObserverRequest = std::function<void(enet::Http& _interface, const enet::HttpHeader&)>; //!< Define an Observer: function pointer
|
||||
using ObserverRequest = std::function<void(const enet::HttpRequest&)>; //!< Define an Observer: function pointer
|
||||
protected:
|
||||
ObserverRequest m_observerRequest;
|
||||
/**
|
||||
* @brief Connect an function member on the signal with the shared_ptr object.
|
||||
* @param[in] _class shared_ptr Object on whe we need to call ==> the object is get in keeped in weak_ptr.
|
||||
* @param[in] _func Function to call.
|
||||
* @param[in] _args Argument optinnal the user want to add.
|
||||
*/
|
||||
template<class CLASS_TYPE>
|
||||
void connectHeader(CLASS_TYPE* _class, void (CLASS_TYPE::*_func)(enet::Http& _interface, const enet::HttpHeader&)) {
|
||||
m_observerRequest = [=](enet::Http& _interface, std::vector<uint8_t>& _value){
|
||||
(*_class.*_func)(_value);
|
||||
};
|
||||
}
|
||||
void connectHeader(ObserverRequest _func) {
|
||||
m_observerRequest = _func;
|
||||
}
|
||||
public:
|
||||
using ObserverAnswer = std::function<void(const enet::HttpAnswer&)>; //!< Define an Observer: function pointer
|
||||
protected:
|
||||
ObserverAnswer m_observerAnswer;
|
||||
public:
|
||||
/**
|
||||
* @brief Write a chunk of data on the socket
|
||||
* @param[in] _data pointer on the data might be write
|
||||
@ -244,5 +298,59 @@ namespace enet {
|
||||
return ret/sizeof(T);
|
||||
}
|
||||
};
|
||||
|
||||
class HttpClient : public Http {
|
||||
public:
|
||||
HttpClient(enet::Tcp _connection);
|
||||
public:
|
||||
void setHeader(const enet::HttpRequest& _header) {
|
||||
setRequestHeader(_header);
|
||||
}
|
||||
public:
|
||||
//bool get(const std::string& _address);
|
||||
//bool post(const std::string& _address, const std::map<std::string, std::string>& _values);
|
||||
//bool post(const std::string& _address, const std::string& _contentType, const std::string& _data);
|
||||
public:
|
||||
/**
|
||||
* @brief Connect an function member on the signal with the shared_ptr object.
|
||||
* @param[in] _class shared_ptr Object on whe we need to call ==> the object is get in keeped in weak_ptr.
|
||||
* @param[in] _func Function to call.
|
||||
* @param[in] _args Argument optinnal the user want to add.
|
||||
*/
|
||||
template<class CLASS_TYPE>
|
||||
void connectHeader(CLASS_TYPE* _class, void (CLASS_TYPE::*_func)(const enet::HttpAnswer&)) {
|
||||
m_observerAnswer = [=](const enet::HttpAnswer& _value){
|
||||
(*_class.*_func)(_value);
|
||||
};
|
||||
}
|
||||
void connectHeader(Http::ObserverAnswer _func) {
|
||||
m_observerAnswer = _func;
|
||||
}
|
||||
};
|
||||
|
||||
class HttpServer : public Http {
|
||||
public:
|
||||
HttpServer(enet::Tcp _connection);
|
||||
public:
|
||||
void setHeader(const enet::HttpAnswer& _header) {
|
||||
setAnswerHeader(_header);
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* @brief Connect an function member on the signal with the shared_ptr object.
|
||||
* @param[in] _class shared_ptr Object on whe we need to call ==> the object is get in keeped in weak_ptr.
|
||||
* @param[in] _func Function to call.
|
||||
* @param[in] _args Argument optinnal the user want to add.
|
||||
*/
|
||||
template<class CLASS_TYPE>
|
||||
void connectHeader(CLASS_TYPE* _class, void (CLASS_TYPE::*_func)(const enet::HttpRequest&)) {
|
||||
m_observerRequest = [=](const enet::HttpRequest& _value){
|
||||
(*_class.*_func)(_value);
|
||||
};
|
||||
}
|
||||
void connectHeader(Http::ObserverRequest _func) {
|
||||
m_observerRequest = _func;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -13,26 +13,79 @@
|
||||
|
||||
|
||||
enet::WebSocket::WebSocket(enet::Tcp _connection, bool _isServer) :
|
||||
m_interface(std::move(_connection), _isServer) {
|
||||
|
||||
m_interface(),
|
||||
m_observer(nullptr) {
|
||||
if (_isServer == true) {
|
||||
ememory::SharedPtr<enet::HttpServer> interface = std::make_shared<enet::HttpServer>(std::move(_connection));
|
||||
interface->connectHeader(this, &enet::WebSocket::onReceiveRequest);
|
||||
m_interface = interface;
|
||||
} else {
|
||||
ememory::SharedPtr<enet::HttpClient> interface = std::make_shared<enet::HttpClient>(std::move(_connection));
|
||||
interface->connectHeader(this, &enet::WebSocket::onReceiveAnswer);
|
||||
m_interface = interface;
|
||||
}
|
||||
m_interface->connect(this, &enet::WebSocket::onReceiveData);
|
||||
}
|
||||
|
||||
enet::WebSocket::~WebSocket() {
|
||||
|
||||
if (m_interface == nullptr) {
|
||||
return;
|
||||
}
|
||||
stop(true);
|
||||
}
|
||||
|
||||
|
||||
void enet::WebSocket::start(const std::string& _uri) {
|
||||
if (m_interface.isServer() == true) {
|
||||
|
||||
if (m_interface == nullptr) {
|
||||
ENET_ERROR("Nullptr interface ...");
|
||||
return;
|
||||
}
|
||||
m_interface.start();
|
||||
if (m_interface.isServer() == false) {
|
||||
m_interface.get(
|
||||
m_interface->start();
|
||||
if (m_interface->isServer() == false) {
|
||||
enet::HttpRequest req(enet::HTTPReqType::GET);
|
||||
req.setUri(_uri);
|
||||
std::dynamic_pointer_cast<enet::HttpClient>(m_interface)->setHeader(req);
|
||||
}
|
||||
}
|
||||
|
||||
void enet::WebSocket::stop(bool _inThread=false) {
|
||||
|
||||
void enet::WebSocket::stop(bool _inThread) {
|
||||
if (m_interface == nullptr) {
|
||||
ENET_ERROR("Nullptr interface ...");
|
||||
return;
|
||||
}
|
||||
m_interface->stop(_inThread);
|
||||
m_interface.reset();
|
||||
}
|
||||
|
||||
void enet::WebSocket::onReceiveData(std::vector<uint8_t>& _data) {
|
||||
if (m_interface == nullptr) {
|
||||
ENET_ERROR("Nullptr interface ...");
|
||||
return;
|
||||
}
|
||||
ENET_ERROR("manage receive data event ...");
|
||||
}
|
||||
|
||||
void enet::WebSocket::onReceiveRequest(const enet::HttpRequest& _data) {
|
||||
if (m_interface == nullptr) {
|
||||
ENET_ERROR("Nullptr interface ...");
|
||||
return;
|
||||
}
|
||||
_data.display();
|
||||
}
|
||||
|
||||
void enet::WebSocket::onReceiveAnswer(const enet::HttpAnswer& _data) {
|
||||
if (m_interface == nullptr) {
|
||||
ENET_ERROR("Nullptr interface ...");
|
||||
return;
|
||||
}
|
||||
_data.display();
|
||||
}
|
||||
|
||||
int32_t enet::WebSocket::write(const void* _data, int32_t _len) {
|
||||
if (m_interface == nullptr) {
|
||||
ENET_ERROR("Nullptr interface ...");
|
||||
return -1;
|
||||
}
|
||||
// TODO : ...
|
||||
return -1;
|
||||
}
|
@ -5,18 +5,88 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <enet/Tcp.h>
|
||||
#include <enet/Http.h>
|
||||
#include <ememory/memory.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace enet {
|
||||
class WebSocket{
|
||||
class WebSocket {
|
||||
private:
|
||||
enet::Http m_interface;
|
||||
ememory::SharedPtr<enet::Http> m_interface;
|
||||
public:
|
||||
WebSocket(enet::Tcp _connection, bool _isServer=false);
|
||||
virtual ~WebSocket();
|
||||
void start(const std::string& _uri);
|
||||
void start(const std::string& _uri="");
|
||||
void stop(bool _inThread=false);
|
||||
bool isAlive() {
|
||||
return m_interface->isAlive();
|
||||
}
|
||||
void onReceiveData(std::vector<uint8_t>& _data);
|
||||
void onReceiveRequest(const enet::HttpRequest& _data);
|
||||
void onReceiveAnswer(const enet::HttpAnswer& _data);
|
||||
public:
|
||||
using Observer = std::function<void(std::vector<uint8_t>&)>; //!< Define an Observer: function pointer
|
||||
private:
|
||||
Observer m_observer;
|
||||
public:
|
||||
/**
|
||||
* @brief Connect an function member on the signal with the shared_ptr object.
|
||||
* @param[in] _class shared_ptr Object on whe we need to call ==> the object is get in keeped in weak_ptr.
|
||||
* @param[in] _func Function to call.
|
||||
* @param[in] _args Argument optinnal the user want to add.
|
||||
*/
|
||||
template<class CLASS_TYPE>
|
||||
void connect(CLASS_TYPE* _class, void (CLASS_TYPE::*_func)(std::vector<uint8_t>&)) {
|
||||
m_observer = [=](std::vector<uint8_t>& _value){
|
||||
(*_class.*_func)(_value);
|
||||
};
|
||||
}
|
||||
void connect(Observer _func) {
|
||||
m_observer = _func;
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* @brief Write a chunk of data on the socket
|
||||
* @param[in] _data pointer on the data might be write
|
||||
* @param[in] _len Size that must be written socket
|
||||
* @return >0 byte size on the socket write
|
||||
* @return -1 an error occured.
|
||||
*/
|
||||
int32_t write(const void* _data, int32_t _len);
|
||||
/**
|
||||
* @brief Write a chunk of data on the socket
|
||||
* @param[in] _data String to rite on the soccket
|
||||
* @param[in] _writeBackSlashZero if false, the \0 is not write
|
||||
* @return >0 byte size on the socket write
|
||||
* @return -1 an error occured.
|
||||
*/
|
||||
int32_t write(const std::string& _data, bool _writeBackSlashZero = true) {
|
||||
if (_data.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (_writeBackSlashZero == true) {
|
||||
return write(_data.c_str(), _data.size()+1);
|
||||
}
|
||||
return write(_data.c_str(), _data.size());
|
||||
}
|
||||
/**
|
||||
* @brief Write a chunk of data on the socket
|
||||
* @param[in] _data String to rite on the soccket
|
||||
* @param[in] _writeBackSlashZero if false, the \0 is not write
|
||||
* @return >0 T element write on the socket
|
||||
* @return -1 an error occured.
|
||||
*/
|
||||
template <class T>
|
||||
int32_t write(const std::vector<T>& _data) {
|
||||
if (_data.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
size_t ret = write(&_data[0], _data.size()*sizeof(T));
|
||||
if (ret <=0) {
|
||||
return ret;
|
||||
}
|
||||
return ret/sizeof(T);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ namespace enet {
|
||||
|
||||
#define ENET_BASE(info,data) ELOG_BASE(enet::getLogId(),info,data)
|
||||
|
||||
#define ENET_PRINT(data) ENET_BASE(-1, data)
|
||||
#define ENET_CRITICAL(data) ENET_BASE(1, data)
|
||||
#define ENET_ERROR(data) ENET_BASE(2, data)
|
||||
#define ENET_WARNING(data) ENET_BASE(3, data)
|
||||
|
@ -26,7 +26,7 @@ def get_version():
|
||||
|
||||
def create(target, module_name):
|
||||
my_module = module.Module(__file__, module_name, get_type())
|
||||
my_module.add_module_depend(['etk'])
|
||||
my_module.add_module_depend(['etk', 'ememory'])
|
||||
my_module.add_src_file([
|
||||
'enet/debug.cpp'
|
||||
])
|
||||
@ -40,6 +40,7 @@ def create(target, module_name):
|
||||
'enet/TcpClient.cpp',
|
||||
'enet/Http.cpp',
|
||||
'enet/Ftp.cpp',
|
||||
'enet/WebSocket.cpp',
|
||||
])
|
||||
my_module.add_header_file([
|
||||
'enet/debug.h',
|
||||
@ -49,6 +50,7 @@ def create(target, module_name):
|
||||
'enet/TcpClient.h',
|
||||
'enet/Http.h',
|
||||
'enet/Ftp.h',
|
||||
'enet/WebSocket.h',
|
||||
])
|
||||
return my_module
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
namespace appl {
|
||||
void onReceiveData(enet::Http& _interface, std::vector<uint8_t>& _data) {
|
||||
void onReceiveData(std::vector<uint8_t>& _data) {
|
||||
TEST_INFO("Receive Datas : " << _data.size() << " bytes");
|
||||
TEST_INFO("data:" << (char*)&_data[0] << "");
|
||||
}
|
||||
@ -41,15 +41,15 @@ int main(int _argc, const char *_argv[]) {
|
||||
// TODO : Check if connection is valid ...
|
||||
|
||||
// Create a HTTP connection in Client mode
|
||||
enet::Http connection(std::move(tcpConnection), false);
|
||||
connection.setKeepAlive(true);
|
||||
enet::HttpClient connection(std::move(tcpConnection));
|
||||
// Set callbacks:
|
||||
connection.connect(appl::onReceiveData);
|
||||
|
||||
// start http connection (the actual state is just TCP start ...)
|
||||
connection.start();
|
||||
connection.get("plop.txt");
|
||||
|
||||
enet::HttpRequest req(enet::HTTPReqType::GET);
|
||||
req.setUri("plop.txt");
|
||||
connection.setHeader(req);
|
||||
|
||||
while (connection.isAlive() == true) {
|
||||
usleep(100000);
|
||||
|
@ -13,23 +13,27 @@
|
||||
#include <unistd.h>
|
||||
#include <etk/stdTools.h>
|
||||
namespace appl {
|
||||
void onReceiveData(enet::Http& _interface, std::vector<uint8_t>& _data) {
|
||||
void onReceiveData(enet::HttpServer* _interface, std::vector<uint8_t>& _data) {
|
||||
TEST_INFO("Receive Datas : " << _data.size() << " bytes");
|
||||
}
|
||||
void onReceiveHeader(enet::Http& _interface, const enet::HttpHeader& _data) {
|
||||
void onReceiveHeader(enet::HttpServer* _interface, const enet::HttpRequest& _data) {
|
||||
TEST_INFO("Receive Header data:");
|
||||
_data.display();
|
||||
if (_data.m_req == "GET") {
|
||||
if (_data.m_what == "http://127.0.0.1:12345/plop.txt") {
|
||||
_interface.writeAnswerHeader(enet::HTTPAnswerCode::c200_ok);
|
||||
if (_data.getType() == enet::HTTPReqType::GET) {
|
||||
if (_data.getUri() == "http://127.0.0.1:12345/plop.txt") {
|
||||
enet::HttpAnswer answer(enet::HTTPAnswerCode::c200_ok);
|
||||
std::string data = "<html><head></head></body>coucou</body></html>";
|
||||
_interface.write(data);
|
||||
_interface.stop();
|
||||
answer.setKey("Content-Length", etk::to_string(data.size()));
|
||||
_interface->setHeader(answer);
|
||||
_interface->write(data);
|
||||
_interface->stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
_interface.writeAnswerHeader(enet::HTTPAnswerCode::c200_ok);
|
||||
_interface.stop();
|
||||
enet::HttpAnswer answer(enet::HTTPAnswerCode::c404_notFound);
|
||||
answer.setKey("Connection", "close");
|
||||
_interface->setHeader(answer);
|
||||
_interface->stop();
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,11 +67,15 @@ int main(int _argc, const char *_argv[]) {
|
||||
// TODO : Check if connection is valid ...
|
||||
|
||||
// Create a HTTP connection in Server mode
|
||||
enet::Http connection(std::move(tcpConnection), true);
|
||||
connection.setKeepAlive(true);
|
||||
enet::HttpServer connection(std::move(tcpConnection));
|
||||
enet::HttpServer* tmp = &connection;
|
||||
// Set callbacks:
|
||||
connection.connect(appl::onReceiveData);
|
||||
connection.connectHeader(appl::onReceiveHeader);
|
||||
connection.connect([=](std::vector<uint8_t>& _value){
|
||||
appl::onReceiveData(tmp, _value);
|
||||
});
|
||||
connection.connectHeader([=](const enet::HttpRequest& _value){
|
||||
appl::onReceiveHeader(tmp, _value);
|
||||
});
|
||||
|
||||
// start http connection (the actual state is just TCP start ...)
|
||||
connection.start();
|
||||
|
Loading…
x
Reference in New Issue
Block a user