/*
* InspIRCd -- Internet Relay Chat Daemon
*
+ * Copyright (C) 2019 linuxdaemon <linuxdaemon.irc@gmail.com>
+ * Copyright (C) 2018 edef <edef@edef.eu>
+ * Copyright (C) 2013-2014, 2017-2020 Sadie Powell <sadie@witchery.services>
+ * Copyright (C) 2012-2016 Attila Molnar <attilamolnar@hush.com>
+ * Copyright (C) 2012 Robby <robby@chatbelgie.be>
+ * Copyright (C) 2009 Uli Schlachter <psychon@inspircd.org>
* Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- * Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
- * Copyright (C) 2008 Pippijn van Steenhoven <pip88nl@gmail.com>
- * Copyright (C) 2006-2008 Craig Edwards <craigedwards@brainbox.cc>
- * Copyright (C) 2007 John Brooks <john.brooks@dereferenced.net>
+ * Copyright (C) 2008 Robin Burchell <robin+git@viroteck.net>
+ * Copyright (C) 2007 John Brooks <special@inspircd.org>
* Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
+ * Copyright (C) 2006, 2008, 2010 Craig Edwards <brain@inspircd.org>
*
* This file is part of InspIRCd. InspIRCd is free software: you can
* redistribute it and/or modify it under the terms of the GNU General Public
#include "iohook.h"
#include "modules/httpd.h"
+#ifdef __GNUC__
+# pragma GCC diagnostic push
+#endif
+
// Fix warnings about the use of commas at end of enumerator lists and long long
-// on C++03 and warnings about shadowing in the http_parser library.
+// on C++03.
#if defined __clang__
# pragma clang diagnostic ignored "-Wc++11-extensions"
# pragma clang diagnostic ignored "-Wc++11-long-long"
#elif defined __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
-# pragma GCC diagnostic ignored "-Wshadow"
# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8))
# pragma GCC diagnostic ignored "-Wpedantic"
# else
# endif
#endif
+// Fix warnings about shadowing in http_parser.
+#ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wshadow"
+#endif
+
#include <http_parser.c>
+#ifdef __GNUC__
+# pragma GCC diagnostic pop
+#endif
+
class ModuleHttpServer;
static ModuleHttpServer* HttpModule;
{
if (!messagecomplete)
{
- AddToCull();
+ ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "HTTP socket %d timed out", GetFd());
+ Close();
return false;
}
// IOHook may have errored
if (!getError().empty())
{
- AddToCull();
+ ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "HTTP socket %d encountered a hook error: %s",
+ GetFd(), getError().c_str());
+ Close();
return;
}
}
sockets.erase(this);
}
- void OnError(BufferedSocketError) CXX11_OVERRIDE
+ void Close() CXX11_OVERRIDE
+ {
+ if (waitingcull || !HasFd())
+ return;
+
+ waitingcull = true;
+ BufferedSocket::Close();
+ ServerInstance->GlobalCulls.AddItem(this);
+ }
+
+ void OnError(BufferedSocketError err) CXX11_OVERRIDE
{
- AddToCull();
+ 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)
+ void SendHTTPError(unsigned int response, const char* errstr = NULL)
{
- HTTPHeaders empty;
+ 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>Server error %u: %s<br>"
- "<small>Powered by <a href='https://www.inspircd.org'>InspIRCd</a></small></body></html>", response, http_status_str((http_status)response));
+ "<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);
}
else
rheaders.RemoveHeader("Content-Type");
- /* Supporting Connection: keep-alive causes a whole world of hurt syncronizing timeouts,
+ /* Supporting Connection: keep-alive causes a whole world of hurt synchronizing timeouts,
* so remove it, its not essential for what we need.
*/
rheaders.SetHeader("Connection", "Close");
if (parser.upgrade || HTTP_PARSER_ERRNO(&parser))
return;
http_parser_execute(&parser, &parser_settings, recvq.data(), recvq.size());
- if (parser.upgrade || HTTP_PARSER_ERRNO(&parser))
+ if (parser.upgrade)
SendHTTPError(status_code ? status_code : 400);
+ else if (HTTP_PARSER_ERRNO(&parser))
+ SendHTTPError(status_code ? status_code : 400, http_errno_description((http_errno)parser.http_errno));
}
void ServeData()
FIRST_MOD_RESULT_CUSTOM(*aclevprov, HTTPACLEventListener, OnHTTPACLCheck, MOD_RESULT, (acl));
if (MOD_RESULT != MOD_RES_DENY)
{
- HTTPRequest url(method, parsed, &headers, this, ip, body);
- FIRST_MOD_RESULT_CUSTOM(*reqevprov, HTTPRequestEventListener, OnHTTPRequest, MOD_RESULT, (url));
+ HTTPRequest request(method, parsed, &headers, this, ip, body);
+ FIRST_MOD_RESULT_CUSTOM(*reqevprov, HTTPRequestEventListener, OnHTTPRequest, MOD_RESULT, (request));
if (MOD_RESULT == MOD_RES_PASSTHRU)
{
SendHTTPError(404);
{
SendHeaders(s.length(), response, *hheaders);
WriteData(s);
- Close(true);
+ BufferedSocket::Close(true);
}
void Page(std::stringstream* n, unsigned int response, HTTPHeaders* hheaders)
Page(n->str(), response, hheaders);
}
- void AddToCull()
- {
- if (waitingcull)
- return;
-
- waitingcull = true;
- Close();
- ServerInstance->GlobalCulls.AddItem(this);
- }
-
- bool ParseURI(const std::string& uri, HTTPRequestURI& out)
+ bool ParseURI(const std::string& uristr, HTTPRequestURI& out)
{
http_parser_url_init(&url);
- if (http_parser_parse_url(uri.c_str(), uri.size(), 0, &url) != 0)
+ if (http_parser_parse_url(uristr.c_str(), uristr.size(), 0, &url) != 0)
return false;
if (url.field_set & (1 << UF_PATH))
for (insp::intrusive_list<HttpServerSocket>::const_iterator i = sockets.begin(); i != sockets.end(); ++i)
{
HttpServerSocket* sock = *i;
- sock->AddToCull();
+ sock->Close();
}
return Module::cull();
}
Version GetVersion() CXX11_OVERRIDE
{
- return Version("Provides HTTP serving facilities to modules", VF_VENDOR);
+ return Version("Allows the server administrator to serve various useful resources over HTTP.", VF_VENDOR);
}
};