Skip to content

Commit

Permalink
Moved the general server code from HttpServer to TcpServer.
Browse files Browse the repository at this point in the history
It should be possible to shut down cleanly all servers that inherit from TcpServer.
  • Loading branch information
slav-at-attachix committed Nov 9, 2017
1 parent ed35208 commit decbf7c
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 95 deletions.
9 changes: 0 additions & 9 deletions Sming/SmingCore/Network/Http/HttpServerConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,6 @@ HttpServerConnection::~HttpServerConnection()
if(this->resource) {
this->resource->shutdown(*this);
}

if(destroyedDelegate) {
destroyedDelegate();
}
}

void HttpServerConnection::setResourceTree(ResourceTree* resourceTree)
Expand Down Expand Up @@ -547,8 +543,3 @@ void HttpServerConnection::sendError(const char* message /* = NULL*/, enum http_

send();
}

void HttpServerConnection::setDestroyedDelegate(HttpServerConnectionDestroyedDelegate destroyedDelegate)
{
this->destroyedDelegate = destroyedDelegate;
}
11 changes: 0 additions & 11 deletions Sming/SmingCore/Network/Http/HttpServerConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
class HttpServerConnection;

typedef Delegate<void(HttpServerConnection& connection)> HttpServerConnectionDelegate;
typedef Delegate<void()> HttpServerConnectionDestroyedDelegate;


class HttpServerConnection: public TcpClient
{
Expand All @@ -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);
Expand Down Expand Up @@ -103,8 +94,6 @@ class HttpServerConnection: public TcpClient

BodyParsers* bodyParsers = NULL;
HttpBodyParserDelegate bodyParser;

HttpServerConnectionDestroyedDelegate destroyedDelegate = 0;
};

#endif /* _SMING_CORE_HTTPSERVERCONNECTION_H_ */
60 changes: 2 additions & 58 deletions Sming/SmingCore/Network/HttpServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
}
7 changes: 0 additions & 7 deletions Sming/SmingCore/Network/HttpServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -93,9 +89,6 @@ class HttpServer: public TcpServer
HttpServerSettings settings;
ResourceTree resourceTree;
BodyParsers bodyParsers;
bool active = true;

Vector<HttpServerConnection*> connections;
};

/** @} */
Expand Down
30 changes: 23 additions & 7 deletions Sming/SmingCore/Network/TcpConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 */)
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -749,15 +760,17 @@ 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;
}

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];
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
13 changes: 13 additions & 0 deletions Sming/SmingCore/Network/TcpConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "../Wiring/WiringFrameworkDependencies.h"
#include "IPAddress.h"
#include "../Delegate.h"


#define NETWORK_DEBUG
Expand Down Expand Up @@ -71,6 +72,9 @@ class String;
class IDataSourceStream;
class IPAddress;
class TcpServer;
class TcpConnection;

typedef Delegate<void(TcpConnection&)> TcpConnectionDestroyedDelegate;

class TcpConnection
{
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -234,6 +244,9 @@ class TcpConnection
SSLSessionId* sslSessionId = NULL;
#endif
bool useSsl = false;

private:
TcpConnectionDestroyedDelegate destroyedDelegate = 0;
};

/** @} */
Expand Down
55 changes: 53 additions & 2 deletions Sming/SmingCore/Network/TcpServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
}
Loading

0 comments on commit decbf7c

Please sign in to comment.