From f55b77a98a41ba784109842cde39ba0e1d2bc262 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 6 Oct 2013 16:40:28 +0200 Subject: Fixed memory leaks in the HTTP framework --- source/HTTPServer/HTTPConnection.cpp | 25 +++++++++++++++++++++++++ source/HTTPServer/HTTPConnection.h | 4 ++++ source/HTTPServer/HTTPServer.cpp | 5 +++-- source/WebAdmin.cpp | 13 +++++++++---- source/WebAdmin.h | 2 ++ 5 files changed, 43 insertions(+), 6 deletions(-) (limited to 'source') diff --git a/source/HTTPServer/HTTPConnection.cpp b/source/HTTPServer/HTTPConnection.cpp index 2addf4cfc..68afdfc11 100644 --- a/source/HTTPServer/HTTPConnection.cpp +++ b/source/HTTPServer/HTTPConnection.cpp @@ -17,11 +17,22 @@ cHTTPConnection::cHTTPConnection(cHTTPServer & a_HTTPServer) : m_State(wcsRecvHeaders), m_CurrentRequest(NULL) { + // LOGD("HTTP: New connection at %p", this); } + +cHTTPConnection::~cHTTPConnection() +{ + // LOGD("HTTP: Del connection at %p", this); +} + + + + + void cHTTPConnection::SendStatusAndReason(int a_StatusCode, const AString & a_Response) { AppendPrintf(m_OutgoingData, "%d %s\r\nContent-Length: 0\r\n\r\n", a_StatusCode, a_Response.c_str()); @@ -120,6 +131,19 @@ void cHTTPConnection::AwaitNextRequest(void) +void cHTTPConnection::Terminate(void) +{ + if (m_CurrentRequest != NULL) + { + m_HTTPServer.RequestFinished(*this, *m_CurrentRequest); + } + m_HTTPServer.CloseConnection(*this); +} + + + + + void cHTTPConnection::DataReceived(const char * a_Data, int a_Size) { switch (m_State) @@ -214,6 +238,7 @@ void cHTTPConnection::SocketClosed(void) { m_HTTPServer.RequestFinished(*this, *m_CurrentRequest); } + m_HTTPServer.CloseConnection(*this); } diff --git a/source/HTTPServer/HTTPConnection.h b/source/HTTPServer/HTTPConnection.h index 941a29000..14603bb70 100644 --- a/source/HTTPServer/HTTPConnection.h +++ b/source/HTTPServer/HTTPConnection.h @@ -39,6 +39,7 @@ public: } ; cHTTPConnection(cHTTPServer & a_HTTPServer); + ~cHTTPConnection(); /// Sends HTTP status code together with a_Reason (used for HTTP errors) void SendStatusAndReason(int a_StatusCode, const AString & a_Reason); @@ -61,6 +62,9 @@ public: /// Resets the connection for a new request. Depending on the state, this will send an "InternalServerError" status or a "ResponseEnd" void AwaitNextRequest(void); + /// Terminates the connection; finishes any request being currently processed + void Terminate(void); + protected: typedef std::map cNameValueMap; diff --git a/source/HTTPServer/HTTPServer.cpp b/source/HTTPServer/HTTPServer.cpp index 9636eb59f..f6f5b0f8b 100644 --- a/source/HTTPServer/HTTPServer.cpp +++ b/source/HTTPServer/HTTPServer.cpp @@ -179,9 +179,9 @@ void cHTTPServer::Stop(void) // Drop all current connections: cCSLock Lock(m_CSConnections); - for (cHTTPConnections::iterator itr = m_Connections.begin(), end = m_Connections.end(); itr != end; ++itr) + while (!m_Connections.empty()) { - m_SocketThreads.RemoveClient(*itr); + m_Connections.front()->Terminate(); } // for itr - m_Connections[] } @@ -213,6 +213,7 @@ void cHTTPServer::CloseConnection(cHTTPConnection & a_Connection) break; } } + delete &a_Connection; } diff --git a/source/WebAdmin.cpp b/source/WebAdmin.cpp index 378a5966c..c917ec658 100644 --- a/source/WebAdmin.cpp +++ b/source/WebAdmin.cpp @@ -488,15 +488,20 @@ void cWebAdmin::OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & ) { HandleWebadminRequest(a_Connection, a_Request); - return; } - if (URL == "/") + else if (URL == "/") { // The root needs no body handler and is fully handled in the OnRequestFinished() call HandleRootRequest(a_Connection, a_Request); - return; } - // TODO: Handle other requests + else + { + // TODO: Handle other requests + } + + // Delete any request data assigned to the request: + cRequestData * Data = (cRequestData *)(a_Request.GetUserData()); + delete Data; } diff --git a/source/WebAdmin.h b/source/WebAdmin.h index 271f819d6..16b5dd4dc 100644 --- a/source/WebAdmin.h +++ b/source/WebAdmin.h @@ -134,6 +134,8 @@ protected: class cRequestData { public: + virtual ~cRequestData() {} // Force a virtual destructor in all descendants + /// Called when a new chunk of body data is received virtual void OnBody(const char * a_Data, int a_Size) = 0; } ; -- cgit v1.2.3