From db50d40c8ced134c51447925570c578be6264dbf Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Fri, 1 Jul 2016 23:39:24 +0200 Subject: [PATCH] [DEBUG] add lock on read and write on the socket and check return of http header before continue sending datas... --- enet/Http.cpp | 4 ++++ enet/Tcp.cpp | 15 +++++++++++--- enet/Tcp.h | 2 ++ enet/WebSocket.cpp | 49 +++++++++++++++++++++++++++++++++++++++------- enet/WebSocket.h | 1 + 5 files changed, 61 insertions(+), 10 deletions(-) diff --git a/enet/Http.cpp b/enet/Http.cpp index 5691104..35f1715 100644 --- a/enet/Http.cpp +++ b/enet/Http.cpp @@ -387,6 +387,10 @@ void enet::Http::getHeader() { break; } } + if (m_connection.getConnectionStatus() != enet::Tcp::status::link) { + ENET_ERROR("Read HTTP Header [STOP] : '" << header << "' ==> status move in unlink ..."); + return; + } ENET_VERBOSE("Read HTTP Header [STOP] : '" << header << "'"); m_headerIsSend = true; // parse header : diff --git a/enet/Tcp.cpp b/enet/Tcp.cpp index 9b9a84a..93df7f8 100644 --- a/enet/Tcp.cpp +++ b/enet/Tcp.cpp @@ -117,7 +117,11 @@ int32_t enet::Tcp::read(void* _data, int32_t _maxLen) { // Receive all incoming data on this socket before we loop back and call poll again. // Receive data on this connection until the recv fails with EWOULDBLOCK. // If any other failure occurs, we will close the connection. - rc = recv(m_fds[0].fd, _data, _maxLen, 0); + { + std::unique_lock lock(m_mutex); + //ENET_DEBUG("Read on socketid = " << m_fds[0].fd ); + rc = recv(m_fds[0].fd, _data, _maxLen, 0); + } if (rc < 0) { if (errno != EWOULDBLOCK) { ENET_ERROR(" recv() failed"); @@ -126,7 +130,7 @@ int32_t enet::Tcp::read(void* _data, int32_t _maxLen) { } // Check to see if the connection has been closed by the client if (rc == 0) { - ENET_INFO(" Connection closed"); + ENET_INFO("Connection closed"); closeConn = true; } if (closeConn == false) { @@ -147,7 +151,12 @@ int32_t enet::Tcp::write(const void* _data, int32_t _len) { ENET_ERROR("Can not write on unlink connection"); return -1; } - int32_t size = ::write(m_socketId, _data, _len); + //ENET_DEBUG("write on socketid = " << m_socketId << " data@=" << int64_t(_data) << " size=" << _len ); + int32_t size; + { + std::unique_lock lock(m_mutex); + size = ::write(m_socketId, _data, _len); + } if ( size != _len && errno != 0) { ENET_ERROR("PB when writing data on the FD : request=" << _len << " have=" << size << ", erno=" << errno << "," << strerror(errno)); diff --git a/enet/Tcp.h b/enet/Tcp.h index 224b977..d79cfe5 100644 --- a/enet/Tcp.h +++ b/enet/Tcp.h @@ -7,12 +7,14 @@ #include #include +#include namespace enet { class Tcp { private: int32_t m_socketId; //!< socket linux interface generic struct pollfd m_fds[1]; + std::mutex m_mutex; public: Tcp(); Tcp(int32_t _idSocket, const std::string& _name); diff --git a/enet/WebSocket.cpp b/enet/WebSocket.cpp index c12b622..0e3a8b0 100644 --- a/enet/WebSocket.cpp +++ b/enet/WebSocket.cpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace enet { @@ -27,25 +28,35 @@ namespace enet { } enet::WebSocket::WebSocket() : - m_interface(), + m_connectionValidate(false), + m_interface(nullptr), m_observer(nullptr), m_observerUriCheck(nullptr) { } enet::WebSocket::WebSocket(enet::Tcp _connection, bool _isServer) : - m_interface(), + m_connectionValidate(false), + m_interface(nullptr), m_observer(nullptr), m_observerUriCheck(nullptr) { _connection.setTCPNoDelay(true); if (_isServer == true) { ememory::SharedPtr interface = std::make_shared(std::move(_connection)); - interface->connectHeader(this, &enet::WebSocket::onReceiveRequest); m_interface = interface; + if (interface != nullptr) { + interface->connectHeader(this, &enet::WebSocket::onReceiveRequest); + } } else { ememory::SharedPtr interface = std::make_shared(std::move(_connection)); - interface->connectHeader(this, &enet::WebSocket::onReceiveAnswer); m_interface = interface; + if (interface != nullptr) { + interface->connectHeader(this, &enet::WebSocket::onReceiveAnswer); + } + } + if (m_interface == nullptr) { + ENET_ERROR("can not create interface for the websocket"); + return; } m_interface->connectRaw(this, &enet::WebSocket::onReceiveData); } @@ -54,12 +65,20 @@ void enet::WebSocket::setInterface(enet::Tcp _connection, bool _isServer) { _connection.setTCPNoDelay(true); if (_isServer == true) { ememory::SharedPtr interface = std::make_shared(std::move(_connection)); - interface->connectHeader(this, &enet::WebSocket::onReceiveRequest); m_interface = interface; + if (interface != nullptr) { + interface->connectHeader(this, &enet::WebSocket::onReceiveRequest); + } } else { ememory::SharedPtr interface = std::make_shared(std::move(_connection)); - interface->connectHeader(this, &enet::WebSocket::onReceiveAnswer); m_interface = interface; + if (interface != nullptr) { + interface->connectHeader(this, &enet::WebSocket::onReceiveAnswer); + } + } + if (m_interface == nullptr) { + ENET_ERROR("can not create interface for the websocket"); + return; } m_interface->connectRaw(this, &enet::WebSocket::onReceiveData); } @@ -121,13 +140,27 @@ void enet::WebSocket::start(const std::string& _uri, const std::vector interface = std::dynamic_pointer_cast(m_interface); - if (interface!=nullptr) { + if (interface != nullptr) { interface->setHeader(req); + int32_t timeout = 500000; // 5 second + while (timeout>=0) { + if ( m_connectionValidate == true + || m_interface->isAlive() == false) { + break; + } + usleep(10000); + timeout--; + } + if ( m_connectionValidate == false + || m_interface->isAlive() == false) { + ENET_ERROR("Connection refused by SERVER ..."); + } } } } void enet::WebSocket::stop(bool _inThread) { + ENET_DEBUG("Stop interface ..."); if (m_interface == nullptr) { ENET_ERROR("Nullptr interface ..."); return; @@ -401,6 +434,8 @@ void enet::WebSocket::onReceiveAnswer(const enet::HttpAnswer& _data) { } setProtocol(_data.getKey("Sec-WebSocket-Protocol")); // TODO : Create a methode to check the current protocol ... + // now we can release the client call connection ... + m_connectionValidate = true; } bool enet::WebSocket::writeHeader(int32_t _len, bool _isString, bool _mask) { diff --git a/enet/WebSocket.h b/enet/WebSocket.h index 16d3f2b..87a2d5c 100644 --- a/enet/WebSocket.h +++ b/enet/WebSocket.h @@ -13,6 +13,7 @@ namespace enet { class WebSocket { protected: + bool m_connectionValidate; ememory::SharedPtr m_interface; std::vector m_buffer; std::string m_checkKey;