Skip to content

Commit

Permalink
add timeout to http filters
Browse files Browse the repository at this point in the history
  • Loading branch information
jkarneges committed Feb 13, 2025
1 parent 818f784 commit 4c0ccf4
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/core/httprequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class HttpRequest : public QObject
virtual void setIgnorePolicies(bool on) = 0;
virtual void setTrustConnectHost(bool on) = 0;
virtual void setIgnoreTlsErrors(bool on) = 0;
virtual void setTimeout(int msecs) = 0;

virtual void start(const QString &method, const QUrl &uri, const HttpHeaders &headers) = 0;
virtual void beginResponse(int code, const QByteArray &reason, const HttpHeaders &headers) = 0;
Expand Down
26 changes: 26 additions & 0 deletions src/core/zhttprequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class ZhttpRequest::Private : public QObject
bool ignorePolicies;
bool trustConnectHost;
bool ignoreTlsErrors;
int timeout;
bool sendBodyAfterAck;
QVariant passthrough;
QString requestMethod;
Expand Down Expand Up @@ -101,10 +102,12 @@ class ZhttpRequest::Private : public QObject
ErrorCondition errorCondition;
RTimer *expireTimer;
RTimer *keepAliveTimer;
RTimer *finishTimer;
bool multi;
bool quiet;
Connection expTimerConnection;
Connection keepAliveTimerConnection;
Connection finishTimerConnection;
DeferCall deferCall;

Private(ZhttpRequest *_q) :
Expand All @@ -118,6 +121,7 @@ class ZhttpRequest::Private : public QObject
ignorePolicies(false),
trustConnectHost(false),
ignoreTlsErrors(false),
timeout(0),
sendBodyAfterAck(false),
inSeq(0),
outSeq(0),
Expand All @@ -135,6 +139,7 @@ class ZhttpRequest::Private : public QObject
errored(false),
expireTimer(0),
keepAliveTimer(0),
finishTimer(0),
multi(false),
quiet(false)
{
Expand Down Expand Up @@ -176,6 +181,14 @@ class ZhttpRequest::Private : public QObject
keepAliveTimer = 0;
}

if(finishTimer)
{
finishTimerConnection.disconnect();
finishTimer->setParent(0);
DeferCall::deleteLater(finishTimer);
finishTimer = 0;
}

if(manager)
{
manager->unregisterKeepAlive(q);
Expand Down Expand Up @@ -281,6 +294,14 @@ class ZhttpRequest::Private : public QObject
{
state = ClientStarting;

if(timeout > 0)
{
finishTimer = new RTimer;
finishTimerConnection = finishTimer->timeout.connect(boost::bind(&Private::expire_timeout, this));
finishTimer->setSingleShot(true);
finishTimer->start(timeout);
}

refreshTimeout();
update();
}
Expand Down Expand Up @@ -1231,6 +1252,11 @@ void ZhttpRequest::setIgnoreTlsErrors(bool on)
d->ignoreTlsErrors = on;
}

void ZhttpRequest::setTimeout(int msecs)
{
d->timeout = msecs;
}

void ZhttpRequest::setIsTls(bool on)
{
d->requestUri.setScheme(on ? "https" : "http");
Expand Down
3 changes: 3 additions & 0 deletions src/core/zhttprequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include "httprequest.h"
#include <boost/signals2.hpp>

#define TIMERS_PER_ZHTTPREQUEST 3

using Connection = boost::signals2::scoped_connection;

class ZhttpRequestPacket;
Expand Down Expand Up @@ -89,6 +91,7 @@ class ZhttpRequest : public HttpRequest
virtual void setIgnorePolicies(bool on);
virtual void setTrustConnectHost(bool on);
virtual void setIgnoreTlsErrors(bool on);
virtual void setTimeout(int msecs);

virtual void start(const QString &method, const QUrl &uri, const HttpHeaders &headers);
virtual void beginResponse(int code, const QByteArray &reason, const HttpHeaders &headers);
Expand Down
31 changes: 30 additions & 1 deletion src/handler/filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include "zhttpmanager.h"
#include "zhttprequest.h"

#define REQUEST_TIMEOUT_SECS 10

namespace {

class SkipSelfFilter : public Filter, public Filter::MessageFilter
Expand Down Expand Up @@ -378,6 +380,9 @@ class HttpFilterInner

void startRequest()
{
// set timeout since filters should be fast
req->setTimeout(REQUEST_TIMEOUT_SECS * 1000);

req->start("POST", uri, headers);

if(mode == HttpFilter::Modify)
Expand Down Expand Up @@ -453,8 +458,32 @@ class HttpFilterInner

void req_error()
{
const char *s;

switch(req->errorCondition())
{
case HttpRequest::ErrorConnect:
s = "connection refused";
break;
case HttpRequest::ErrorConnectTimeout:
s = "connection timed out";
break;
case HttpRequest::ErrorTls:
s = "tls error";
break;
case HttpRequest::ErrorDisconnected:
s = "disconnected";
break;
case HttpRequest::ErrorTimeout:
s = "request timed out";
break;
default:
s = "general error";
break;
}

Filter::MessageFilter::Result r;
r.errorMessage = "network request failed";
r.errorMessage = QString("network request failed: %1").arg(s);
finished(r);
}
};
Expand Down
4 changes: 2 additions & 2 deletions src/handler/filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@
#include <QMetaType>
#include <QUrl>
#include <boost/signals2.hpp>
#include "zhttprequest.h"
#include "ratelimiter.h"

#define MESSAGEFILTERSTACK_SIZE_MAX 5

// 2 timers per zhttprequest
#define TIMERS_PER_MESSAGEFILTERSTACK (2 * MESSAGEFILTERSTACK_SIZE_MAX)
#define TIMERS_PER_MESSAGEFILTERSTACK (TIMERS_PER_ZHTTPREQUEST * MESSAGEFILTERSTACK_SIZE_MAX)

class ZhttpManager;

Expand Down
7 changes: 4 additions & 3 deletions src/handler/httpsession.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@
#include <boost/signals2.hpp>

// each session can have a bunch of timers:
// 2 per incoming zhttprequest
// 2 per outgoing zhttprequest
// incoming request
// outgoing request
// 2 additional timers
// filter timers
#define TIMERS_PER_HTTPSESSION (10 + TIMERS_PER_MESSAGEFILTERSTACK)
// a few more just in case
#define TIMERS_PER_HTTPSESSION ((TIMERS_PER_ZHTTPREQUEST * 2) + 2 + TIMERS_PER_MESSAGEFILTERSTACK + 4)

using Connection = boost::signals2::scoped_connection;

Expand Down
5 changes: 5 additions & 0 deletions src/proxy/testhttprequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ void TestHttpRequest::setIgnoreTlsErrors(bool on)
Q_UNUSED(on);
}

void TestHttpRequest::setTimeout(int msecs)
{
Q_UNUSED(msecs);
}

void TestHttpRequest::start(const QString &method, const QUrl &uri, const HttpHeaders &headers)
{
assert(d->state == Private::Idle);
Expand Down
1 change: 1 addition & 0 deletions src/proxy/testhttprequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class TestHttpRequest : public HttpRequest
virtual void setIgnorePolicies(bool on);
virtual void setTrustConnectHost(bool on);
virtual void setIgnoreTlsErrors(bool on);
virtual void setTimeout(int msecs);

virtual void start(const QString &method, const QUrl &uri, const HttpHeaders &headers);
virtual void beginResponse(int code, const QByteArray &reason, const HttpHeaders &headers);
Expand Down

0 comments on commit 4c0ccf4

Please sign in to comment.