+ public:
+ HttpServerSocket(int newfd, const std::string& IP, ListenSocket* via, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server, unsigned int timeoutsec)
+ : BufferedSocket(newfd)
+ , Timer(timeoutsec)
+ , ip(IP)
+ , status_code(0)
+ , waitingcull(false)
+ , messagecomplete(false)
+ {
+ if ((!via->iohookprovs.empty()) && (via->iohookprovs.back()))
+ {
+ via->iohookprovs.back()->OnAccept(this, client, server);
+ // IOHook may have errored
+ if (!getError().empty())
+ {
+ ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "HTTP socket %d encountered a hook error: %s",
+ GetFd(), getError().c_str());
+ Close();
+ return;
+ }
+ }
+
+ parser.data = this;
+ http_parser_init(&parser, HTTP_REQUEST);
+ ServerInstance->Timers.AddTimer(this);
+ }
+
+ ~HttpServerSocket()
+ {
+ sockets.erase(this);
+ }
+
+ void Close() CXX11_OVERRIDE
+ {
+ if (waitingcull || !HasFd())
+ return;
+
+ waitingcull = true;
+ BufferedSocket::Close();
+ ServerInstance->GlobalCulls.AddItem(this);
+ }
+
+ void OnError(BufferedSocketError err) CXX11_OVERRIDE
+ {
+ ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "HTTP socket %d encountered an error: %d - %s",
+ GetFd(), err, getError().c_str());
+ Close();
+ }
+
+ void SendHTTPError(unsigned int response, const char* errstr = NULL)
+ {
+ if (!errstr)
+ errstr = http_status_str((http_status)response);
+
+ ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Sending HTTP error %u: %s", response, errstr);
+ static HTTPHeaders empty;
+ std::string data = InspIRCd::Format(
+ "<html><head></head><body style='font-family: sans-serif; text-align: center'>"
+ "<h1 style='font-size: 48pt'>Error %u</h1><h2 style='font-size: 24pt'>%s</h2><hr>"
+ "<small>Powered by <a href='https://www.inspircd.org'>InspIRCd</a></small></body></html>",
+ response, errstr);
+
+ Page(data, response, &empty);
+ }
+
+ void SendHeaders(unsigned long size, unsigned int response, HTTPHeaders &rheaders)
+ {
+ WriteData(InspIRCd::Format("HTTP/%u.%u %u %s\r\n", parser.http_major ? parser.http_major : 1, parser.http_major ? parser.http_minor : 1, response, http_status_str((http_status)response)));