summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
05756b8)
Fixes sending large pages in m_httpd (#1646).
+ /** Whether this socket should close once its sendq is empty */
+ bool closeonempty;
+
+ /** Whether the socket is currently closing or not, used to avoid repeatedly closing a closed socket */
+ bool closing;
+
/** The IOHook that handles raw I/O for this socket, or NULL */
IOHook* iohook;
/** The IOHook that handles raw I/O for this socket, or NULL */
IOHook* iohook;
public:
const Type type;
StreamSocket(Type sstype = SS_UNKNOWN)
public:
const Type type;
StreamSocket(Type sstype = SS_UNKNOWN)
+ : closeonempty(false)
+ , closing(false)
+ , iohook(NULL)
* Close the socket, remove from socket engine, etc
*/
virtual void Close();
* Close the socket, remove from socket engine, etc
*/
virtual void Close();
+
+ /** If writeblock is true then only close the socket if all data has been sent. Otherwise, close immediately. */
+ void Close(bool writeblock);
+
/** This ensures that close is called prior to destructor */
CullResult cull() CXX11_OVERRIDE;
/** This ensures that close is called prior to destructor */
CullResult cull() CXX11_OVERRIDE;
void StreamSocket::Close()
{
void StreamSocket::Close()
{
+ if (closing)
+ return;
+
+ closing = true;
if (this->fd > -1)
{
// final chance, dump as much of the sendq as we can
if (this->fd > -1)
{
// final chance, dump as much of the sendq as we can
+void StreamSocket::Close(bool writeblock)
+{
+ if (getSendQSize() != 0 && writeblock)
+ closeonempty = true;
+ else
+ Close();
+}
+
CullResult StreamSocket::cull()
{
Close();
CullResult StreamSocket::cull()
{
Close();
void StreamSocket::DoWrite()
{
if (getSendQSize() == 0)
void StreamSocket::DoWrite()
{
if (getSendQSize() == 0)
+ {
+ if (closeonempty)
+ Close();
+
if (!error.empty() || fd < 0)
{
ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "DoWrite on errored or closed socket");
if (!error.empty() || fd < 0)
{
ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "DoWrite on errored or closed socket");
if (psendq)
FlushSendQ(*psendq);
if (psendq)
FlushSendQ(*psendq);
+
+ if (getSendQSize() == 0 && closeonempty)
+ Close();
}
void StreamSocket::FlushSendQ(SendQueue& sq)
}
void StreamSocket::FlushSendQ(SendQueue& sq)
/** True if this object is in the cull list
*/
bool waitingcull;
/** True if this object is in the cull list
*/
bool waitingcull;
bool Tick(time_t currtime) CXX11_OVERRIDE
{
bool Tick(time_t currtime) CXX11_OVERRIDE
{
- AddToCull();
- return false;
+ if (!messagecomplete)
+ {
+ AddToCull();
+ return false;
+ }
+
+ return true;
}
template<int (HttpServerSocket::*f)()>
}
template<int (HttpServerSocket::*f)()>
int OnMessageComplete()
{
int OnMessageComplete()
{
+ messagecomplete = true;
, ip(IP)
, status_code(0)
, waitingcull(false)
, ip(IP)
, status_code(0)
, waitingcull(false)
+ , messagecomplete(false)
{
if ((!via->iohookprovs.empty()) && (via->iohookprovs.back()))
{
{
if ((!via->iohookprovs.empty()) && (via->iohookprovs.back()))
{
"<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>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)
}
void SendHeaders(unsigned long size, unsigned int response, HTTPHeaders &rheaders)
+ 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)
{
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);