mirror of https://github.com/vitalif/phantomjs
WebPage: network timeout setting.
Fixes issue #11129. https://github.com/ariya/phantomjs/issues/111291.9
parent
b16a5348a9
commit
52883ced68
|
@ -58,6 +58,7 @@
|
|||
#define PAGE_SETTINGS_USERNAME "userName"
|
||||
#define PAGE_SETTINGS_PASSWORD "password"
|
||||
#define PAGE_SETTINGS_MAX_AUTH_ATTEMPTS "maxAuthAttempts"
|
||||
#define PAGE_SETTINGS_RESOURCE_TIMEOUT "resourceTimeout"
|
||||
#define PAGE_SETTINGS_WEB_SECURITY_ENABLED "webSecurityEnabled"
|
||||
#define PAGE_SETTINGS_JS_CAN_OPEN_WINDOWS "javascriptCanOpenWindows"
|
||||
#define PAGE_SETTINGS_JS_CAN_CLOSE_WINDOWS "javascriptCanCloseWindows"
|
||||
|
|
|
@ -254,6 +254,8 @@ function decorateNewPage(opts, page) {
|
|||
|
||||
definePageSignalHandler(page, handlers, "onResourceError", "resourceError");
|
||||
|
||||
definePageSignalHandler(page, handlers, "onResourceTimeout", "resourceTimeout");
|
||||
|
||||
definePageSignalHandler(page, handlers, "onAlert", "javaScriptAlertSent");
|
||||
|
||||
definePageSignalHandler(page, handlers, "onConsoleMessage", "javaScriptConsoleMessageSent");
|
||||
|
|
|
@ -67,6 +67,12 @@ static const char *toString(QNetworkAccessManager::Operation op)
|
|||
return str;
|
||||
}
|
||||
|
||||
TimeoutTimer::TimeoutTimer(QObject* parent)
|
||||
: QTimer(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
JsNetworkRequest::JsNetworkRequest(QNetworkRequest* request, QObject* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
|
@ -97,6 +103,7 @@ NetworkAccessManager::NetworkAccessManager(QObject *parent, const Config *config
|
|||
, m_idCounter(0)
|
||||
, m_networkDiskCache(0)
|
||||
, m_sslConfiguration(QSslConfiguration::defaultConfiguration())
|
||||
, m_resourceTimeout(0)
|
||||
{
|
||||
setCookieJar(CookieJar::instance());
|
||||
|
||||
|
@ -141,6 +148,11 @@ void NetworkAccessManager::setPassword(const QString &password)
|
|||
m_password = password;
|
||||
}
|
||||
|
||||
void NetworkAccessManager::setResourceTimeout(int resourceTimeout)
|
||||
{
|
||||
m_resourceTimeout = resourceTimeout;
|
||||
}
|
||||
|
||||
void NetworkAccessManager::setMaxAuthAttempts(int maxAttempts)
|
||||
{
|
||||
m_maxAuthAttempts = maxAttempts;
|
||||
|
@ -223,6 +235,19 @@ QNetworkReply *NetworkAccessManager::createRequest(Operation op, const QNetworkR
|
|||
// reparent jsNetworkRequest to make sure that it will be destroyed with QNetworkReply
|
||||
jsNetworkRequest.setParent(reply);
|
||||
|
||||
// If there is a timeout set, create a TimeoutTimer
|
||||
if(m_resourceTimeout > 0){
|
||||
|
||||
TimeoutTimer *nt = new TimeoutTimer(reply);
|
||||
nt->reply = reply; // We need the reply object in order to abort it later on.
|
||||
nt->data = data;
|
||||
nt->setInterval(m_resourceTimeout);
|
||||
nt->setSingleShot(true);
|
||||
nt->start();
|
||||
|
||||
connect(nt, SIGNAL(timeout()), this, SLOT(handleTimeout()));
|
||||
}
|
||||
|
||||
m_ids[reply] = m_idCounter;
|
||||
|
||||
connect(reply, SIGNAL(readyRead()), this, SLOT(handleStarted()));
|
||||
|
@ -232,6 +257,22 @@ QNetworkReply *NetworkAccessManager::createRequest(Operation op, const QNetworkR
|
|||
return reply;
|
||||
}
|
||||
|
||||
void NetworkAccessManager::handleTimeout()
|
||||
{
|
||||
TimeoutTimer *nt = qobject_cast<TimeoutTimer*>(sender());
|
||||
|
||||
if(!nt->reply)
|
||||
return;
|
||||
|
||||
nt->data["errorCode"] = 408;
|
||||
nt->data["errorString"] = "Network timeout on resource.";
|
||||
|
||||
emit resourceTimeout(nt->data);
|
||||
|
||||
// Abort the reply that we attached to the Network Timeout
|
||||
nt->reply->abort();
|
||||
}
|
||||
|
||||
void NetworkAccessManager::handleStarted()
|
||||
{
|
||||
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
||||
|
|
|
@ -37,11 +37,22 @@
|
|||
#include <QNetworkReply>
|
||||
#include <QSet>
|
||||
#include <QSslConfiguration>
|
||||
#include <QTimer>
|
||||
|
||||
class Config;
|
||||
class QNetworkDiskCache;
|
||||
class QSslConfiguration;
|
||||
|
||||
class TimeoutTimer : public QTimer
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TimeoutTimer(QObject *parent = 0);
|
||||
QNetworkReply *reply;
|
||||
QVariantMap data;
|
||||
};
|
||||
|
||||
class JsNetworkRequest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -62,6 +73,7 @@ public:
|
|||
void setUserName(const QString &userName);
|
||||
void setPassword(const QString &password);
|
||||
void setMaxAuthAttempts(int maxAttempts);
|
||||
void setResourceTimeout(int resourceTimeout);
|
||||
void setCustomHeaders(const QVariantMap &headers);
|
||||
QVariantMap customHeaders() const;
|
||||
|
||||
|
@ -71,6 +83,7 @@ protected:
|
|||
bool m_ignoreSslErrors;
|
||||
int m_authAttempts;
|
||||
int m_maxAuthAttempts;
|
||||
int m_resourceTimeout;
|
||||
QString m_userName;
|
||||
QString m_password;
|
||||
QNetworkReply *createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData = 0);
|
||||
|
@ -80,6 +93,7 @@ signals:
|
|||
void resourceRequested(const QVariant& data, QObject *);
|
||||
void resourceReceived(const QVariant& data);
|
||||
void resourceError(const QVariant& data);
|
||||
void resourceTimeout(const QVariant& data);
|
||||
|
||||
private slots:
|
||||
void handleStarted();
|
||||
|
@ -87,6 +101,7 @@ private slots:
|
|||
void provideAuthentication(QNetworkReply *reply, QAuthenticator *authenticator);
|
||||
void handleSslErrors(const QList<QSslError> &errors);
|
||||
void handleNetworkError();
|
||||
void handleTimeout();
|
||||
|
||||
private:
|
||||
QHash<QNetworkReply*, int> m_ids;
|
||||
|
|
|
@ -386,6 +386,8 @@ WebPage::WebPage(QObject *parent, const QUrl &baseUrl)
|
|||
SIGNAL(resourceReceived(QVariant)));
|
||||
connect(m_networkAccessManager, SIGNAL(resourceError(QVariant)),
|
||||
SIGNAL(resourceError(QVariant)));
|
||||
connect(m_networkAccessManager, SIGNAL(resourceTimeout(QVariant)),
|
||||
SIGNAL(resourceTimeout(QVariant)));
|
||||
|
||||
m_customWebPage->setViewportSize(QSize(400, 300));
|
||||
}
|
||||
|
@ -583,6 +585,10 @@ void WebPage::applySettings(const QVariantMap &def)
|
|||
|
||||
if (def.contains(PAGE_SETTINGS_MAX_AUTH_ATTEMPTS))
|
||||
m_networkAccessManager->setMaxAuthAttempts(def[PAGE_SETTINGS_MAX_AUTH_ATTEMPTS].toInt());
|
||||
|
||||
if (def.contains(PAGE_SETTINGS_RESOURCE_TIMEOUT))
|
||||
m_networkAccessManager->setResourceTimeout(def[PAGE_SETTINGS_RESOURCE_TIMEOUT].toInt());
|
||||
|
||||
}
|
||||
|
||||
QString WebPage::userAgent() const
|
||||
|
|
|
@ -469,6 +469,7 @@ signals:
|
|||
void resourceRequested(const QVariant &requestData, QObject *request);
|
||||
void resourceReceived(const QVariant &resource);
|
||||
void resourceError(const QVariant &errorData);
|
||||
void resourceTimeout(const QVariant &errorData);
|
||||
void urlChanged(const QUrl &url);
|
||||
void navigationRequested(const QUrl &url, const QString &navigationType, bool navigationLocked, bool isMainFrame);
|
||||
void rawPageCreated(QObject *page);
|
||||
|
|
|
@ -1280,6 +1280,18 @@ describe("WebPage construction with options", function () {
|
|||
checkScrollPosition(new WebPage(opts), opts.scrollPosition);
|
||||
});
|
||||
|
||||
describe("specifying timeout", function () {
|
||||
var opts = {
|
||||
settings: {
|
||||
timeout: 100 // time in ms
|
||||
}
|
||||
};
|
||||
var page = new WebPage(opts);
|
||||
it("should have timeout as "+opts.settings.timeout,function () {
|
||||
expect(page.settings.timeout).toEqual(opts.settings.timeout);
|
||||
});
|
||||
});
|
||||
|
||||
describe("specifying userAgent", function () {
|
||||
var opts = {
|
||||
settings: {
|
||||
|
@ -1584,6 +1596,34 @@ describe("WebPage opening and closing of windows/child-pages", function(){
|
|||
});
|
||||
});
|
||||
|
||||
describe("WebPage timeout handling", function(){
|
||||
it("should call 'onResourceTimeout' on timeout", function(){
|
||||
var p = require("webpage").create(),
|
||||
spy;
|
||||
|
||||
// assume that requesting a web page will take longer than a millisecond
|
||||
p.settings.resourceTimeout = 1;
|
||||
|
||||
spy = jasmine.createSpy("onResourceTimeout spy");
|
||||
p.onResourceTimeout = spy;
|
||||
|
||||
expect(spy.calls.length).toEqual(0);
|
||||
|
||||
p.open("http://www.google.com:81/");
|
||||
|
||||
waitsFor(function() {
|
||||
return spy.calls.length==1;
|
||||
}, "after 1+ milliseconds 'onResourceTimeout' should have been invoked", 10);
|
||||
|
||||
runs(function() {
|
||||
expect(spy).toHaveBeenCalled(); //< called
|
||||
expect(spy.calls.length).toEqual(1); //< only once
|
||||
expect(1).toEqual(1);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe("WebPage closing notification/alerting", function(){
|
||||
it("should call 'onClosing' when 'page.close()' is called", function(){
|
||||
var p = require("webpage").create(),
|
||||
|
|
Loading…
Reference in New Issue