1
1
mirror of https://github.com/ariya/phantomjs.git synced 2024-09-11 12:55:33 +03:00

response body is only available in onResourceReceived event,

if url matches one of the patterns in 'page.captureContent' property

https://github.com/ariya/phantomjs/issues/10158
This commit is contained in:
Dmitry Parshin 2014-04-24 22:44:44 -04:00 committed by Vitaly Slobodin
parent d0fde08979
commit 327f91d60c
9 changed files with 132 additions and 8 deletions

View File

@ -254,6 +254,28 @@ QVariantMap NetworkAccessManager::customHeaders() const
return m_customHeaders;
}
QStringList NetworkAccessManager::captureContent() const
{
return m_captureContentPatterns;
}
void NetworkAccessManager::setCaptureContent(const QStringList &patterns)
{
m_captureContentPatterns = patterns;
compileCaptureContentPatterns();
}
void NetworkAccessManager::compileCaptureContentPatterns()
{
for(QStringList::const_iterator it = m_captureContentPatterns.constBegin();
it != m_captureContentPatterns.constEnd(); ++it) {
m_compiledCaptureContentPatterns.append(QRegExp(*it, Qt::CaseInsensitive));
}
}
void NetworkAccessManager::setCookieJar(QNetworkCookieJar *cookieJar)
{
QNetworkAccessManager::setCookieJar(cookieJar);
@ -322,7 +344,9 @@ QNetworkReply *NetworkAccessManager::createRequest(Operation op, const QNetworkR
emit resourceRequested(data, &jsNetworkRequest);
QNetworkReply *nested_reply = QNetworkAccessManager::createRequest(op, req, outgoingData);
QNetworkReply *tracked_reply = m_replyTracker.trackReply(nested_reply, m_idCounter);
QNetworkReply *tracked_reply = m_replyTracker.trackReply(nested_reply,
m_idCounter,
shouldCaptureResponse(req.url().toString()));
// reparent jsNetworkRequest to make sure that it will be destroyed with QNetworkReply
jsNetworkRequest.setParent(tracked_reply);
@ -343,6 +367,19 @@ QNetworkReply *NetworkAccessManager::createRequest(Operation op, const QNetworkR
return tracked_reply;
}
bool NetworkAccessManager::shouldCaptureResponse(const QString& url)
{
for(QList<QRegExp>::const_iterator it = m_compiledCaptureContentPatterns.constBegin();
it != m_compiledCaptureContentPatterns.constEnd(); ++it) {
if(-1 != it->indexIn(url)) {
return true;
}
}
return false;
}
void NetworkAccessManager::handleTimeout()
{
TimeoutTimer *nt = qobject_cast<TimeoutTimer*>(sender());

View File

@ -36,6 +36,7 @@
#include <QNetworkReply>
#include <QSslConfiguration>
#include <QTimer>
#include <QStringList>
#include "networkreplytracker.h"
@ -90,6 +91,8 @@ public:
void setResourceTimeout(int resourceTimeout);
void setCustomHeaders(const QVariantMap &headers);
QVariantMap customHeaders() const;
QStringList captureContent() const;
void setCaptureContent(const QStringList &patterns);
void setCookieJar(QNetworkCookieJar *cookieJar);
@ -118,9 +121,15 @@ private slots:
void handleTimeout();
private:
bool shouldCaptureResponse(const QString& url);
void compileCaptureContentPatterns();
int m_idCounter;
QNetworkDiskCache* m_networkDiskCache;
QVariantMap m_customHeaders;
QStringList m_captureContentPatterns;
QList<QRegExp> m_compiledCaptureContentPatterns;
QSslConfiguration m_sslConfiguration;
NetworkReplyTracker m_replyTracker;

View File

@ -32,9 +32,11 @@
#include "networkreplyproxy.h"
NetworkReplyProxy::NetworkReplyProxy(QObject* parent, QNetworkReply* reply)
NetworkReplyProxy::NetworkReplyProxy(QObject* parent, QNetworkReply* reply,
bool shouldCaptureResponse)
: QNetworkReply(parent)
, m_reply(reply)
, m_shouldCaptureResponseBody(shouldCaptureResponse)
{
// apply attributes...
setOperation(m_reply->operation());
@ -154,8 +156,10 @@ void NetworkReplyProxy::readInternal()
{
QByteArray data = m_reply->readAll();
//this is a response buffer, whole response is stored here
m_data += data;
if(m_shouldCaptureResponseBody) {
//this is a response buffer, whole response is stored here
m_data += data;
}
//this is a temporary buffer, data is wiped after a call to 'readData'
m_buffer += data;

View File

@ -43,8 +43,11 @@ public:
/*
reply - reply to be proxied(nested reply)
shouldCaptureResponseBody - if true, response body will be collected and
available through body() method
*/
NetworkReplyProxy(QObject* parent, QNetworkReply* reply);
NetworkReplyProxy(QObject* parent, QNetworkReply* reply,
bool shouldCaptureResponseBody);
/*
@ -88,6 +91,7 @@ private:
QNetworkReply* m_reply;
QByteArray m_data;
QByteArray m_buffer;
bool m_shouldCaptureResponseBody;
};
#endif // NETWORKREPLYPROXY_H

View File

@ -37,9 +37,10 @@ NetworkReplyTracker::NetworkReplyTracker(QObject* parent)
}
QNetworkReply* NetworkReplyTracker::trackReply(QNetworkReply *reply, int requestId)
QNetworkReply* NetworkReplyTracker::trackReply(QNetworkReply *reply, int requestId,
bool shouldCaptureResponseBody)
{
NetworkReplyProxy *proxy = new NetworkReplyProxy(this, reply);
NetworkReplyProxy *proxy = new NetworkReplyProxy(this, reply, shouldCaptureResponseBody);
/*
Tracking link between proxy and proxied reply.

View File

@ -54,8 +54,10 @@ public:
/*
reply - reply to track
requestId - unique request id, used to distinguis replies internally
shouldCaptureResponseBody - if true, response body will be available in 'finished' signal
*/
QNetworkReply* trackReply(QNetworkReply *reply, int requestId);
QNetworkReply* trackReply(QNetworkReply *reply, int requestId,
bool shouldCaptureResponseBody);
/*

View File

@ -775,6 +775,16 @@ QVariantMap WebPage::customHeaders() const
return m_networkAccessManager->customHeaders();
}
QStringList WebPage::captureContent() const
{
return m_networkAccessManager->captureContent();
}
void WebPage::setCaptureContent(const QStringList &patterns)
{
m_networkAccessManager->setCaptureContent(patterns);
}
void WebPage::setCookieJar(CookieJar *cookieJar) {
m_cookieJar = cookieJar;
m_customWebPage->setCookieJar(m_cookieJar);

View File

@ -81,6 +81,7 @@ class WebPage : public QObject, public QWebFrame::PrintCallback
Q_PROPERTY(QString focusedFrameName READ focusedFrameName)
Q_PROPERTY(QObject *cookieJar READ cookieJar WRITE setCookieJarFromQObject)
Q_PROPERTY(QVariantList cookies READ cookies WRITE setCookies)
Q_PROPERTY(QStringList captureContent READ captureContent WRITE setCaptureContent)
public:
WebPage(QObject *parent, const QUrl &baseUrl = QUrl());
@ -184,6 +185,25 @@ public:
* Pages that this page has currently open.
*/
QStringList pagesWindowName() const;
/**
* Returns a list of URL patterns, for which response body
* will be captured and returned in onResourceReceived event
*
* @brief captureContent
* @return List (JS Array) containing currently set patterns
*/
QStringList captureContent() const;
/**
* Allows to set a list of URL patterns, for which response body
* will be captured and returned in onResourceReceived event
*
* EXAMPLE: page.captureContent = ['/foo/', '\.jpg' ]
*
* @brief captureContent
* @param patterns Expects a QList of QString
*/
void setCaptureContent(const QStringList &patterns);
/**
* Returns "true" if it owns the pages it creates (and keeps them in "pages[]").

View File

@ -182,6 +182,8 @@ describe("WebPage object", function() {
it("should contain resource body when last chunk of resource received", function() {
var page = require('webpage').create();
page.captureContent = ['/foo'];
var server = require('webserver').create();
server.listen(12345, function(request, response) {
response.statusCode = 200;
@ -212,6 +214,41 @@ describe("WebPage object", function() {
});
it("should not contain resource body if not in the captureContent list", function() {
var page = require('webpage').create();
page.captureContent = ['/foo'];
var server = require('webserver').create();
server.listen(12345, function(request, response) {
response.statusCode = 200;
response.write('resource body');
response.close();
});
var url = "http://localhost:12345/some/other/url";
var lastChunk = "";
var bodySize = 0;
runs(function() {
page.onResourceReceived = function(resource) {
lastChunk = resource.body;
bodySize = resource.bodySize;
};
page.open(url, function(status) {
});
});
waits(50);
runs(function() {
expect(lastChunk).toEqual('');
expect(0).toEqual(lastChunk.length);
page.onResourceReceived = null;
server.close();
});
});
it("should set valid cookie properly, then remove it", function() {
var server = require('webserver').create();
server.listen(12345, function(request, response) {