2011-04-09 21:34:04 +04:00
|
|
|
/*
|
|
|
|
This file is part of the PhantomJS project from Ofi Labs.
|
|
|
|
|
|
|
|
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
2011-08-31 19:29:40 +04:00
|
|
|
Copyright (C) 2011 Ivan De Marino <ivan.de.marino@gmail.com>
|
2011-04-09 21:34:04 +04:00
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions are met:
|
|
|
|
|
|
|
|
* Redistributions of source code must retain the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
* Redistributions in binary form must reproduce the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer in the
|
|
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
* Neither the name of the <organization> nor the
|
|
|
|
names of its contributors may be used to endorse or promote products
|
|
|
|
derived from this software without specific prior written permission.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
|
|
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
|
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
|
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
|
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
2011-06-09 10:32:14 +04:00
|
|
|
#include <QDateTime>
|
2011-04-08 22:28:39 +04:00
|
|
|
#include <QList>
|
2011-04-12 18:21:09 +04:00
|
|
|
#include <QDesktopServices>
|
2011-08-14 12:39:02 +04:00
|
|
|
#include <QNetworkRequest>
|
|
|
|
#include <QNetworkReply>
|
2011-04-12 18:21:09 +04:00
|
|
|
#include <QNetworkDiskCache>
|
2011-09-02 19:35:58 +04:00
|
|
|
#include <QAuthenticator>
|
2011-04-08 20:55:10 +04:00
|
|
|
|
|
|
|
#include "networkaccessmanager.h"
|
2011-08-14 12:39:02 +04:00
|
|
|
#include "networkreplyproxy.h"
|
2011-07-19 21:32:42 +04:00
|
|
|
#include "cookiejar.h"
|
2011-04-08 20:55:10 +04:00
|
|
|
|
2011-06-07 10:56:23 +04:00
|
|
|
static const char *toString(QNetworkAccessManager::Operation op)
|
|
|
|
{
|
|
|
|
const char *str = 0;
|
|
|
|
switch (op) {
|
|
|
|
case QNetworkAccessManager::HeadOperation:
|
|
|
|
str = "HEAD";
|
|
|
|
break;
|
|
|
|
case QNetworkAccessManager::GetOperation:
|
|
|
|
str = "GET";
|
|
|
|
break;
|
|
|
|
case QNetworkAccessManager::PutOperation:
|
|
|
|
str = "PUT";
|
|
|
|
break;
|
|
|
|
case QNetworkAccessManager::PostOperation:
|
|
|
|
str = "POST";
|
|
|
|
break;
|
|
|
|
case QNetworkAccessManager::DeleteOperation:
|
|
|
|
str = "DELETE";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
str = "?";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2011-04-08 20:55:10 +04:00
|
|
|
// public:
|
2011-09-07 03:33:11 +04:00
|
|
|
NetworkAccessManager::NetworkAccessManager(QObject *parent, bool diskCacheEnabled, QString cookieFile, bool ignoreSslErrors, QString authUser, QString authPass, int maxCacheSize)
|
2011-06-08 18:52:19 +04:00
|
|
|
: QNetworkAccessManager(parent)
|
|
|
|
, m_networkDiskCache(0)
|
|
|
|
, m_ignoreSslErrors(ignoreSslErrors)
|
2011-09-02 19:35:58 +04:00
|
|
|
, m_authUser(authUser)
|
|
|
|
, m_authPass(authPass)
|
2011-06-08 18:52:19 +04:00
|
|
|
, m_idCounter(0)
|
2011-04-08 20:55:10 +04:00
|
|
|
{
|
2011-07-19 21:32:42 +04:00
|
|
|
if (!cookieFile.isEmpty()) {
|
|
|
|
setCookieJar(new CookieJar(cookieFile));
|
|
|
|
}
|
|
|
|
|
2011-04-12 18:21:09 +04:00
|
|
|
if (diskCacheEnabled) {
|
|
|
|
m_networkDiskCache = new QNetworkDiskCache();
|
|
|
|
m_networkDiskCache->setCacheDirectory(QDesktopServices::storageLocation(QDesktopServices::CacheLocation));
|
2011-09-07 03:33:11 +04:00
|
|
|
if (maxCacheSize >= 0)
|
|
|
|
m_networkDiskCache->setMaximumCacheSize(maxCacheSize * 1024);
|
2011-04-12 18:21:09 +04:00
|
|
|
setCache(m_networkDiskCache);
|
|
|
|
}
|
2011-09-02 19:35:58 +04:00
|
|
|
|
|
|
|
connect(this, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(provideAuthenication(QNetworkReply*,QAuthenticator*)));
|
2011-04-08 22:28:39 +04:00
|
|
|
connect(this, SIGNAL(finished(QNetworkReply*)), SLOT(handleFinished(QNetworkReply*)));
|
2011-04-08 20:55:10 +04:00
|
|
|
}
|
|
|
|
|
2011-04-12 18:21:09 +04:00
|
|
|
NetworkAccessManager::~NetworkAccessManager()
|
|
|
|
{
|
|
|
|
if (m_networkDiskCache)
|
|
|
|
delete m_networkDiskCache;
|
|
|
|
}
|
|
|
|
|
2011-04-08 20:55:10 +04:00
|
|
|
// protected:
|
|
|
|
QNetworkReply *NetworkAccessManager::createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData)
|
|
|
|
{
|
|
|
|
// Pass duty to the superclass - Nothing special to do here (yet?)
|
2011-04-29 12:24:35 +04:00
|
|
|
QNetworkReply *reply = QNetworkAccessManager::createRequest(op, req, outgoingData);
|
|
|
|
if(m_ignoreSslErrors) {
|
|
|
|
reply->ignoreSslErrors();
|
|
|
|
}
|
2011-06-07 10:56:23 +04:00
|
|
|
|
2011-06-07 11:19:12 +04:00
|
|
|
QVariantList headers;
|
|
|
|
foreach (QByteArray headerName, req.rawHeaderList()) {
|
|
|
|
QVariantMap header;
|
|
|
|
header["name"] = QString::fromUtf8(headerName);
|
|
|
|
header["value"] = QString::fromUtf8(req.rawHeader(headerName));
|
|
|
|
headers += header;
|
|
|
|
}
|
|
|
|
|
2011-06-08 18:52:19 +04:00
|
|
|
m_idCounter++;
|
|
|
|
m_ids[reply] = m_idCounter;
|
|
|
|
|
2011-06-07 10:56:23 +04:00
|
|
|
QVariantMap data;
|
2011-06-08 18:52:19 +04:00
|
|
|
data["id"] = m_idCounter;
|
2011-06-07 10:56:23 +04:00
|
|
|
data["url"] = req.url().toString();
|
|
|
|
data["method"] = toString(op);
|
2011-06-07 11:19:12 +04:00
|
|
|
data["headers"] = headers;
|
2011-06-09 10:32:14 +04:00
|
|
|
data["time"] = QDateTime::currentDateTime();
|
2011-06-07 10:56:23 +04:00
|
|
|
|
2011-06-08 12:01:30 +04:00
|
|
|
connect(reply, SIGNAL(readyRead()), this, SLOT(handleStarted()));
|
|
|
|
|
2011-06-07 10:56:23 +04:00
|
|
|
emit resourceRequested(data);
|
2011-08-14 12:39:02 +04:00
|
|
|
return new NetworkReplyProxy(this, reply);
|
2011-04-08 20:55:10 +04:00
|
|
|
}
|
2011-04-08 22:28:39 +04:00
|
|
|
|
2011-06-08 12:01:30 +04:00
|
|
|
void NetworkAccessManager::handleStarted()
|
2011-04-08 22:28:39 +04:00
|
|
|
{
|
2011-06-08 12:01:30 +04:00
|
|
|
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
|
|
|
if (!reply)
|
|
|
|
return;
|
2011-06-08 18:57:51 +04:00
|
|
|
if (m_started.contains(reply))
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_started += reply;
|
2011-06-08 12:01:30 +04:00
|
|
|
|
|
|
|
QVariantList headers;
|
|
|
|
foreach (QByteArray headerName, reply->rawHeaderList()) {
|
|
|
|
QVariantMap header;
|
|
|
|
header["name"] = QString::fromUtf8(headerName);
|
|
|
|
header["value"] = QString::fromUtf8(reply->rawHeader(headerName));
|
|
|
|
headers += header;
|
2011-04-13 18:45:54 +04:00
|
|
|
}
|
2011-06-08 12:01:30 +04:00
|
|
|
|
|
|
|
QVariantMap data;
|
|
|
|
data["stage"] = "start";
|
2011-06-08 18:52:19 +04:00
|
|
|
data["id"] = m_ids.value(reply);
|
2011-06-08 12:01:30 +04:00
|
|
|
data["url"] = reply->url().toString();
|
|
|
|
data["status"] = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
2011-06-09 10:28:54 +04:00
|
|
|
data["statusText"] = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute);
|
|
|
|
data["contentType"] = reply->header(QNetworkRequest::ContentTypeHeader);
|
|
|
|
data["bodySize"] = reply->size();
|
|
|
|
data["redirectURL"] = reply->header(QNetworkRequest::LocationHeader);
|
2011-06-08 12:01:30 +04:00
|
|
|
data["headers"] = headers;
|
2011-06-09 10:32:14 +04:00
|
|
|
data["time"] = QDateTime::currentDateTime();
|
2011-06-08 12:01:30 +04:00
|
|
|
|
|
|
|
emit resourceReceived(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void NetworkAccessManager::handleFinished(QNetworkReply *reply)
|
|
|
|
{
|
|
|
|
QVariantList headers;
|
|
|
|
foreach (QByteArray headerName, reply->rawHeaderList()) {
|
|
|
|
QVariantMap header;
|
|
|
|
header["name"] = QString::fromUtf8(headerName);
|
|
|
|
header["value"] = QString::fromUtf8(reply->rawHeader(headerName));
|
|
|
|
headers += header;
|
2011-04-08 22:28:39 +04:00
|
|
|
}
|
2011-06-08 12:01:30 +04:00
|
|
|
|
|
|
|
QVariantMap data;
|
|
|
|
data["stage"] = "end";
|
2011-06-08 18:52:19 +04:00
|
|
|
data["id"] = m_ids.value(reply);
|
2011-06-08 12:01:30 +04:00
|
|
|
data["url"] = reply->url().toString();
|
|
|
|
data["status"] = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
2011-06-09 10:28:54 +04:00
|
|
|
data["statusText"] = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute);
|
|
|
|
data["contentType"] = reply->header(QNetworkRequest::ContentTypeHeader);
|
|
|
|
data["redirectURL"] = reply->header(QNetworkRequest::LocationHeader);
|
2011-06-08 12:01:30 +04:00
|
|
|
data["headers"] = headers;
|
2011-06-09 10:32:14 +04:00
|
|
|
data["time"] = QDateTime::currentDateTime();
|
2011-06-08 12:01:30 +04:00
|
|
|
|
2011-08-14 12:39:02 +04:00
|
|
|
NetworkReplyProxy *nrp = qobject_cast<NetworkReplyProxy*>(reply);
|
|
|
|
data["text"] = nrp->body();
|
|
|
|
|
2011-06-08 18:52:19 +04:00
|
|
|
m_ids.remove(reply);
|
2011-06-08 18:57:51 +04:00
|
|
|
m_started.remove(reply);
|
2011-06-08 18:52:19 +04:00
|
|
|
|
2011-06-08 12:01:30 +04:00
|
|
|
emit resourceReceived(data);
|
2011-04-08 22:28:39 +04:00
|
|
|
}
|
2011-09-02 19:35:58 +04:00
|
|
|
|
|
|
|
void NetworkAccessManager::provideAuthenication(QNetworkReply *reply, QAuthenticator *ator)
|
|
|
|
{
|
2011-09-05 18:23:52 +04:00
|
|
|
Q_UNUSED(reply);
|
2011-09-02 19:35:58 +04:00
|
|
|
ator->setUser(m_authUser);
|
|
|
|
ator->setPassword(m_authPass);
|
|
|
|
}
|