diff --git a/src/networkaccessmanager.cpp b/src/networkaccessmanager.cpp index ce9a3bb1..d931fbd4 100644 --- a/src/networkaccessmanager.cpp +++ b/src/networkaccessmanager.cpp @@ -28,13 +28,14 @@ */ #include -#include #include -#include #include +#include +#include #include #include "networkaccessmanager.h" +#include "networkreplyproxy.h" #include "cookiejar.h" static const char *toString(QNetworkAccessManager::Operation op) @@ -118,7 +119,7 @@ QNetworkReply *NetworkAccessManager::createRequest(Operation op, const QNetworkR connect(reply, SIGNAL(readyRead()), this, SLOT(handleStarted())); emit resourceRequested(data); - return reply; + return new NetworkReplyProxy(this, reply); } void NetworkAccessManager::handleStarted() @@ -175,6 +176,9 @@ void NetworkAccessManager::handleFinished(QNetworkReply *reply) data["headers"] = headers; data["time"] = QDateTime::currentDateTime(); + NetworkReplyProxy *nrp = qobject_cast(reply); + data["text"] = nrp->body(); + m_ids.remove(reply); m_started.remove(reply); diff --git a/src/networkaccessmanager.h b/src/networkaccessmanager.h index 731e39df..b74f8ce8 100644 --- a/src/networkaccessmanager.h +++ b/src/networkaccessmanager.h @@ -32,6 +32,7 @@ #include #include +#include #include class QNetworkDiskCache; diff --git a/src/networkreplyproxy.cpp b/src/networkreplyproxy.cpp new file mode 100644 index 00000000..c5e39cbd --- /dev/null +++ b/src/networkreplyproxy.cpp @@ -0,0 +1,146 @@ +/* + This file is part of the PhantomJS project from Ofi Labs. + + Copyright (C) 2011 Ariya Hidayat + + 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 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 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. +*/ + +#include +#include + +#include "networkreplyproxy.h" + +NetworkReplyProxy::NetworkReplyProxy(QObject* parent, QNetworkReply* reply) + : QNetworkReply(parent) + , m_reply(reply) +{ + // apply attributes... + setOperation(m_reply->operation()); + setRequest(m_reply->request()); + setUrl(m_reply->url()); + + // handle these to forward + connect(m_reply, SIGNAL(metaDataChanged()), SLOT(applyMetaData())); + connect(m_reply, SIGNAL(readyRead()), SLOT(readInternal())); + connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(errorInternal(QNetworkReply::NetworkError))); + + // forward signals + connect(m_reply, SIGNAL(finished()), SIGNAL(finished())); + connect(m_reply, SIGNAL(uploadProgress(qint64,qint64)), SIGNAL(uploadProgress(qint64,qint64))); + connect(m_reply, SIGNAL(downloadProgress(qint64,qint64)), SIGNAL(downloadProgress(qint64,qint64))); + + // for the data proxy... + setOpenMode(ReadOnly); +} + +NetworkReplyProxy::~NetworkReplyProxy() +{ + delete m_reply; +} + +QString NetworkReplyProxy::body() +{ + return QString(m_data); +} + +void NetworkReplyProxy::abort() +{ + m_reply->abort(); +} + +void NetworkReplyProxy::close() +{ + m_reply->close(); +} + +bool NetworkReplyProxy::isSequential() const +{ + return m_reply->isSequential(); +} + +void NetworkReplyProxy::setReadBufferSize(qint64 size) +{ + QNetworkReply::setReadBufferSize(size); m_reply->setReadBufferSize(size); +} + +qint64 NetworkReplyProxy::bytesAvailable() const +{ + return m_buffer.size() + QIODevice::bytesAvailable(); +} + +qint64 NetworkReplyProxy::bytesToWrite() const +{ + return -1; +} + +qint64 NetworkReplyProxy::readData(char* data, qint64 maxlen) +{ + qint64 size = qMin(maxlen, qint64(m_buffer.size())); + memcpy(data, m_buffer.constData(), size); + m_buffer.remove(0, size); + return size; +} + +void NetworkReplyProxy::ignoreSslErrors() +{ + m_reply->ignoreSslErrors(); +} + +void NetworkReplyProxy::applyMetaData() +{ + QList headers = m_reply->rawHeaderList(); + foreach(QByteArray header, headers) + setRawHeader(header, m_reply->rawHeader(header)); + + setHeader(QNetworkRequest::ContentTypeHeader, m_reply->header(QNetworkRequest::ContentTypeHeader)); + setHeader(QNetworkRequest::ContentLengthHeader, m_reply->header(QNetworkRequest::ContentLengthHeader)); + setHeader(QNetworkRequest::LocationHeader, m_reply->header(QNetworkRequest::LocationHeader)); + setHeader(QNetworkRequest::LastModifiedHeader, m_reply->header(QNetworkRequest::LastModifiedHeader)); + setHeader(QNetworkRequest::SetCookieHeader, m_reply->header(QNetworkRequest::SetCookieHeader)); + + setAttribute(QNetworkRequest::HttpStatusCodeAttribute, m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute)); + setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute)); + setAttribute(QNetworkRequest::RedirectionTargetAttribute, m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute)); + setAttribute(QNetworkRequest::ConnectionEncryptedAttribute, m_reply->attribute(QNetworkRequest::ConnectionEncryptedAttribute)); + setAttribute(QNetworkRequest::CacheLoadControlAttribute, m_reply->attribute(QNetworkRequest::CacheLoadControlAttribute)); + setAttribute(QNetworkRequest::CacheSaveControlAttribute, m_reply->attribute(QNetworkRequest::CacheSaveControlAttribute)); + setAttribute(QNetworkRequest::SourceIsFromCacheAttribute, m_reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute)); + setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, m_reply->attribute(QNetworkRequest::DoNotBufferUploadDataAttribute)); + emit metaDataChanged(); +} + +void NetworkReplyProxy::errorInternal(QNetworkReply::NetworkError _error) +{ + setError(_error, errorString()); + emit error(_error); +} + +void NetworkReplyProxy::readInternal() +{ + QByteArray data = m_reply->readAll(); + m_data += data; + m_buffer += data; + emit readyRead(); +} \ No newline at end of file diff --git a/src/networkreplyproxy.h b/src/networkreplyproxy.h new file mode 100644 index 00000000..cffce5a4 --- /dev/null +++ b/src/networkreplyproxy.h @@ -0,0 +1,68 @@ +/* + This file is part of the PhantomJS project from Ofi Labs. + + Copyright (C) 2011 Ariya Hidayat + + 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 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 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. +*/ + +#ifndef NETWORKREPLYPROXY_H +#define NETWORKREPLYPROXY_H + +#include + +class NetworkReplyProxy : public QNetworkReply { + Q_OBJECT +public: + NetworkReplyProxy(QObject* parent, QNetworkReply* reply); + ~NetworkReplyProxy(); + + void abort(); + void close(); + bool isSequential() const; + + QString body(); + + // not possible... + void setReadBufferSize(qint64 size); + + // QIODevice proxy... + virtual qint64 bytesAvailable() const; + virtual qint64 bytesToWrite() const; + virtual qint64 readData(char* data, qint64 maxlen); + +public Q_SLOTS: + void ignoreSslErrors(); + void applyMetaData(); + + void errorInternal(QNetworkReply::NetworkError _error); + void readInternal(); + +private: + QNetworkReply* m_reply; + QByteArray m_data; + QByteArray m_buffer; +}; + +#endif // NETWORKREPLYPROXY_H diff --git a/src/phantomjs.pro b/src/phantomjs.pro index bb890b14..d1fdc614 100644 --- a/src/phantomjs.pro +++ b/src/phantomjs.pro @@ -15,6 +15,7 @@ HEADERS += csconverter.h \ webpage.h \ consts.h \ utils.h \ + networkreplyproxy.h \ networkaccessmanager.h \ cookiejar.h \ filesystem.h @@ -23,6 +24,7 @@ SOURCES += phantom.cpp \ main.cpp \ csconverter.cpp \ utils.cpp \ + networkreplyproxy.cpp \ networkaccessmanager.cpp \ cookiejar.cpp \ filesystem.cpp