[DEV] first http get work
This commit is contained in:
commit
77dd712c56
64
.gitignore
vendored
Normal file
64
.gitignore
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
|
||||
###################################
|
||||
# folders
|
||||
###################################
|
||||
CVS
|
||||
.svn
|
||||
Object_*
|
||||
doxygen/API/
|
||||
doxygen/ALL/
|
||||
|
||||
###################################
|
||||
# backup files
|
||||
###################################
|
||||
*~
|
||||
*.swp
|
||||
*.old
|
||||
*.bck
|
||||
|
||||
###################################
|
||||
# Compiled source #
|
||||
###################################
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.o
|
||||
*.so
|
||||
*.pyc
|
||||
tags
|
||||
#ewol
|
||||
out
|
||||
ewol_debug
|
||||
ewol_release
|
||||
|
||||
###################################
|
||||
# Packages #
|
||||
###################################
|
||||
# it's better to unpack these files and commit the raw source
|
||||
# git has its own built in compression methods
|
||||
*.7z
|
||||
*.dmg
|
||||
*.gz
|
||||
*.iso
|
||||
*.jar
|
||||
*.rar
|
||||
*.tar
|
||||
*.zip
|
||||
|
||||
###################################
|
||||
# Logs and databases #
|
||||
###################################
|
||||
*.log
|
||||
*.sql
|
||||
*.sqlite
|
||||
|
||||
###################################
|
||||
# OS generated files #
|
||||
###################################
|
||||
.DS_Store?
|
||||
ehthumbs.db
|
||||
Icon?
|
||||
Thumbs.db
|
||||
Sources/libewol/ewol/os/AndroidAbstraction.cpp
|
||||
org_ewol_EwolConstants.h
|
16
enet/Ftp.cpp
Normal file
16
enet/Ftp.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD 3 clauses (see license file)
|
||||
*/
|
||||
|
||||
#include <enet/debug.h>
|
||||
#include <enet/Ftp.h>
|
||||
|
||||
|
||||
#ifdef __class__
|
||||
#undef __class__
|
||||
#endif
|
||||
#define __class__ ("Ftp")
|
20
enet/Ftp.h
Normal file
20
enet/Ftp.h
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD 3 clauses (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __ENET_FTP_H__
|
||||
#define __ENET_FTP_H__
|
||||
|
||||
namespace enet {
|
||||
class Ftp {
|
||||
public:
|
||||
Ftp(void) { };
|
||||
virtual ~Ftp(void) { };
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
235
enet/Http.cpp
Normal file
235
enet/Http.cpp
Normal file
@ -0,0 +1,235 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD 3 clauses (see license file)
|
||||
*/
|
||||
|
||||
#include <enet/debug.h>
|
||||
#include <enet/Http.h>
|
||||
#include <map>
|
||||
#include <etk/stdTools.h>
|
||||
|
||||
#ifdef __class__
|
||||
#undef __class__
|
||||
#endif
|
||||
#define __class__ ("Http")
|
||||
|
||||
static std::map<int32_t, std::string> getErrorList(void) {
|
||||
static std::map<int32_t, std::string> g_list;
|
||||
return g_list;
|
||||
}
|
||||
|
||||
enet::Http::Http(void) {
|
||||
m_connection.setPort(80);
|
||||
m_connection.setServer(false);
|
||||
}
|
||||
|
||||
enet::Http::~Http(void) {
|
||||
reset();
|
||||
}
|
||||
|
||||
bool enet::Http::connect(void) {
|
||||
if (m_connection.getConnectionStatus() == enet::Tcp::statusLink) {
|
||||
return true;
|
||||
}
|
||||
if (m_connection.link() == false) {
|
||||
ENET_ERROR("can not link to the socket...");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void enet::Http::setSendHeaderProperties(const std::string& _key, const std::string& _val) {
|
||||
m_sendHeader.insert(make_pair(_key, _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 "";
|
||||
}
|
||||
|
||||
bool enet::Http::reset(void) {
|
||||
if (m_connection.getConnectionStatus() != enet::Tcp::statusLink) {
|
||||
m_connection.unlink();
|
||||
}
|
||||
m_receiveData.clear();
|
||||
m_sendHeader.clear();
|
||||
m_receiveHeader.clear();
|
||||
setSendHeaderProperties("User-Agent", "e-net (ewol network interface)");
|
||||
}
|
||||
|
||||
bool enet::Http::setServer(const std::string& _hostName) {
|
||||
// if change server ==> restart connection ...
|
||||
if (_hostName == m_connection.getHostName()) {
|
||||
return true;
|
||||
}
|
||||
reset();
|
||||
m_connection.setHostNane(_hostName);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool enet::Http::setPort(uint16_t _port) {
|
||||
// if change server ==> restart connection ...
|
||||
if (_port == m_connection.getPort()) {
|
||||
return true;
|
||||
}
|
||||
reset();
|
||||
m_connection.setPort(_port);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool enet::Http::get(const std::string& _address) {
|
||||
m_receiveData.clear();
|
||||
m_receiveHeader.clear();
|
||||
if (connect() == false) {
|
||||
return false;
|
||||
}
|
||||
std::string req = "GET http://" + m_connection.getHostName();
|
||||
if (_address != "") {
|
||||
req += "/";
|
||||
req += _address;
|
||||
}
|
||||
req += " HTTP/1.0\n";
|
||||
// add header properties :
|
||||
for (auto &it : m_sendHeader) {
|
||||
req += it.first + ": " + it.second + "\n";
|
||||
}
|
||||
// end of header
|
||||
req += "\n";
|
||||
// no body:
|
||||
|
||||
int32_t len = m_connection.write(req, false);
|
||||
ENET_VERBOSE("read write=" << len << " data: " << req);
|
||||
if (len != req.size()) {
|
||||
ENET_ERROR("An error occured when sending data " << len << "!=" << req.size());
|
||||
return false;
|
||||
}
|
||||
std::string header;
|
||||
// Get data
|
||||
char data[1025];
|
||||
len = 1;
|
||||
bool headerEnded = false;
|
||||
while ( m_connection.getConnectionStatus() == enet::Tcp::statusLink
|
||||
&& len > 0) {
|
||||
len = m_connection.read(data, 1024);
|
||||
// TODO : Parse header ...
|
||||
|
||||
if (headerEnded == false) {
|
||||
char previous = '\0';
|
||||
if (header.size()>0) {
|
||||
previous = header[header.size()-1];
|
||||
}
|
||||
for (int32_t iii=0; iii<len; ++iii) {
|
||||
if (headerEnded == false) {
|
||||
if (data[iii] != '\r') {
|
||||
header += data[iii];
|
||||
if (data[iii] == '\n') {
|
||||
//ENET_VERBOSE("parse: '\\n'");
|
||||
if (previous == '\n') {
|
||||
//ENET_VERBOSE("End header");
|
||||
// Find end of header
|
||||
headerEnded = true;
|
||||
}
|
||||
previous = data[iii];
|
||||
} else {
|
||||
previous = data[iii];
|
||||
//ENET_VERBOSE("parse: '" << data[iii] << "'");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_receiveData.push_back(data[iii]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int32_t iii=0; iii<len; ++iii) {
|
||||
m_receiveData.push_back(data[iii]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_connection.getConnectionStatus() != enet::Tcp::statusLink) {
|
||||
ENET_WARNING("server disconnected");
|
||||
return false;
|
||||
}
|
||||
// parse header :
|
||||
std::vector<std::string> list = std::split(header, '\n');
|
||||
headerEnded = false;
|
||||
for (auto element : list) {
|
||||
if (headerEnded == false) {
|
||||
header = element;
|
||||
headerEnded = true;
|
||||
} else {
|
||||
//ENET_INFO("header : '" << element << "'");
|
||||
size_t found = element.find(":");
|
||||
if (found == std::string::npos) {
|
||||
// nothing
|
||||
continue;
|
||||
}
|
||||
//ENET_INFO("header : key='" << std::string(element, 0, found) << "' value='" << std::string(element, found+2) << "'");
|
||||
m_receiveHeader.insert(make_pair(std::string(element, 0, found), std::string(element, found+2)));
|
||||
}
|
||||
}
|
||||
/*
|
||||
ENET_INFO("header : '" << header << "'");
|
||||
for (auto &it : m_receiveHeader) {
|
||||
ENET_INFO("header : key='" << it.first << "' value='" << it.second << "'");
|
||||
}
|
||||
*/
|
||||
// parse base answear:
|
||||
list = std::split(header, ' ');
|
||||
if (list.size() < 2) {
|
||||
ENET_ERROR("can not parse answear : " << list);
|
||||
return false;
|
||||
}
|
||||
int32_t ret = std::stoi(list[1]);
|
||||
switch (ret/100) {
|
||||
case 1:
|
||||
// information message
|
||||
return true;
|
||||
break;
|
||||
case 2:
|
||||
// OK
|
||||
return true;
|
||||
break;
|
||||
case 3:
|
||||
// Redirect
|
||||
ENET_WARNING("Rediret request");
|
||||
return false;
|
||||
break;
|
||||
case 4:
|
||||
// client Error
|
||||
ENET_WARNING("Client error");
|
||||
return false;
|
||||
break;
|
||||
case 5:
|
||||
// server error
|
||||
ENET_WARNING("Server error");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool enet::Http::post(const std::string& _address) {
|
||||
if (connect() == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::string enet::Http::dataString(void) {
|
||||
std::string data;
|
||||
for (auto element : m_receiveData) {
|
||||
if (element == '\0') {
|
||||
return data;
|
||||
}
|
||||
data += element;
|
||||
}
|
||||
return data;
|
||||
}
|
50
enet/Http.h
Normal file
50
enet/Http.h
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD 3 clauses (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __ENET_HTTP_H__
|
||||
#define __ENET_HTTP_H__
|
||||
|
||||
#include <enet/Tcp.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace enet {
|
||||
class Http {
|
||||
public:
|
||||
Http(void);
|
||||
virtual ~Http(void);
|
||||
private:
|
||||
enet::Tcp m_connection;
|
||||
private:
|
||||
// key, val
|
||||
std::map<std::string, std::string> m_sendHeader;
|
||||
std::map<std::string, std::string> m_receiveHeader;
|
||||
std::vector<uint8_t> m_receiveData;
|
||||
bool connect(void);
|
||||
bool reset(void);
|
||||
public:
|
||||
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 setServer(const std::string& _hostName);
|
||||
bool setPort(uint16_t _port);
|
||||
bool get(const std::string& _address);
|
||||
bool post(const std::string& _address);
|
||||
|
||||
int32_t dataSize(void) {
|
||||
return m_receiveData.size();
|
||||
}
|
||||
const std::vector<uint8_t>& data(void) {
|
||||
return m_receiveData;
|
||||
}
|
||||
std::string dataString(void);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
225
enet/Tcp.cpp
Normal file
225
enet/Tcp.cpp
Normal file
@ -0,0 +1,225 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD 3 clauses (see license file)
|
||||
*/
|
||||
|
||||
#include <enet/debug.h>
|
||||
#include <enet/Tcp.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __class__
|
||||
#undef __class__
|
||||
#endif
|
||||
#define __class__ ("Tcp")
|
||||
|
||||
enet::Tcp::Tcp(void) :
|
||||
m_socketId(-1),
|
||||
m_socketIdClient(-1),
|
||||
m_host("127.0.0.1"),
|
||||
m_port(23191),
|
||||
m_server(false),
|
||||
m_status(statusUnlink) {
|
||||
|
||||
}
|
||||
|
||||
enet::Tcp::~Tcp(void) {
|
||||
unlink();
|
||||
}
|
||||
|
||||
void enet::Tcp::setIpV4(uint8_t _fist, uint8_t _second, uint8_t _third, uint8_t _quatro) {
|
||||
std::string tmpname;
|
||||
tmpname = std::to_string(_fist);
|
||||
tmpname += ".";
|
||||
tmpname += std::to_string(_second);
|
||||
tmpname += ".";
|
||||
tmpname += std::to_string(_third);
|
||||
tmpname += ".";
|
||||
tmpname += std::to_string(_quatro);
|
||||
setHostNane(tmpname);
|
||||
}
|
||||
|
||||
void enet::Tcp::setHostNane(const std::string& _name) {
|
||||
if (_name == m_host) {
|
||||
return;
|
||||
}
|
||||
if (m_status == statusLink) {
|
||||
ENET_ERROR("Can not change parameter while connection is started");
|
||||
return;
|
||||
}
|
||||
m_host = _name;
|
||||
}
|
||||
|
||||
void enet::Tcp::setPort(uint16_t _port) {
|
||||
if (_port == m_port) {
|
||||
return;
|
||||
}
|
||||
if (m_status == statusLink) {
|
||||
ENET_ERROR("Can not change parameter while connection is started");
|
||||
return;
|
||||
}
|
||||
m_port = _port;
|
||||
}
|
||||
|
||||
void enet::Tcp::setServer(bool _status) {
|
||||
if (_status == m_server) {
|
||||
return;
|
||||
}
|
||||
if (m_status == statusLink) {
|
||||
ENET_ERROR("Can not change parameter while connection is started");
|
||||
return;
|
||||
}
|
||||
m_server = _status;
|
||||
}
|
||||
|
||||
bool enet::Tcp::link(void) {
|
||||
if (m_status == statusLink) {
|
||||
ENET_ERROR("Connection is already started");
|
||||
return false;
|
||||
}
|
||||
ENET_INFO("Start connection on " << m_host << ":" << m_port);
|
||||
if (m_server == false) {
|
||||
#define MAX_TEST_TIME (5)
|
||||
for(int32_t iii=0; iii<MAX_TEST_TIME ;iii++) {
|
||||
// open in Socket normal mode
|
||||
m_socketIdClient = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (m_socketIdClient < 0) {
|
||||
ENET_ERROR("ERROR while opening socket : errno=" << errno << "," << strerror(errno));
|
||||
usleep(200000);
|
||||
continue;
|
||||
}
|
||||
ENET_INFO("Try connect on socket ... (" << iii+1 << "/" << MAX_TEST_TIME << ")");
|
||||
struct sockaddr_in servAddr;
|
||||
struct hostent* server = gethostbyname(m_host.c_str());
|
||||
if (server == NULL) {
|
||||
ENET_ERROR("ERROR, no such host : " << m_host);
|
||||
usleep(200000);
|
||||
continue;
|
||||
}
|
||||
bzero((char *) &servAddr, sizeof(servAddr));
|
||||
servAddr.sin_family = AF_INET;
|
||||
bcopy((char *)server->h_addr, (char *)&servAddr.sin_addr.s_addr, server->h_length);
|
||||
servAddr.sin_port = htons(m_port);
|
||||
ENET_INFO("Start connexion ...");
|
||||
if (connect(m_socketIdClient,(struct sockaddr *) &servAddr,sizeof(servAddr)) != 0) {
|
||||
if(errno != EINPROGRESS) {
|
||||
if(errno != ENOENT && errno != EAGAIN && errno != ECONNREFUSED) {
|
||||
ENET_ERROR("ERROR connecting on : errno=" << errno << "," << strerror(errno));
|
||||
}
|
||||
close(m_socketIdClient);
|
||||
m_socketIdClient = -1;
|
||||
}
|
||||
ENET_ERROR("ERROR connecting, maybe retry ... errno=" << errno << "," << strerror(errno));
|
||||
usleep(500000);
|
||||
continue;
|
||||
}
|
||||
// if we are here ==> then the connextion is done corectly ...
|
||||
break;
|
||||
}
|
||||
if (m_socketIdClient<0) {
|
||||
ENET_ERROR("ERROR connecting ... (after all try)");
|
||||
return false;
|
||||
} else {
|
||||
m_status = statusLink;
|
||||
ENET_DEBUG("Connection done");
|
||||
}
|
||||
} else {
|
||||
// open in Socket normal mode
|
||||
m_socketId = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (m_socketId < 0) {
|
||||
ENET_ERROR("ERROR while opening socket : errno=" << errno << "," << strerror(errno));
|
||||
return false;
|
||||
}
|
||||
// set the reuse of the socket if previously opened :
|
||||
int sockOpt = 1;
|
||||
if(setsockopt(m_socketId, SOL_SOCKET, SO_REUSEADDR, (const char*)&sockOpt, sizeof(int)) != 0) {
|
||||
ENET_ERROR("ERROR while configuring socket re-use : errno=" << errno << "," << strerror(errno));
|
||||
return false;
|
||||
}
|
||||
// clear all
|
||||
struct sockaddr_in servAddr;
|
||||
bzero((char *) &servAddr, sizeof(servAddr));
|
||||
servAddr.sin_family = AF_INET;
|
||||
servAddr.sin_addr.s_addr = INADDR_ANY;
|
||||
servAddr.sin_port = htons(m_port);
|
||||
ENET_INFO("Start binding Socket ... (can take some time ...)");
|
||||
if (bind(m_socketId, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) {
|
||||
ENET_ERROR("ERROR on binding errno=" << errno << "," << strerror(errno));
|
||||
close(m_socketId);
|
||||
m_socketId = -1;
|
||||
return false;
|
||||
}
|
||||
ENET_INFO("End binding Socket ... (start listen)");
|
||||
listen(m_socketId,1); // 1 is for the number of connection at the same time ...
|
||||
ENET_INFO("End listen Socket ... (start accept)");
|
||||
struct sockaddr_in clientAddr;
|
||||
socklen_t clilen = sizeof(clientAddr);
|
||||
m_socketIdClient = accept(m_socketId, (struct sockaddr *) &clientAddr, &clilen);
|
||||
if (m_socketIdClient < 0) {
|
||||
ENET_ERROR("ERROR on accept errno=" << errno << "," << strerror(errno));
|
||||
close(m_socketId);
|
||||
m_socketId = -1;
|
||||
return false;
|
||||
} else {
|
||||
m_status = statusLink;
|
||||
ENET_DEBUG("Connection done");
|
||||
}
|
||||
}
|
||||
ENET_INFO("End configuring Socket ...");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool enet::Tcp::unlink(void) {
|
||||
if (m_socketIdClient >= 0) {
|
||||
ENET_INFO(" close client socket");
|
||||
close(m_socketIdClient);
|
||||
m_socketIdClient = -1;
|
||||
}
|
||||
if (m_socketId >= 0) {
|
||||
ENET_INFO(" close server socket");
|
||||
close(m_socketId);
|
||||
m_socketId = -1;
|
||||
}
|
||||
m_status = statusUnlink;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int32_t enet::Tcp::read(void* _data, int32_t _maxLen) {
|
||||
if (m_status != statusLink) {
|
||||
ENET_ERROR("Can not read on unlink connection");
|
||||
return -1;
|
||||
}
|
||||
int32_t size = ::read(m_socketIdClient, _data, _maxLen);
|
||||
if ( size != _maxLen
|
||||
&& errno != 0) {
|
||||
ENET_ERROR("PB when reading data on the FD : request=" << _maxLen << " have=" << size << ", erno=" << errno << "," << strerror(errno));
|
||||
m_status = statusError;
|
||||
return -1;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t enet::Tcp::write(const void* _data, int32_t _len) {
|
||||
if (m_status != statusLink) {
|
||||
ENET_ERROR("Can not write on unlink connection");
|
||||
return -1;
|
||||
}
|
||||
int32_t size = ::write(m_socketIdClient, _data, _len);
|
||||
if ( size != _len
|
||||
&& errno != 0) {
|
||||
ENET_ERROR("PB when writing data on the FD : request=" << _len << " have=" << size << ", erno=" << errno << "," << strerror(errno));
|
||||
m_status = statusError;
|
||||
return -1;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
155
enet/Tcp.h
Normal file
155
enet/Tcp.h
Normal file
@ -0,0 +1,155 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD 3 clauses (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __ENET_TCP_H__
|
||||
#define __ENET_TCP_H__
|
||||
|
||||
namespace enet {
|
||||
class Tcp {
|
||||
private:
|
||||
int32_t m_socketId; //!< socket linux interface generic
|
||||
int32_t m_socketIdClient;
|
||||
public:
|
||||
Tcp(void);
|
||||
virtual ~Tcp(void);
|
||||
private:
|
||||
std::string m_host; //!< hostname/IP to connect with.
|
||||
public:
|
||||
/**
|
||||
* @brief Set the connection IP id.
|
||||
* @param[in] _first Firt number of the IP v4.
|
||||
* @param[in] _second Second number of the IP v4.
|
||||
* @param[in] _third Third number of the IP v4.
|
||||
* @param[in] _quatro Quatro number of the IP v4.
|
||||
*/
|
||||
void setIpV4(uint8_t _fist, uint8_t _second, uint8_t _third, uint8_t _quatro);
|
||||
/**
|
||||
* @brief set the Host name is the same things as set an Ip adress, but in test mode "127.0.0.1" or "localhost".
|
||||
* @param[in] _name Host name to connect.
|
||||
*/
|
||||
void setHostNane(const std::string& _name);
|
||||
/**
|
||||
* @brief Get the decriptive name hot the host
|
||||
* @return the string requested
|
||||
*/
|
||||
const std::string& getHostName(void) {
|
||||
return m_host;
|
||||
}
|
||||
private:
|
||||
uint16_t m_port; //!< IP port to connect with.
|
||||
public:
|
||||
/**
|
||||
* @brief set the port number to connect or to spy
|
||||
* @param[in] _port Number of the port requested
|
||||
*/
|
||||
void setPort(uint16_t _port);
|
||||
/**
|
||||
* @brief Get the port number.
|
||||
* @return The requested port number.
|
||||
*/
|
||||
uint16_t getPort(void) {
|
||||
return m_port;
|
||||
}
|
||||
private:
|
||||
bool m_server; //!< if at true, the server mode is requested
|
||||
public:
|
||||
/**
|
||||
* @brief Set the TCP interface in server mode
|
||||
* @param[in] _status if true, this enable the server mode
|
||||
*/
|
||||
void setServer(bool _status);
|
||||
/**
|
||||
* @brief Get the server mode status.
|
||||
* @return true: the tcp interface is configure as a server.
|
||||
*/
|
||||
int32_t getServer(void) {
|
||||
return m_server;
|
||||
}
|
||||
public:
|
||||
enum status {
|
||||
statusUnlink,
|
||||
statusLink,
|
||||
statusError
|
||||
};
|
||||
private:
|
||||
enum status m_status; //!< current connection status
|
||||
public:
|
||||
/**
|
||||
* @brief Get the current Status of the connection
|
||||
* @return The status.
|
||||
*/
|
||||
enum status getConnectionStatus(void) {
|
||||
return m_status;
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* @brief Link on a specific interface.
|
||||
* @return true if connection is done
|
||||
* @return false otherwise ...
|
||||
*/
|
||||
bool link(void);
|
||||
/**
|
||||
* @brief Unlink on a specific interface.
|
||||
* @return true if connection is removed
|
||||
* @return false otherwise ...
|
||||
*/
|
||||
bool unlink(void);
|
||||
/**
|
||||
* @brief Read a chunk of data on the socket
|
||||
* @param[in] _data pointer on the data might be write
|
||||
* @param[in] _maxLen Size that can be written on the pointer
|
||||
* @return >0 byte size on the socket read
|
||||
* @return -1 an error occured.
|
||||
*/
|
||||
int32_t read(void* _data, int32_t _maxLen);
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
16
enet/Udp.cpp
Normal file
16
enet/Udp.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD 3 clauses (see license file)
|
||||
*/
|
||||
|
||||
#include <enet/debug.h>
|
||||
#include <enet/Udp.h>
|
||||
|
||||
|
||||
#ifdef __class__
|
||||
#undef __class__
|
||||
#endif
|
||||
#define __class__ ("Udp")
|
20
enet/Udp.h
Normal file
20
enet/Udp.h
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD 3 clauses (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __ENET_UDP_H__
|
||||
#define __ENET_UDP_H__
|
||||
|
||||
namespace enet {
|
||||
class Udp {
|
||||
public:
|
||||
Udp(void) { };
|
||||
virtual ~Udp(void) { };
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
14
enet/debug.cpp
Normal file
14
enet/debug.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD 3 clauses (see license file)
|
||||
*/
|
||||
|
||||
#include <enet/debug.h>
|
||||
|
||||
int32_t enet::getLogId(void) {
|
||||
static int32_t g_val = etk::log::registerInstance("enet");
|
||||
return g_val;
|
||||
}
|
53
enet/debug.h
Normal file
53
enet/debug.h
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD 3 clauses (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __ENET_DEBUG_H__
|
||||
#define __ENET_DEBUG_H__
|
||||
|
||||
#include <etk/log.h>
|
||||
|
||||
namespace enet {
|
||||
int32_t getLogId(void);
|
||||
};
|
||||
|
||||
// TODO : Review this problem of multiple intanciation of "std::stringbuf sb"
|
||||
#define ENET_BASE(info,data) \
|
||||
do { \
|
||||
if (info <= etk::log::getLevel(enet::getLogId())) { \
|
||||
std::stringbuf sb; \
|
||||
std::ostream tmpStream(&sb); \
|
||||
tmpStream << data; \
|
||||
etk::log::logStream(enet::getLogId(), info, __LINE__, __class__, __func__, tmpStream); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define ENET_CRITICAL(data) ENET_BASE(1, data)
|
||||
#define ENET_ERROR(data) ENET_BASE(2, data)
|
||||
#define ENET_WARNING(data) ENET_BASE(3, data)
|
||||
#ifdef DEBUG
|
||||
#define ENET_INFO(data) ENET_BASE(4, data)
|
||||
#define ENET_DEBUG(data) ENET_BASE(5, data)
|
||||
#define ENET_VERBOSE(data) ENET_BASE(6, data)
|
||||
#define ENET_TODO(data) ENET_BASE(4, "TODO : " << data)
|
||||
#else
|
||||
#define ENET_INFO(data) do { } while(false)
|
||||
#define ENET_DEBUG(data) do { } while(false)
|
||||
#define ENET_VERBOSE(data) do { } while(false)
|
||||
#define ENET_TODO(data) do { } while(false)
|
||||
#endif
|
||||
|
||||
#define ENET_ASSERT(cond,data) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
ENET_CRITICAL(data); \
|
||||
assert(!#cond); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
17
enet/enet.h
Normal file
17
enet/enet.h
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD 3 clauses (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __ENET_H__
|
||||
#define __ENET_H__
|
||||
|
||||
#include <enet/Udp.h>
|
||||
#include <enet/Tcp.h>
|
||||
#include <enet/Http.h>
|
||||
#include <enet/Ftp.h>
|
||||
|
||||
#endif
|
34
license.txt
Normal file
34
license.txt
Normal file
@ -0,0 +1,34 @@
|
||||
Copyright (c) 2011, Edouard DUPIN
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* Neither the name of the ENET nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
see : http://opensource.org/licenses/BSD-3-Clause
|
||||
|
37
lutin_enet.py
Normal file
37
lutin_enet.py
Normal file
@ -0,0 +1,37 @@
|
||||
#!/usr/bin/python
|
||||
import lutinModule as module
|
||||
import lutinTools as tools
|
||||
|
||||
def get_desc():
|
||||
return "e-net TCP/UDP/HTTP/FTP interface"
|
||||
|
||||
def get_licence():
|
||||
return {
|
||||
"assimilate":"BSD",
|
||||
"type":"BSD-3-clauses"
|
||||
}
|
||||
|
||||
def create(target):
|
||||
myModule = module.Module(__file__, 'enet', 'LIBRARY')
|
||||
|
||||
myModule.add_module_depend(['etk'])
|
||||
|
||||
myModule.add_src_file([
|
||||
'enet/debug.cpp',
|
||||
'enet/Udp.cpp',
|
||||
'enet/Tcp.cpp',
|
||||
'enet/Http.cpp',
|
||||
'enet/Ftp.cpp',
|
||||
])
|
||||
|
||||
myModule.add_export_path(tools.get_current_path(__file__))
|
||||
|
||||
# add the currrent module at the
|
||||
return myModule
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
34
lutin_enettest.py
Normal file
34
lutin_enettest.py
Normal file
@ -0,0 +1,34 @@
|
||||
#!/usr/bin/python
|
||||
import lutinModule as module
|
||||
import lutinTools as tools
|
||||
|
||||
def get_desc():
|
||||
return "e-net TEST test software for enet"
|
||||
|
||||
def get_licence():
|
||||
return {
|
||||
"assimilate":"BSD",
|
||||
"type":"BSD-3-clauses"
|
||||
}
|
||||
|
||||
def create(target):
|
||||
myModule = module.Module(__file__, 'enettest', 'BINARY')
|
||||
|
||||
myModule.add_module_depend(['enet'])
|
||||
|
||||
myModule.add_src_file([
|
||||
'test/debug.cpp',
|
||||
'test/main.cpp'
|
||||
])
|
||||
|
||||
myModule.add_export_path(tools.get_current_path(__file__))
|
||||
|
||||
# add the currrent module at the
|
||||
return myModule
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
14
test/debug.cpp
Normal file
14
test/debug.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD 3 clauses (see license file)
|
||||
*/
|
||||
|
||||
#include <test/debug.h>
|
||||
|
||||
int32_t appl::getLogId(void) {
|
||||
static int32_t g_val = etk::log::registerInstance("enettest");
|
||||
return g_val;
|
||||
}
|
53
test/debug.h
Normal file
53
test/debug.h
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD 3 clauses (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __APPL_DEBUG_H__
|
||||
#define __APPL_DEBUG_H__
|
||||
|
||||
#include <etk/log.h>
|
||||
|
||||
namespace appl {
|
||||
int32_t getLogId(void);
|
||||
};
|
||||
|
||||
// TODO : Review this problem of multiple intanciation of "std::stringbuf sb"
|
||||
#define APPL_BASE(info,data) \
|
||||
do { \
|
||||
if (info <= etk::log::getLevel(appl::getLogId())) { \
|
||||
std::stringbuf sb; \
|
||||
std::ostream tmpStream(&sb); \
|
||||
tmpStream << data; \
|
||||
etk::log::logStream(appl::getLogId(), info, __LINE__, __class__, __func__, tmpStream); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define APPL_CRITICAL(data) APPL_BASE(1, data)
|
||||
#define APPL_ERROR(data) APPL_BASE(2, data)
|
||||
#define APPL_WARNING(data) APPL_BASE(3, data)
|
||||
#ifdef DEBUG
|
||||
#define APPL_INFO(data) APPL_BASE(4, data)
|
||||
#define APPL_DEBUG(data) APPL_BASE(5, data)
|
||||
#define APPL_VERBOSE(data) APPL_BASE(6, data)
|
||||
#define APPL_TODO(data) APPL_BASE(4, "TODO : " << data)
|
||||
#else
|
||||
#define APPL_INFO(data) do { } while(false)
|
||||
#define APPL_DEBUG(data) do { } while(false)
|
||||
#define APPL_VERBOSE(data) do { } while(false)
|
||||
#define APPL_TODO(data) do { } while(false)
|
||||
#endif
|
||||
|
||||
#define APPL_ASSERT(cond,data) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
APPL_CRITICAL(data); \
|
||||
assert(!#cond); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
92
test/main.cpp
Normal file
92
test/main.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD 3 clauses (see license file)
|
||||
*/
|
||||
|
||||
#include <test/debug.h>
|
||||
#include <enet/Tcp.h>
|
||||
#include <enet/Http.h>
|
||||
|
||||
|
||||
#undef __class__
|
||||
#define __class__ "test"
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
etk::log::setLevel(etk::log::logLevelVerbose);
|
||||
APPL_VERBOSE("plop");
|
||||
if (argc > 2) {
|
||||
// client mode ...
|
||||
enet::Http connection;
|
||||
connection.setServer("example.com");
|
||||
|
||||
APPL_INFO("Get data : ");
|
||||
if (connection.get("") == false) {
|
||||
APPL_ERROR("can not Get data...");
|
||||
return -1;
|
||||
}
|
||||
APPL_INFO("data : " << connection.dataString());
|
||||
} else if (argc > 1) {
|
||||
// client mode ...
|
||||
enet::Tcp connection;
|
||||
connection.setHostNane("127.0.0.1");
|
||||
connection.setPort(31234);
|
||||
connection.setServer(false);
|
||||
APPL_INFO("CLIENT connect ...");
|
||||
if (connection.link() == false) {
|
||||
APPL_ERROR("can not link to the socket...");
|
||||
return -1;
|
||||
}
|
||||
int32_t iii = 0;
|
||||
while ( connection.getConnectionStatus() == enet::Tcp::statusLink
|
||||
&& iii<10000) {
|
||||
char data[1024];
|
||||
int32_t len = connection.read(data, 1024);
|
||||
APPL_INFO("read len=" << len << " data='" << data << "'");
|
||||
iii++;
|
||||
}
|
||||
if (iii>=10000) {
|
||||
APPL_INFO("auto disconnected");
|
||||
} else if (connection.getConnectionStatus() != enet::Tcp::statusLink) {
|
||||
APPL_INFO("server disconnected");
|
||||
} else {
|
||||
APPL_INFO("ERROR disconnected");
|
||||
}
|
||||
if (connection.unlink() == false) {
|
||||
APPL_ERROR("can not unlink to the socket...");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
// server mode ...
|
||||
enet::Tcp connection;
|
||||
connection.setHostNane("127.0.0.1");
|
||||
connection.setPort(31234);
|
||||
connection.setServer(true);
|
||||
APPL_INFO("SERVER connect ...");
|
||||
if (connection.link() == false) {
|
||||
APPL_ERROR("can not link to the socket...");
|
||||
return -1;
|
||||
}
|
||||
int32_t iii = 0;
|
||||
while (connection.getConnectionStatus() == enet::Tcp::statusLink) {
|
||||
int32_t len = connection.write("plop" + std::to_string(iii));
|
||||
APPL_INFO("write len=" << len);
|
||||
iii++;
|
||||
}
|
||||
if (iii>=1000000) {
|
||||
APPL_INFO("auto disconnected");
|
||||
} else if (connection.getConnectionStatus() != enet::Tcp::statusLink) {
|
||||
APPL_INFO("server disconnected");
|
||||
} else {
|
||||
APPL_INFO("ERROR disconnected");
|
||||
}
|
||||
if (connection.unlink() == false) {
|
||||
APPL_ERROR("can not unlink to the socket...");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user