#include "iohook.h"
#include "modules/httpd.h"
-/* $ModDep: modules/httpd.h */
-
class ModuleHttpServer;
static ModuleHttpServer* HttpModule;
static bool claimed;
+static insp::intrusive_list<HttpServerSocket> sockets;
/** HTTP socket states
*/
/** A socket used for HTTP transport
*/
-class HttpServerSocket : public BufferedSocket
+class HttpServerSocket : public BufferedSocket, public Timer, public insp::intrusive_list_node<HttpServerSocket>
{
HttpState InternalState;
std::string ip;
std::string uri;
std::string http_version;
+ /** True if this object is in the cull list
+ */
+ bool waitingcull;
+
+ bool Tick(time_t currtime) CXX11_OVERRIDE
+ {
+ AddToCull();
+ return false;
+ }
+
public:
- HttpServerSocket(int newfd, const std::string& IP, ListenSocket* via, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server)
- : BufferedSocket(newfd), ip(IP), postsize(0)
+ HttpServerSocket(int newfd, const std::string& IP, ListenSocket* via, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server, unsigned int timeoutsec)
+ : BufferedSocket(newfd)
+ , Timer(timeoutsec)
+ , InternalState(HTTP_SERVE_WAIT_REQUEST)
+ , ip(IP)
+ , postsize(0)
+ , waitingcull(false)
{
- InternalState = HTTP_SERVE_WAIT_REQUEST;
+ ServerInstance->Timers.AddTimer(this);
- FOREACH_MOD(I_OnHookIO, OnHookIO(this, via));
- if (GetIOHook())
- GetIOHook()->OnStreamSocketAccept(this, client, server);
+ if (via->iohookprov)
+ via->iohookprov->OnAccept(this, client, server);
+ }
+
+ ~HttpServerSocket()
+ {
+ sockets.erase(this);
}
void OnError(BufferedSocketError) CXX11_OVERRIDE
{
- ServerInstance->GlobalCulls.AddItem(this);
+ AddToCull();
}
std::string Response(int response)
case 300:
return "MULTIPLE CHOICES";
case 301:
- return "MOVED PERMENANTLY";
+ return "MOVED PERMANENTLY";
case 302:
return "FOUND";
case 303:
WriteData(http_version + " "+ConvToStr(response)+" "+Response(response)+"\r\n");
- time_t local = ServerInstance->Time();
- struct tm *timeinfo = gmtime(&local);
- char *date = asctime(timeinfo);
- date[strlen(date) - 1] = '\0';
- rheaders.CreateHeader("Date", date);
-
- rheaders.CreateHeader("Server", BRANCH);
+ rheaders.CreateHeader("Date", InspIRCd::TimeString(ServerInstance->Time(), "%a, %d %b %Y %H:%M:%S GMT", true));
+ rheaders.CreateHeader("Server", INSPIRCD_BRANCH);
rheaders.SetHeader("Content-Length", ConvToStr(size));
if (size)
if (reqbuffer.length() >= 8192)
{
- ServerInstance->Logs->Log("m_httpd", LOG_DEBUG, "m_httpd dropped connection due to an oversized request buffer");
+ ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "m_httpd dropped connection due to an oversized request buffer");
reqbuffer.clear();
SetError("Buffer");
}
SendHeaders(n->str().length(), response, *hheaders);
WriteData(n->str());
}
+
+ void AddToCull()
+ {
+ if (waitingcull)
+ return;
+
+ waitingcull = true;
+ Close();
+ ServerInstance->GlobalCulls.AddItem(this);
+ }
};
class HTTPdAPIImpl : public HTTPdAPIBase
class ModuleHttpServer : public Module
{
- std::vector<HttpServerSocket *> httpsocks;
HTTPdAPIImpl APIImpl;
+ unsigned int timeoutsec;
public:
ModuleHttpServer()
void init() CXX11_OVERRIDE
{
HttpModule = this;
- ServerInstance->Modules->AddService(APIImpl);
- ServerInstance->Modules->Attach(I_OnAcceptConnection, this);
+ }
+
+ void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
+ {
+ ConfigTag* tag = ServerInstance->Config->ConfValue("httpd");
+ timeoutsec = tag->getInt("timeout", 10, 1);
}
ModResult OnAcceptConnection(int nfd, ListenSocket* from, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) CXX11_OVERRIDE
int port;
std::string incomingip;
irc::sockets::satoap(*client, incomingip, port);
- new HttpServerSocket(nfd, incomingip, from, client, server);
+ sockets.push_front(new HttpServerSocket(nfd, incomingip, from, client, server, timeoutsec));
return MOD_RES_ALLOW;
}
- ~ModuleHttpServer()
+ CullResult cull() CXX11_OVERRIDE
{
- for (size_t i = 0; i < httpsocks.size(); i++)
+ for (insp::intrusive_list<HttpServerSocket>::const_iterator i = sockets.begin(); i != sockets.end(); ++i)
{
- httpsocks[i]->cull();
- delete httpsocks[i];
+ HttpServerSocket* sock = *i;
+ sock->AddToCull();
}
+ return Module::cull();
}
Version GetVersion() CXX11_OVERRIDE