From c0f946f2b7195e101cdaae9d5453e0027d4204b4 Mon Sep 17 00:00:00 2001 From: attilamolnar Date: Mon, 9 Sep 2013 13:30:31 +0200 Subject: m_httpd Close all open http sockets on unload --- src/modules/m_httpd.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'src/modules/m_httpd.cpp') diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp index 37f715a8d..6315809a9 100644 --- a/src/modules/m_httpd.cpp +++ b/src/modules/m_httpd.cpp @@ -32,6 +32,7 @@ class ModuleHttpServer; static ModuleHttpServer* HttpModule; static bool claimed; +static std::set sockets; /** HTTP socket states */ @@ -69,6 +70,11 @@ class HttpServerSocket : public BufferedSocket GetIOHook()->OnStreamSocketAccept(this, client, server); } + ~HttpServerSocket() + { + sockets.erase(this); + } + virtual void OnError(BufferedSocketError) { ServerInstance->GlobalCulls.AddItem(this); @@ -333,7 +339,6 @@ class HttpServerSocket : public BufferedSocket class ModuleHttpServer : public Module { - std::vector httpsocks; public: void init() @@ -358,18 +363,21 @@ class ModuleHttpServer : public Module int port; std::string incomingip; irc::sockets::satoap(*client, incomingip, port); - new HttpServerSocket(nfd, incomingip, from, client, server); + sockets.insert(new HttpServerSocket(nfd, incomingip, from, client, server)); return MOD_RES_ALLOW; } - - virtual ~ModuleHttpServer() + CullResult cull() { - for (size_t i = 0; i < httpsocks.size(); i++) + std::set local; + local.swap(sockets); + for (std::set::const_iterator i = local.begin(); i != local.end(); ++i) { - httpsocks[i]->cull(); - delete httpsocks[i]; + HttpServerSocket* sock = *i; + sock->cull(); + delete sock; } + return Module::cull(); } virtual Version GetVersion() -- cgit v1.3.1-10-gc9f91 From ef264e2dca03126e1ea38ee05594bd015384622b Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Mon, 20 Jan 2014 16:57:30 +0100 Subject: m_httpd Add timeout option; remove timed out connections --- docs/conf/modules.conf.example | 3 +++ src/modules/m_httpd.cpp | 32 +++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) (limited to 'src/modules/m_httpd.cpp') diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example index b65a0ca02..09a8514a4 100644 --- a/docs/conf/modules.conf.example +++ b/docs/conf/modules.conf.example @@ -870,6 +870,9 @@ # a tag with type "httpd", and load at least one of the other # m_httpd_* modules to provide pages to display. # +# You can adjust the timeout for HTTP connections below. All HTTP +# connections will be closed after (roughly) this many seconds. +# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # http ACL module: Provides access control lists for m_httpd dependent diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp index 6315809a9..a853e12c2 100644 --- a/src/modules/m_httpd.cpp +++ b/src/modules/m_httpd.cpp @@ -59,9 +59,11 @@ class HttpServerSocket : public BufferedSocket std::string http_version; public: + const time_t createtime; HttpServerSocket(int newfd, const std::string& IP, ListenSocket* via, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) : BufferedSocket(newfd), ip(IP), postsize(0) + , createtime(ServerInstance->Time()) { InternalState = HTTP_SERVE_WAIT_REQUEST; @@ -339,12 +341,22 @@ class HttpServerSocket : public BufferedSocket class ModuleHttpServer : public Module { + unsigned int timeoutsec; + public: void init() { HttpModule = this; - ServerInstance->Modules->Attach(I_OnAcceptConnection, this); + Implementation eventlist[] = { I_OnAcceptConnection, I_OnBackgroundTimer, I_OnRehash }; + ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); + OnRehash(NULL); + } + + void OnRehash(User* user) + { + ConfigTag* tag = ServerInstance->Config->ConfValue("httpd"); + timeoutsec = tag->getInt("timeout"); } void OnRequest(Request& request) @@ -367,6 +379,24 @@ class ModuleHttpServer : public Module return MOD_RES_ALLOW; } + void OnBackgroundTimer(time_t curtime) + { + if (!timeoutsec) + return; + + time_t oldest_allowed = curtime - timeoutsec; + for (std::set::const_iterator i = sockets.begin(); i != sockets.end(); ) + { + HttpServerSocket* sock = *i; + ++i; + if (sock->createtime < oldest_allowed) + { + sock->cull(); + delete sock; + } + } + } + CullResult cull() { std::set local; -- cgit v1.3.1-10-gc9f91