summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlinuxdaemon <linuxdaemon@users.noreply.github.com>2019-05-22 13:47:17 -0500
committerPeter Powell <petpow@saberuk.com>2019-05-22 19:47:17 +0100
commitde7011e54ad88656e01c92a88dd053a94b5acc6b (patch)
tree713d80e075dd880f0d635eee297bd313441b0337 /src
parent05756b842f26c647e527ec186c192c8cf448113f (diff)
Add an overload of StreamSocket::Close which closes when all data has been written.
Fixes sending large pages in m_httpd (#1646).
Diffstat (limited to 'src')
-rw-r--r--src/inspsocket.cpp20
-rw-r--r--src/modules/m_httpd.cpp27
2 files changed, 39 insertions, 8 deletions
diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp
index 59d9558a4..684ee051d 100644
--- a/src/inspsocket.cpp
+++ b/src/inspsocket.cpp
@@ -95,6 +95,10 @@ BufferedSocketError BufferedSocket::BeginConnect(const irc::sockets::sockaddrs&
void StreamSocket::Close()
{
+ if (closing)
+ return;
+
+ closing = true;
if (this->fd > -1)
{
// final chance, dump as much of the sendq as we can
@@ -114,6 +118,14 @@ void StreamSocket::Close()
}
}
+void StreamSocket::Close(bool writeblock)
+{
+ if (getSendQSize() != 0 && writeblock)
+ closeonempty = true;
+ else
+ Close();
+}
+
CullResult StreamSocket::cull()
{
Close();
@@ -206,7 +218,12 @@ static const int MYIOV_MAX = IOV_MAX < 128 ? IOV_MAX : 128;
void StreamSocket::DoWrite()
{
if (getSendQSize() == 0)
+ {
+ if (closeonempty)
+ Close();
+
return;
+ }
if (!error.empty() || fd < 0)
{
ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "DoWrite on errored or closed socket");
@@ -242,6 +259,9 @@ void StreamSocket::DoWrite()
if (psendq)
FlushSendQ(*psendq);
+
+ if (getSendQSize() == 0 && closeonempty)
+ Close();
}
void StreamSocket::FlushSendQ(SendQueue& sq)
diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp
index 8c409cbcb..dadd2f257 100644
--- a/src/modules/m_httpd.cpp
+++ b/src/modules/m_httpd.cpp
@@ -72,11 +72,17 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru
/** True if this object is in the cull list
*/
bool waitingcull;
+ bool messagecomplete;
bool Tick(time_t currtime) CXX11_OVERRIDE
{
- AddToCull();
- return false;
+ if (!messagecomplete)
+ {
+ AddToCull();
+ return false;
+ }
+
+ return true;
}
template<int (HttpServerSocket::*f)()>
@@ -186,6 +192,7 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru
int OnMessageComplete()
{
+ messagecomplete = true;
ServeData();
return 0;
}
@@ -197,6 +204,7 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru
, ip(IP)
, status_code(0)
, waitingcull(false)
+ , messagecomplete(false)
{
if ((!via->iohookprovs.empty()) && (via->iohookprovs.back()))
{
@@ -231,9 +239,7 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru
"<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));
- SendHeaders(data.length(), response, empty);
- WriteData(data);
- Close();
+ Page(data, response, &empty);
}
void SendHeaders(unsigned long size, unsigned int response, HTTPHeaders &rheaders)
@@ -286,11 +292,16 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru
}
}
+ void Page(const std::string& s, unsigned int response, HTTPHeaders* hheaders)
+ {
+ SendHeaders(s.length(), response, *hheaders);
+ WriteData(s);
+ Close(true);
+ }
+
void Page(std::stringstream* n, unsigned int response, HTTPHeaders* hheaders)
{
- SendHeaders(n->str().length(), response, *hheaders);
- WriteData(n->str());
- Close();
+ Page(n->str(), response, hheaders);
}
void AddToCull()