diff options
author | Markus Goetz <Markus.Goetz@nokia.com> | 2009-08-20 13:45:43 (GMT) |
---|---|---|
committer | Markus Goetz <Markus.Goetz@nokia.com> | 2009-08-20 14:30:36 (GMT) |
commit | c0b24b7ce12387aff6e74b05b4060c61a58d87e0 (patch) | |
tree | 6b8e32f38dd26122b452cdf7de45a9fc92c878a1 | |
parent | 354a08b44bcd90cdce22698e204f7306ceea9385 (diff) | |
download | Qt-c0b24b7ce12387aff6e74b05b4060c61a58d87e0.zip Qt-c0b24b7ce12387aff6e74b05b4060c61a58d87e0.tar.gz Qt-c0b24b7ce12387aff6e74b05b4060c61a58d87e0.tar.bz2 |
QNAM HTTP: New attribute, Demo browser: Some request statistic output
New output that tells if a QNetworkReply was retrieved by using
HTTP pipelining.
The demo browser now shows some (debug) output about usage of cache,
pipelining and SSL.
Reviewed-by: Prasanth
-rw-r--r-- | demos/browser/networkaccessmanager.cpp | 36 | ||||
-rw-r--r-- | demos/browser/networkaccessmanager.h | 13 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnectionchannel.cpp | 2 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkreply.cpp | 5 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkreply_p.h | 4 | ||||
-rw-r--r-- | src/network/access/qnetworkaccesshttpbackend.cpp | 2 | ||||
-rw-r--r-- | src/network/access/qnetworkrequest.cpp | 5 | ||||
-rw-r--r-- | src/network/access/qnetworkrequest.h | 1 |
8 files changed, 60 insertions, 8 deletions
diff --git a/demos/browser/networkaccessmanager.cpp b/demos/browser/networkaccessmanager.cpp index 3781652..3ce9c08 100644 --- a/demos/browser/networkaccessmanager.cpp +++ b/demos/browser/networkaccessmanager.cpp @@ -57,16 +57,21 @@ #include <QtNetwork/QAuthenticator> #include <QtNetwork/QNetworkDiskCache> #include <QtNetwork/QNetworkProxy> +#include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkReply> #include <QtNetwork/QSslError> NetworkAccessManager::NetworkAccessManager(QObject *parent) - : QNetworkAccessManager(parent) + : QNetworkAccessManager(parent), + requestFinishedCount(0), requestFinishedFromCacheCount(0), requestFinishedPipelinedCount(0), + requestFinishedSecureCount(0) { connect(this, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); connect(this, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), SLOT(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*))); + connect(this, SIGNAL(finished(QNetworkReply *)), + SLOT(requestFinished(QNetworkReply *))); #ifndef QT_NO_OPENSSL connect(this, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&)), SLOT(sslErrors(QNetworkReply*, const QList<QSslError>&))); @@ -79,6 +84,35 @@ NetworkAccessManager::NetworkAccessManager(QObject *parent) setCache(diskCache); } +QNetworkReply* NetworkAccessManager::createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData) +{ + QNetworkRequest request = req; // copy so we can modify + // this is a temporary hack until we properly use the pipelining flags from QtWebkit + // pipeline everything! :) + request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); + return QNetworkAccessManager::createRequest(op, request, outgoingData); +} + +void NetworkAccessManager::requestFinished(QNetworkReply *reply) +{ + requestFinishedCount++; + + if (reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool() == true) + requestFinishedFromCacheCount++; + + if (reply->attribute(QNetworkRequest::HttpPipeliningWasUsedAttribute).toBool() == true) + requestFinishedPipelinedCount++; + + if (reply->attribute(QNetworkRequest::ConnectionEncryptedAttribute).toBool() == true) + requestFinishedSecureCount++; + + double pctCached = (double(requestFinishedFromCacheCount) * 100.0/ double(requestFinishedCount)); + double pctPipelined = (double(requestFinishedPipelinedCount) * 100.0/ double(requestFinishedCount)); + double pctSecure = (double(requestFinishedSecureCount) * 100.0/ double(requestFinishedCount)); + qDebug("%lli requests [%3.2f%% from cache] [%3.2f%% pipelined] [%3.2f%% SSL/TLS]", requestFinishedCount, pctCached, pctPipelined, pctSecure); + +} + void NetworkAccessManager::loadSettings() { QSettings settings; diff --git a/demos/browser/networkaccessmanager.h b/demos/browser/networkaccessmanager.h index 4c4603e..189d6a0 100644 --- a/demos/browser/networkaccessmanager.h +++ b/demos/browser/networkaccessmanager.h @@ -52,19 +52,18 @@ class NetworkAccessManager : public QNetworkAccessManager public: NetworkAccessManager(QObject *parent = 0); - // this is a temporary hack until we properly use the pipelining flags from QtWebkit - // pipeline everything! :) - virtual QNetworkReply* createRequest ( Operation op, const QNetworkRequest & req, QIODevice * outgoingData = 0 ) { - QNetworkRequest request = req; // copy so we can modify - request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); - return QNetworkAccessManager::createRequest(op, request, outgoingData); - } + virtual QNetworkReply* createRequest ( Operation op, const QNetworkRequest & req, QIODevice * outgoingData = 0 ); private: QList<QString> sslTrustedHostList; + qint64 requestFinishedCount; + qint64 requestFinishedFromCacheCount; + qint64 requestFinishedPipelinedCount; + qint64 requestFinishedSecureCount; public slots: void loadSettings(); + void requestFinished(QNetworkReply *reply); private slots: void authenticationRequired(QNetworkReply *reply, QAuthenticator *auth); diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 37386ea..9d78c55 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -130,6 +130,7 @@ bool QHttpNetworkConnectionChannel::sendRequest() reply->d_func()->clear(); reply->d_func()->connection = connection; reply->d_func()->autoDecompress = request.d->autoDecompress; + reply->d_func()->pipeliningUsed = false; } state = QHttpNetworkConnectionChannel::WritingState; pendingEncrypt = false; @@ -682,6 +683,7 @@ void QHttpNetworkConnectionChannel::pipelineInto(HttpMessagePair &pair) reply->d_func()->clear(); reply->d_func()->connection = connection; reply->d_func()->autoDecompress = request.d->autoDecompress; + reply->d_func()->pipeliningUsed = true; } #ifndef QT_NO_NETWORKPROXY diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index eb8ecb5..4a315e4 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -187,6 +187,10 @@ bool QHttpNetworkReply::isFinished() const return d_func()->state == QHttpNetworkReplyPrivate::AllDoneState; } +bool QHttpNetworkReply::isPipeliningUsed() const +{ + return d_func()->pipeliningUsed; +} QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl) @@ -195,6 +199,7 @@ QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl) chunkedTransferEncoding(0), currentChunkSize(0), currentChunkRead(0), connection(0), initInflate(false), autoDecompress(false), responseData(), requestIsPrepared(false) + ,pipeliningUsed(false) { } diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index f9503a9..8d4d724 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -128,6 +128,8 @@ public: bool isFinished() const; + bool isPipeliningUsed() const; + #ifndef QT_NO_OPENSSL QSslConfiguration sslConfiguration() const; void setSslConfiguration(const QSslConfiguration &config); @@ -223,6 +225,8 @@ public: QByteDataBuffer responseData; // uncompressed body QByteArray compressedData; // compressed body (temporary) bool requestIsPrepared; + + bool pipeliningUsed; }; diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index fd47b34..3532de8 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -716,6 +716,8 @@ void QNetworkAccessHttpBackend::checkForRedirect(const int statusCode) void QNetworkAccessHttpBackend::replyHeaderChanged() { + setAttribute(QNetworkRequest::HttpPipeliningWasUsedAttribute, httpReply->isPipeliningUsed()); + // reconstruct the HTTP header QList<QPair<QByteArray, QByteArray> > headerMap = httpReply->header(); QList<QPair<QByteArray, QByteArray> >::ConstIterator it = headerMap.constBegin(), diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 9fb2d5e..c6cbddd 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -172,6 +172,11 @@ QT_BEGIN_NAMESPACE Indicates whether the QNetworkAccessManager code is allowed to use HTTP pipelining with this request. + \value HttpPipeliningWasUsedAttribute + Replies only, type: QVariant::Bool + Indicates whether the HTTP pipelining was used for receiving + this reply. + \value User Special type. Additional information can be passed in QVariants with types ranging from User to UserMax. The default diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h index fb5ea52..2c26038 100644 --- a/src/network/access/qnetworkrequest.h +++ b/src/network/access/qnetworkrequest.h @@ -77,6 +77,7 @@ public: SourceIsFromCacheAttribute, DoNotBufferUploadDataAttribute, HttpPipeliningAllowedAttribute, + HttpPipeliningWasUsedAttribute, User = 1000, UserMax = 32767 |