X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_httpd.cpp;h=7c93a70b609418255da3bccd81854775039463f4;hb=bc344671460c1675fbc31504fd1ffc03ff58a135;hp=b8926083146208ea2611ba1f31d31d40f672466e;hpb=03e0fb206d3f5709868f03bc7a401cb666c38ffb;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp index b89260831..7c93a70b6 100644 --- a/src/modules/m_httpd.cpp +++ b/src/modules/m_httpd.cpp @@ -2,7 +2,7 @@ * | Inspire Internet Relay Chat Daemon | * +------------------------------------+ * - * InspIRCd: (C) 2002-2007 InspIRCd Development Team + * InspIRCd: (C) 2002-2008 InspIRCd Development Team * See: http://www.inspircd.org/wiki/index.php/Credits * * This program is free but copyrighted software; see @@ -32,31 +32,9 @@ enum HttpState HTTP_SERVE_SEND_DATA = 3 /* Sending response */ }; -class HttpServerSocket; - -/** This class is used to handle HTTP socket timeouts - */ -class HttpServerTimeout : public Timer -{ - private: - /** HttpServerSocket we are attached to - */ - HttpServerSocket* s; - /** Socketengine the file descriptor is in - */ - SocketEngine* SE; - public: - /** Attach timeout to HttpServerSocket - */ - HttpServerTimeout(HttpServerSocket* sock, SocketEngine* engine); - /** Handle timer tick - */ - void Tick(time_t TIME); -}; - /** A socket used for HTTP transport */ -class HttpServerSocket : public InspSocket +class HttpServerSocket : public BufferedSocket { FileReader* index; HttpState InternalState; @@ -68,25 +46,17 @@ class HttpServerSocket : public InspSocket std::string request_type; std::string uri; std::string http_version; - bool keepalive; - - HttpServerTimeout* Timeout; - bool DataSinceLastTick; - friend class HttpServerTimeout; public: - HttpServerSocket(InspIRCd* SI, std::string host, int port, bool listening, unsigned long maxtime, FileReader* index_page) : InspSocket(SI, host, port, listening, maxtime), index(index_page), postsize(0) + HttpServerSocket(InspIRCd* SI, std::string shost, int iport, bool listening, unsigned long maxtime, FileReader* index_page) : BufferedSocket(SI, shost, iport, listening, maxtime), index(index_page), postsize(0) { InternalState = HTTP_LISTEN; - Timeout = NULL; } - HttpServerSocket(InspIRCd* SI, int newfd, char* ip, FileReader* ind) : InspSocket(SI, newfd, ip), index(ind), postsize(0), keepalive(false), DataSinceLastTick(false) + HttpServerSocket(InspIRCd* SI, int newfd, char* ip, FileReader* ind) : BufferedSocket(SI, newfd, ip), index(ind), postsize(0) { InternalState = HTTP_SERVE_WAIT_REQUEST; - Timeout = new HttpServerTimeout(this, Instance->SE); - Instance->Timers->AddTimer(Timeout); } FileReader* GetIndex() @@ -96,26 +66,6 @@ class HttpServerSocket : public InspSocket ~HttpServerSocket() { - if (Timeout) - { - if (Instance->Time() < Timeout->GetTimer()) - Instance->Timers->DelTimer(Timeout); - Timeout = NULL; - } - } - - void ResetRequest() - { - headers.Clear(); - postdata.clear(); - postsize = 0; - request_type.clear(); - uri.clear(); - http_version.clear(); - InternalState = HTTP_SERVE_WAIT_REQUEST; - - if (reqbuffer.size()) - CheckRequestBuffer(); } virtual int OnIncomingConnection(int newsock, char* ip) @@ -230,9 +180,7 @@ class HttpServerSocket : public InspSocket SendHeaders(data.length(), response, empty); this->Write(data); - - if (keepalive) - ResetRequest(); + this->FlushWriteBuffer(); } void SendHeaders(unsigned long size, int response, HTTPHeaders &rheaders) @@ -246,7 +194,7 @@ class HttpServerSocket : public InspSocket date[strlen(date) - 1] = '\0'; rheaders.CreateHeader("Date", date); - rheaders.CreateHeader("Server", "InspIRCd/m_httpd.so/1.1"); + rheaders.CreateHeader("Server", "InspIRCd/m_httpd.so/1.2"); rheaders.SetHeader("Content-Length", ConvToStr(size)); if (size) @@ -254,30 +202,23 @@ class HttpServerSocket : public InspSocket else rheaders.RemoveHeader("Content-Type"); - if (rheaders.GetHeader("Connection") == "Close") - keepalive = false; - else if (rheaders.GetHeader("Connection") == "Keep-Alive" && !headers.IsSet("Connection")) - keepalive = true; - else if (!rheaders.IsSet("Connection") && !keepalive) - rheaders.SetHeader("Connection", "Close"); + /* Supporting Connection: keep-alive causes a whole world of hurt syncronizing timeouts, + * so remove it, its not essential for what we need. + */ + rheaders.SetHeader("Connection", "Close"); this->Write(rheaders.GetFormattedHeaders()); this->Write("\r\n"); - - if (!size && keepalive) - ResetRequest(); } virtual bool OnDataReady() { - char* data = this->Read(); + const char* data = this->Read(); /* Check that the data read is a valid pointer and it has some content */ if (!data || !*data) return false; - DataSinceLastTick = true; - if (InternalState == HTTP_SERVE_RECV_POSTDATA) { postdata.append(data); @@ -290,7 +231,7 @@ class HttpServerSocket : public InspSocket if (reqbuffer.length() >= 8192) { - Instance->Log(DEBUG, "m_httpd dropped connection due to an oversized request buffer"); + Instance->Logs->Log("m_httpd",DEBUG, "m_httpd dropped connection due to an oversized request buffer"); reqbuffer.clear(); return false; } @@ -325,6 +266,7 @@ class HttpServerSocket : public InspSocket if (request_type.empty() || uri.empty() || http_version.empty()) { SendHTTPError(400); + SetWrite(); return; } @@ -338,6 +280,7 @@ class HttpServerSocket : public InspSocket if ((fieldsep == std::string::npos) || (fieldsep == 0) || (fieldsep == cheader.length() - 1)) { SendHTTPError(400); + SetWrite(); return; } @@ -354,12 +297,10 @@ class HttpServerSocket : public InspSocket if ((http_version != "HTTP/1.1") && (http_version != "HTTP/1.0")) { SendHTTPError(505); + SetWrite(); return; } - - if (strcasecmp(headers.GetHeader("Connection").c_str(), "keep-alive") == 0) - keepalive = true; - + if (headers.IsSet("Content-Length") && (postsize = atoi(headers.GetHeader("Content-Length").c_str())) != 0) { InternalState = HTTP_SERVE_RECV_POSTDATA; @@ -393,51 +334,50 @@ class HttpServerSocket : public InspSocket HTTPHeaders empty; SendHeaders(index->ContentSize(), 200, empty); this->Write(index->Contents()); + this->FlushWriteBuffer(); + SetWrite(); } else { claimed = false; HTTPRequest httpr(request_type,uri,&headers,this,this->GetIP(),postdata); - Event e((char*)&httpr, (Module*)HttpModule, "httpd_url"); - e.Send(this->Instance); + Event acl((char*)&httpr, (Module*)HttpModule, "httpd_acl"); + acl.Send(this->Instance); if (!claimed) { - SendHTTPError(404); + Event e((char*)&httpr, (Module*)HttpModule, "httpd_url"); + e.Send(this->Instance); + if (!claimed) + { + SendHTTPError(404); + SetWrite(); + } } } } - void Page(std::stringstream* n, int response, HTTPHeaders *headers) + + bool OnWriteReady() { - SendHeaders(n->str().length(), response, *headers); - this->Write(n->str()); - - if (!keepalive) - { - Instance->SE->DelFd(this); - this->Close(); - } - else - this->ResetRequest(); + Instance->Logs->Log("m_httpd",DEBUG,"OnWriteReady()"); + return false; } -}; -HttpServerTimeout::HttpServerTimeout(HttpServerSocket* sock, SocketEngine* engine) : Timer(15, time(NULL), true), s(sock), SE(engine) -{ -} + void Page(std::stringstream* n, int response, HTTPHeaders *hheaders) + { + SendHeaders(n->str().length(), response, *hheaders); + this->Write(n->str()); + this->FlushWriteBuffer(); + SetWrite(); + } -void HttpServerTimeout::Tick(time_t TIME) -{ - if (!s->DataSinceLastTick) + void SetWrite() { - SE->DelFd(s); - s->Close(); - s->Timeout = NULL; - this->CancelRepeat(); + Instance->Logs->Log("m_httpd",DEBUG,"SetWrite()"); + this->WaitingForWriteEvent = true; + Instance->SE->WantWrite(this); } - else - s->DataSinceLastTick = false; -} +}; class ModuleHttpServer : public Module { @@ -474,9 +414,11 @@ class ModuleHttpServer : public Module { ReadConfig(); HttpModule = this; + Implementation eventlist[] = { I_OnRequest }; + ServerInstance->Modules->Attach(eventlist, this, 1); } - char* OnRequest(Request* request) + virtual const char* OnRequest(Request* request) { claimed = true; HTTPDocument* doc = (HTTPDocument*)request->GetData(); @@ -485,10 +427,6 @@ class ModuleHttpServer : public Module return NULL; } - void Implements(char* List) - { - List[I_OnRequest] = 1; - } virtual ~ModuleHttpServer() { @@ -498,12 +436,12 @@ class ModuleHttpServer : public Module httpsocks[i]->Close(); delete httpsocks[i]->GetIndex(); } - ServerInstance->InspSocketCull(); + ServerInstance->BufferedSocketCull(); } virtual Version GetVersion() { - return Version(1,1,0,0,VF_VENDOR|VF_SERVICEPROVIDER,API_VERSION); + return Version(1,2,0,0,VF_VENDOR|VF_SERVICEPROVIDER,API_VERSION); } };