diff --git a/Sming/SmingCore/Network/Http/HttpServerConnection.cpp b/Sming/SmingCore/Network/Http/HttpServerConnection.cpp index 209e06c4c6..3baa6afdf9 100644 --- a/Sming/SmingCore/Network/Http/HttpServerConnection.cpp +++ b/Sming/SmingCore/Network/Http/HttpServerConnection.cpp @@ -49,10 +49,6 @@ HttpServerConnection::~HttpServerConnection() if(this->resource) { this->resource->shutdown(*this); } - - if(destroyedDelegate) { - destroyedDelegate(); - } } void HttpServerConnection::setResourceTree(ResourceTree* resourceTree) @@ -547,8 +543,3 @@ void HttpServerConnection::sendError(const char* message /* = NULL*/, enum http_ send(); } - -void HttpServerConnection::setDestroyedDelegate(HttpServerConnectionDestroyedDelegate destroyedDelegate) -{ - this->destroyedDelegate = destroyedDelegate; -} diff --git a/Sming/SmingCore/Network/Http/HttpServerConnection.h b/Sming/SmingCore/Network/Http/HttpServerConnection.h index afc74ba90e..534df786d5 100644 --- a/Sming/SmingCore/Network/Http/HttpServerConnection.h +++ b/Sming/SmingCore/Network/Http/HttpServerConnection.h @@ -33,8 +33,6 @@ class HttpServerConnection; typedef Delegate HttpServerConnectionDelegate; -typedef Delegate HttpServerConnectionDestroyedDelegate; - class HttpServerConnection: public TcpClient { @@ -49,13 +47,6 @@ class HttpServerConnection: public TcpClient using TcpClient::send; - /** - * Sets a callback to be called when the object instance is destroyed - * - * @param HttpServerConnectionDestroyedDelegate destroyedDelegate - callback - */ - void setDestroyedDelegate(HttpServerConnectionDestroyedDelegate destroyedDelegate); - protected: virtual err_t onReceive(pbuf *buf); virtual void onReadyToSendData(TcpConnectionEvent sourceEvent); @@ -103,8 +94,6 @@ class HttpServerConnection: public TcpClient BodyParsers* bodyParsers = NULL; HttpBodyParserDelegate bodyParser; - - HttpServerConnectionDestroyedDelegate destroyedDelegate = 0; }; #endif /* _SMING_CORE_HTTPSERVERCONNECTION_H_ */ diff --git a/Sming/SmingCore/Network/HttpServer.cpp b/Sming/SmingCore/Network/HttpServer.cpp index 2dd589e854..9ad31c89ee 100644 --- a/Sming/SmingCore/Network/HttpServer.cpp +++ b/Sming/SmingCore/Network/HttpServer.cpp @@ -15,13 +15,13 @@ #include "TcpClient.h" #include "../Wiring/WString.h" -HttpServer::HttpServer(): active(true) +HttpServer::HttpServer() { settings.keepAliveSeconds = 0; configure(settings); } -HttpServer::HttpServer(HttpServerSettings settings): active(true) +HttpServer::HttpServer(HttpServerSettings settings) { configure(settings); } @@ -45,7 +45,6 @@ void HttpServer::configure(HttpServerSettings settings) HttpServer::~HttpServer() { - active = true; for(int i=0; i< resourceTree.count(); i++) { if(resourceTree.valueAt(i) != NULL) { delete resourceTree.valueAt(i); @@ -60,20 +59,9 @@ void HttpServer::setBodyParser(const String& contentType, HttpBodyParserDelegate TcpConnection* HttpServer::createClient(tcp_pcb *clientTcp) { - if(!active) { - debugf("Refusing new connections. The server is shutting down"); - return NULL; - } - HttpServerConnection* con = new HttpServerConnection(clientTcp); con->setResourceTree(&resourceTree); con->setBodyParsers(&bodyParsers); - con->setCompleteDelegate(TcpClientCompleteDelegate(&HttpServer::onConnectionClose, this)); - con->setDestroyedDelegate(HttpServerConnectionDestroyedDelegate(&HttpServer::onClientDestroy, this)); - - connections.add(con); - totalConnections = connections.count(); - debugf("Opening connection. Total connections: %d", totalConnections); return con; } @@ -110,47 +98,3 @@ void HttpServer::setDefaultResource(HttpResource* resource) { addPath("*", resource); } - -void HttpServer::shutdown() -{ - active = false; - - if(tcp) { - tcp_arg(tcp, NULL); - tcp_accept(tcp, NULL); - tcp_close(tcp); - - tcp = NULL; - } - - for(int i=0; i < connections.count(); i++) { - HttpServerConnection* connection = connections[i]; - if(connection == NULL) { - continue; - } - - connection->setTimeOut(1); - } -} - -void HttpServer::onClientDestroy() -{ - if(active) { - return; - } - - if(connections.count() == 0) { - debugf("Http Server will be destroyed."); - delete this; - } -} - -void HttpServer::onConnectionClose(TcpClient& connection, bool success) -{ - connections.removeElement((HttpServerConnection*)&connection); - totalConnections = connections.count(); - if(totalConnections == 0 && !active){ - debugf("Shutting down the Http Server ..."); - } - debugf("Closing connection. Total connections: %d", totalConnections); -} diff --git a/Sming/SmingCore/Network/HttpServer.h b/Sming/SmingCore/Network/HttpServer.h index b3aca483d0..f688aa80ec 100644 --- a/Sming/SmingCore/Network/HttpServer.h +++ b/Sming/SmingCore/Network/HttpServer.h @@ -77,12 +77,8 @@ class HttpServer: public TcpServer void setDefaultHandler(const HttpPathDelegate& callback); void setDefaultResource(HttpResource* resource); - void shutdown(); - protected: virtual TcpConnection* createClient(tcp_pcb *clientTcp); - virtual void onConnectionClose(TcpClient& connection, bool success); - virtual void onClientDestroy(); protected: #ifdef ENABLE_SSL @@ -93,9 +89,6 @@ class HttpServer: public TcpServer HttpServerSettings settings; ResourceTree resourceTree; BodyParsers bodyParsers; - bool active = true; - - Vector connections; }; /** @} */ diff --git a/Sming/SmingCore/Network/TcpConnection.cpp b/Sming/SmingCore/Network/TcpConnection.cpp index f29399a53e..aa9d342ba9 100644 --- a/Sming/SmingCore/Network/TcpConnection.cpp +++ b/Sming/SmingCore/Network/TcpConnection.cpp @@ -38,6 +38,10 @@ TcpConnection::~TcpConnection() freeSslClientKeyCert(); #endif debugf("~TCP connection"); + + if(destroyedDelegate) { + destroyedDelegate(*this); + } } bool TcpConnection::connect(String server, int port, bool useSsl /* = false */, uint32_t sslOptions /* = 0 */) @@ -698,12 +702,19 @@ void TcpConnection::staticDnsResponse(const char *name, ip_addr_t *ipaddr, void delete dlook; } +void TcpConnection::setDestroyedDelegate(TcpConnectionDestroyedDelegate destroyedDelegate) +{ + this->destroyedDelegate = destroyedDelegate; +} + #ifdef ENABLE_SSL -void TcpConnection::addSslOptions(uint32_t sslOptions) { +void TcpConnection::addSslOptions(uint32_t sslOptions) +{ this->sslOptions |= sslOptions; } -bool TcpConnection::pinCertificate(const uint8_t *fingerprint, SslFingerprintType type, bool freeAfterHandshake /* = false */) { +bool TcpConnection::pinCertificate(const uint8_t *fingerprint, SslFingerprintType type, bool freeAfterHandshake /* = false */) +{ int length = 0; uint8_t *localStore; @@ -749,7 +760,8 @@ bool TcpConnection::pinCertificate(const uint8_t *fingerprint, SslFingerprintTyp return true; } -bool TcpConnection::pinCertificate(SSLFingerprints fingerprints, bool freeAfterHandshake /* = false */) { +bool TcpConnection::pinCertificate(SSLFingerprints fingerprints, bool freeAfterHandshake /* = false */) +{ sslFingerprint = fingerprints; freeFingerprints = freeAfterHandshake; return true; @@ -757,7 +769,8 @@ bool TcpConnection::pinCertificate(SSLFingerprints fingerprints, bool freeAfterH bool TcpConnection::setSslClientKeyCert(const uint8_t *key, int keyLength, const uint8_t *certificate, int certificateLength, - const char *keyPassword /* = NULL */, bool freeAfterHandshake /* = false */) { + const char *keyPassword /* = NULL */, bool freeAfterHandshake /* = false */) +{ clientKeyCert.key = new uint8_t[keyLength]; @@ -785,14 +798,16 @@ bool TcpConnection::setSslClientKeyCert(const uint8_t *key, int keyLength, return true; } -bool TcpConnection::setSslClientKeyCert(SSLKeyCertPair clientKeyCert, bool freeAfterHandshake /* = false */) { +bool TcpConnection::setSslClientKeyCert(SSLKeyCertPair clientKeyCert, bool freeAfterHandshake /* = false */) +{ this->clientKeyCert = clientKeyCert; freeClientKeyCert = freeAfterHandshake; return true; } -void TcpConnection::freeSslClientKeyCert() { +void TcpConnection::freeSslClientKeyCert() +{ if(clientKeyCert.key) { delete[] clientKeyCert.key; clientKeyCert.key = NULL; @@ -812,7 +827,8 @@ void TcpConnection::freeSslClientKeyCert() { clientKeyCert.certificateLength = 0; } -void TcpConnection::freeSslFingerprints() { +void TcpConnection::freeSslFingerprints() +{ if(sslFingerprint.certSha1) { delete[] sslFingerprint.certSha1; sslFingerprint.certSha1 = NULL; diff --git a/Sming/SmingCore/Network/TcpConnection.h b/Sming/SmingCore/Network/TcpConnection.h index a902e3b55a..932e4dc7fe 100644 --- a/Sming/SmingCore/Network/TcpConnection.h +++ b/Sming/SmingCore/Network/TcpConnection.h @@ -20,6 +20,7 @@ #include "../Wiring/WiringFrameworkDependencies.h" #include "IPAddress.h" +#include "../Delegate.h" #define NETWORK_DEBUG @@ -71,6 +72,9 @@ class String; class IDataSourceStream; class IPAddress; class TcpServer; +class TcpConnection; + +typedef Delegate TcpConnectionDestroyedDelegate; class TcpConnection { @@ -99,6 +103,12 @@ class TcpConnection IPAddress getRemoteIp() { return (tcp == NULL) ? INADDR_NONE : IPAddress(tcp->remote_ip);}; uint16_t getRemotePort() { return (tcp == NULL) ? 0 : tcp->remote_port; }; + /** + * @brief Sets a callback to be called when the object instance is destroyed + * @param TcpServerConnectionDestroyedDelegate destroyedDelegate - callback + */ + void setDestroyedDelegate(TcpConnectionDestroyedDelegate destroyedDelegate); + #ifdef ENABLE_SSL void addSslOptions(uint32_t sslOptions); @@ -234,6 +244,9 @@ class TcpConnection SSLSessionId* sslSessionId = NULL; #endif bool useSsl = false; + +private: + TcpConnectionDestroyedDelegate destroyedDelegate = 0; }; /** @} */ diff --git a/Sming/SmingCore/Network/TcpServer.cpp b/Sming/SmingCore/Network/TcpServer.cpp index 828d725563..32362f2d70 100644 --- a/Sming/SmingCore/Network/TcpServer.cpp +++ b/Sming/SmingCore/Network/TcpServer.cpp @@ -63,6 +63,11 @@ TcpConnection* TcpServer::createClient(tcp_pcb *clientTcp) debugf("TCP Server createClient not NULL"); } + if(!active) { + debugf("Refusing new connections. The server is shutting down"); + return NULL; + } + TcpConnection* con = new TcpClient(clientTcp, TcpClientDataDelegate(&TcpServer::onClientReceive,this), TcpClientCompleteDelegate(&TcpServer::onClientComplete,this)); @@ -83,7 +88,8 @@ void TcpServer::setTimeOut(uint16_t waitTimeOut) } #ifdef ENABLE_SSL -void TcpServer::setServerKeyCert(SSLKeyCertPair serverKeyCert) { +void TcpServer::setServerKeyCert(SSLKeyCertPair serverKeyCert) +{ clientKeyCert = serverKeyCert; } #endif @@ -148,7 +154,7 @@ err_t TcpServer::onAccept(tcp_pcb *clientTcp, err_t err) } #ifdef NETWORK_DEBUG - debugf("onAccept state: %d K=%d", err, totalConnections); + debugf("onAccept state: %d K=%d", err, connections.count()); list_mem(); #endif @@ -177,6 +183,11 @@ err_t TcpServer::onAccept(tcp_pcb *clientTcp, err_t err) } #endif + client->setDestroyedDelegate(TcpConnectionDestroyedDelegate(&TcpServer::onClientDestroy, this)); + + connections.add(client); + debugf("Opening connection. Total connections: %d", connections.count()); + onClient((TcpClient*)client); return ERR_OK; @@ -231,3 +242,43 @@ err_t TcpServer::staticAccept(void *arg, tcp_pcb *new_tcp, err_t err) err_t res = con->onAccept(new_tcp, err); return res; } + + +void TcpServer::shutdown() +{ + active = false; + + debugf("Shutting down the server ..."); + + if(tcp) { + tcp_arg(tcp, NULL); + tcp_accept(tcp, NULL); + tcp_close(tcp); + + tcp = NULL; + } + + for(int i=0; i < connections.count(); i++) { + TcpConnection* connection = connections[i]; + if(connection == NULL) { + continue; + } + + connection->setTimeOut(1); + } +} + +void TcpServer::onClientDestroy(TcpConnection& connection) +{ + connections.removeElement((TcpConnection*)&connection); + debugf("Destroying connection. Total connections: %d", connections.count()); + + if(active) { + return; + } + + if(connections.count() == 0) { + debugf("Server is destroyed."); + delete this; + } +} diff --git a/Sming/SmingCore/Network/TcpServer.h b/Sming/SmingCore/Network/TcpServer.h index f70d69b171..39e88d36a4 100644 --- a/Sming/SmingCore/Network/TcpServer.h +++ b/Sming/SmingCore/Network/TcpServer.h @@ -33,6 +33,8 @@ class TcpServer: public TcpConnection { virtual bool listen(int port, bool useSsl = false); void setTimeOut(uint16_t waitTimeOut); + void shutdown(); + #ifdef ENABLE_SSL /** * @brief Adds SSL support and specifies the server certificate and private key. @@ -46,8 +48,9 @@ class TcpServer: public TcpConnection { virtual err_t onAccept(tcp_pcb *clientTcp, err_t err); virtual void onClient(TcpClient *client); - virtual void onClientComplete(TcpClient& client, bool succesfull); virtual bool onClientReceive (TcpClient& client, char *data, int size); + virtual void onClientComplete(TcpClient& client, bool succesfull); + virtual void onClientDestroy(TcpConnection& connection); static err_t staticAccept(void *arg, tcp_pcb *new_tcp, err_t err); @@ -62,6 +65,9 @@ class TcpServer: public TcpConnection { int sslSessionCacheSize = 50; #endif + bool active = true; + Vector connections; + private: uint16_t timeOut; TcpClientDataDelegate clientReceiveDelegate = NULL;