summaryrefslogtreecommitdiffstats
path: root/src/network/access
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/access')
-rw-r--r--src/network/access/qftp.cpp17
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp23
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h10
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp14
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel_p.h3
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp6
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp58
-rw-r--r--src/network/access/qhttpthreaddelegate_p.h3
-rw-r--r--src/network/access/qnetworkaccessbackend.cpp4
-rw-r--r--src/network/access/qnetworkaccessftpbackend.cpp4
-rw-r--r--src/network/access/qnetworkaccesshttpbackend.cpp6
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp36
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h2
-rw-r--r--src/network/access/qnetworkcookie.cpp2
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp2
-rw-r--r--src/network/access/qnetworkrequest.cpp2
16 files changed, 177 insertions, 15 deletions
diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp
index 69e59d1..4ff45ba 100644
--- a/src/network/access/qftp.cpp
+++ b/src/network/access/qftp.cpp
@@ -319,6 +319,10 @@ void QFtpDTP::connectToHost(const QString & host, quint16 port)
socket = 0;
}
socket = new QTcpSocket(this);
+#ifndef QT_NO_BEARERMANAGEMENT
+ //copy network session down to the socket
+ socket->setProperty("_q_networksession", property("_q_networksession"));
+#endif
socket->setObjectName(QLatin1String("QFtpDTP Passive state socket"));
connect(socket, SIGNAL(connected()), SLOT(socketConnected()));
connect(socket, SIGNAL(readyRead()), SLOT(socketReadyRead()));
@@ -331,6 +335,10 @@ void QFtpDTP::connectToHost(const QString & host, quint16 port)
int QFtpDTP::setupListener(const QHostAddress &address)
{
+#ifndef QT_NO_BEARERMANAGEMENT
+ //copy network session down to the socket
+ listener.setProperty("_q_networksession", property("_q_networksession"));
+#endif
if (!listener.isListening() && !listener.listen(address, 0))
return -1;
return listener.serverPort();
@@ -808,6 +816,11 @@ QFtpPI::QFtpPI(QObject *parent) :
void QFtpPI::connectToHost(const QString &host, quint16 port)
{
emit connectState(QFtp::HostLookup);
+#ifndef QT_NO_BEARERMANAGEMENT
+ //copy network session down to the socket & DTP
+ commandSocket.setProperty("_q_networksession", property("_q_networksession"));
+ dtp.setProperty("_q_networksession", property("_q_networksession"));
+#endif
commandSocket.connectToHost(host, port);
}
@@ -2240,6 +2253,10 @@ void QFtpPrivate::_q_startNextCommand()
c->rawCmds.clear();
_q_piFinished(QLatin1String("Proxy set to ") + proxyHost + QLatin1Char(':') + QString::number(proxyPort));
} else if (c->command == QFtp::ConnectToHost) {
+#ifndef QT_NO_BEARERMANAGEMENT
+ //copy network session down to the PI
+ pi.setProperty("_q_networksession", q->property("_q_networksession"));
+#endif
if (!proxyHost.isEmpty()) {
host = c->rawCmds[0];
port = c->rawCmds[1].toUInt();
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 29ae5b0..83156c6 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -117,9 +117,14 @@ QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate()
void QHttpNetworkConnectionPrivate::init()
{
+ Q_Q(QHttpNetworkConnection);
for (int i = 0; i < channelCount; i++) {
channels[i].setConnection(this->q_func());
channels[i].ssl = encrypt;
+#ifndef QT_NO_BEARERMANAGEMENT
+ //push session down to channels
+ channels[i].networkSession = networkSession;
+#endif
channels[i].init();
}
}
@@ -830,6 +835,23 @@ void QHttpNetworkConnectionPrivate::readMoreLater(QHttpNetworkReply *reply)
}
}
+#ifndef QT_NO_BEARERMANAGEMENT
+QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 port, bool encrypt, QObject *parent, QSharedPointer<QNetworkSession> networkSession)
+ : QObject(*(new QHttpNetworkConnectionPrivate(hostName, port, encrypt)), parent)
+{
+ Q_D(QHttpNetworkConnection);
+ d->networkSession = networkSession;
+ d->init();
+}
+
+QHttpNetworkConnection::QHttpNetworkConnection(quint16 connectionCount, const QString &hostName, quint16 port, bool encrypt, QObject *parent, QSharedPointer<QNetworkSession> networkSession)
+ : QObject(*(new QHttpNetworkConnectionPrivate(connectionCount, hostName, port, encrypt)), parent)
+{
+ Q_D(QHttpNetworkConnection);
+ d->networkSession = networkSession;
+ d->init();
+}
+#else
QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 port, bool encrypt, QObject *parent)
: QObject(*(new QHttpNetworkConnectionPrivate(hostName, port, encrypt)), parent)
{
@@ -843,6 +865,7 @@ QHttpNetworkConnection::QHttpNetworkConnection(quint16 connectionCount, const QS
Q_D(QHttpNetworkConnection);
d->init();
}
+#endif
QHttpNetworkConnection::~QHttpNetworkConnection()
{
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index 874ea22..adb779f4 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -55,6 +55,7 @@
#include <QtNetwork/qnetworkrequest.h>
#include <QtNetwork/qnetworkreply.h>
#include <QtNetwork/qabstractsocket.h>
+#include <QtNetwork/qnetworksession.h>
#include <private/qobject_p.h>
#include <qauthenticator.h>
@@ -88,8 +89,13 @@ class Q_AUTOTEST_EXPORT QHttpNetworkConnection : public QObject
Q_OBJECT
public:
+#ifndef QT_NO_BEARERMANAGEMENT
+ QHttpNetworkConnection(const QString &hostName, quint16 port = 80, bool encrypt = false, QObject *parent = 0, QSharedPointer<QNetworkSession> networkSession = QSharedPointer<QNetworkSession>());
+ QHttpNetworkConnection(quint16 channelCount, const QString &hostName, quint16 port = 80, bool encrypt = false, QObject *parent = 0, QSharedPointer<QNetworkSession> networkSession = QSharedPointer<QNetworkSession>());
+#else
QHttpNetworkConnection(const QString &hostName, quint16 port = 80, bool encrypt = false, QObject *parent = 0);
QHttpNetworkConnection(quint16 channelCount, const QString &hostName, quint16 port = 80, bool encrypt = false, QObject *parent = 0);
+#endif
~QHttpNetworkConnection();
//The hostname to which this is connected to.
@@ -208,6 +214,10 @@ public:
QList<HttpMessagePair> highPriorityQueue;
QList<HttpMessagePair> lowPriorityQueue;
+#ifndef QT_NO_BEARERMANAGEMENT
+ QSharedPointer<QNetworkSession> networkSession;
+#endif
+
friend class QHttpNetworkConnectionChannel;
};
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 6564b4b..6fbc6f8 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -54,6 +54,10 @@
# include <QtNetwork/qsslconfiguration.h>
#endif
+#ifndef QT_NO_BEARERMANAGEMENT
+#include "private/qnetworksession_p.h"
+#endif
+
QT_BEGIN_NAMESPACE
// TODO: Put channel specific stuff here so it does not polute qhttpnetworkconnection.cpp
@@ -91,6 +95,11 @@ void QHttpNetworkConnectionChannel::init()
#else
socket = new QTcpSocket;
#endif
+#ifndef QT_NO_BEARERMANAGEMENT
+ //push session down to socket
+ if (networkSession)
+ socket->setProperty("_q_networksession", QVariant::fromValue(networkSession));
+#endif
#ifndef QT_NO_NETWORKPROXY
// Set by QNAM anyway, but let's be safe here
socket->setProxy(QNetworkProxy::NoProxy);
@@ -833,7 +842,10 @@ void QHttpNetworkConnectionChannel::handleStatus()
bool QHttpNetworkConnectionChannel::resetUploadData()
{
- Q_ASSERT(reply);
+ if (!reply) {
+ //this happens if server closes connection while QHttpNetworkConnectionPrivate::_q_startNextRequest is pending
+ return false;
+ }
QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice();
if (!uploadByteDevice)
return true;
diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
index 893d75e..f27c6f5 100644
--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
+++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
@@ -117,6 +117,9 @@ public:
bool ignoreAllSslErrors;
QList<QSslError> ignoreSslErrorsList;
#endif
+#ifndef QT_NO_BEARERMANAGEMENT
+ QSharedPointer<QNetworkSession> networkSession;
+#endif
// HTTP pipelining -> http://en.wikipedia.org/wiki/Http_pipelining
enum PipeliningSupport {
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index 8573364..2c67e87 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -158,8 +158,10 @@ QByteArray QHttpNetworkRequestPrivate::header(const QHttpNetworkRequest &request
}
if (request.d->operation == QHttpNetworkRequest::Post) {
// add content type, if not set in the request
- if (request.headerField("content-type").isEmpty())
- ba += "Content-Type: application/x-www-form-urlencoded\r\n";
+ if (request.headerField("content-type").isEmpty()) {
+ qWarning("content-type missing in HTTP POST, defaulting to application/octet-stream");
+ ba += "Content-Type: application/octet-stream\r\n";
+ }
if (!request.d->uploadByteDevice && request.d->url.hasQuery()) {
QByteArray query = request.d->url.encodedQuery();
ba += "Content-Length: ";
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index 5bf6db1..99f9376 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+//#define QHTTPTHREADDELEGATE_DEBUG
#include "qhttpthreaddelegate_p.h"
#include <QThread>
@@ -148,8 +149,13 @@ class QNetworkAccessCachedHttpConnection: public QHttpNetworkConnection,
{
// Q_OBJECT
public:
+#ifdef QT_NO_BEARERMANAGEMENT
QNetworkAccessCachedHttpConnection(const QString &hostName, quint16 port, bool encrypt)
: QHttpNetworkConnection(hostName, port, encrypt)
+#else
+ QNetworkAccessCachedHttpConnection(const QString &hostName, quint16 port, bool encrypt, QSharedPointer<QNetworkSession> networkSession)
+ : QHttpNetworkConnection(hostName, port, encrypt, /*parent=*/0, networkSession)
+#endif
{
setExpires(true);
setShareable(true);
@@ -197,12 +203,16 @@ QHttpThreadDelegate::QHttpThreadDelegate(QObject *parent) :
, downloadBuffer(0)
, httpConnection(0)
, httpReply(0)
+ , synchronousRequestLoop(0)
{
}
// This is invoked as BlockingQueuedConnection from QNetworkAccessHttpBackend in the user thread
void QHttpThreadDelegate::startRequestSynchronously()
{
+#ifdef QHTTPTHREADDELEGATE_DEBUG
+ qDebug() << "QHttpThreadDelegate::startRequestSynchronously() thread=" << QThread::currentThreadId();
+#endif
synchronous = true;
QEventLoop synchronousRequestLoop;
@@ -217,12 +227,18 @@ void QHttpThreadDelegate::startRequestSynchronously()
connections.localData()->releaseEntry(cacheKey);
connections.setLocalData(0);
+#ifdef QHTTPTHREADDELEGATE_DEBUG
+ qDebug() << "QHttpThreadDelegate::startRequestSynchronously() thread=" << QThread::currentThreadId() << "finished";
+#endif
}
// This is invoked as QueuedConnection from QNetworkAccessHttpBackend in the user thread
void QHttpThreadDelegate::startRequest()
{
+#ifdef QHTTPTHREADDELEGATE_DEBUG
+ qDebug() << "QHttpThreadDelegate::startRequest() thread=" << QThread::currentThreadId();
+#endif
// Check QThreadStorage for the QNetworkAccessCache
// If not there, create this connection cache
if (!connections.hasLocalData()) {
@@ -248,10 +264,14 @@ void QHttpThreadDelegate::startRequest()
if (httpConnection == 0) {
// no entry in cache; create an object
// the http object is actually a QHttpNetworkConnection
+#ifdef QT_NO_BEARERMANAGEMENT
httpConnection = new QNetworkAccessCachedHttpConnection(urlCopy.host(), urlCopy.port(), ssl);
+#else
+ httpConnection = new QNetworkAccessCachedHttpConnection(urlCopy.host(), urlCopy.port(), ssl, networkSession);
+#endif
#ifndef QT_NO_OPENSSL
// Set the QSslConfiguration from this QNetworkRequest.
- if (ssl) {
+ if (ssl && incomingSslConfiguration != QSslConfiguration::defaultConfiguration()) {
httpConnection->setSslConfiguration(incomingSslConfiguration);
}
#endif
@@ -309,15 +329,22 @@ void QHttpThreadDelegate::startRequest()
// This gets called from the user thread or by the synchronous HTTP timeout timer
void QHttpThreadDelegate::abortRequest()
{
+#ifdef QHTTPTHREADDELEGATE_DEBUG
+ qDebug() << "QHttpThreadDelegate::abortRequest() thread=" << QThread::currentThreadId() << "sync=" << synchronous;
+#endif
if (httpReply) {
delete httpReply;
httpReply = 0;
- this->deleteLater();
}
// Got aborted by the timeout timer
- if (synchronous)
+ if (synchronous) {
incomingErrorCode = QNetworkReply::TimeoutError;
+ QMetaObject::invokeMethod(synchronousRequestLoop, "quit", Qt::QueuedConnection);
+ } else {
+ //only delete this for asynchronous mode or QNetworkAccessHttpBackend will crash - see QNetworkAccessHttpBackend::postRequest()
+ this->deleteLater();
+ }
}
void QHttpThreadDelegate::readyReadSlot()
@@ -338,6 +365,9 @@ void QHttpThreadDelegate::finishedSlot()
qWarning() << "QHttpThreadDelegate::finishedSlot: HTTP reply had already been deleted, internal problem. Please report.";
return;
}
+#ifdef QHTTPTHREADDELEGATE_DEBUG
+ qDebug() << "QHttpThreadDelegate::finishedSlot() thread=" << QThread::currentThreadId() << "result=" << httpReply->statusCode();
+#endif
// If there is still some data left emit that now
while (httpReply->readAnyAvailable()) {
@@ -367,6 +397,9 @@ void QHttpThreadDelegate::finishedSlot()
void QHttpThreadDelegate::synchronousFinishedSlot()
{
+#ifdef QHTTPTHREADDELEGATE_DEBUG
+ qDebug() << "QHttpThreadDelegate::synchronousFinishedSlot() thread=" << QThread::currentThreadId() << "result=" << httpReply->statusCode();
+#endif
if (httpReply->statusCode() >= 400) {
// it's an error reply
QString msg = QLatin1String(QT_TRANSLATE_NOOP("QNetworkReply",
@@ -388,6 +421,9 @@ void QHttpThreadDelegate::finishedWithErrorSlot(QNetworkReply::NetworkError erro
qWarning() << "QHttpThreadDelegate::finishedWithErrorSlot: HTTP reply had already been deleted, internal problem. Please report.";
return;
}
+#ifdef QHTTPTHREADDELEGATE_DEBUG
+ qDebug() << "QHttpThreadDelegate::finishedWithErrorSlot() thread=" << QThread::currentThreadId() << "error=" << errorCode << detail;
+#endif
#ifndef QT_NO_OPENSSL
if (ssl)
@@ -405,6 +441,9 @@ void QHttpThreadDelegate::finishedWithErrorSlot(QNetworkReply::NetworkError erro
void QHttpThreadDelegate::synchronousFinishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail)
{
+#ifdef QHTTPTHREADDELEGATE_DEBUG
+ qDebug() << "QHttpThreadDelegate::synchronousFinishedWithErrorSlot() thread=" << QThread::currentThreadId() << "error=" << errorCode << detail;
+#endif
incomingErrorCode = errorCode;
incomingErrorDetail = detail;
@@ -420,6 +459,10 @@ static void downloadBufferDeleter(char *ptr)
void QHttpThreadDelegate::headerChangedSlot()
{
+#ifdef QHTTPTHREADDELEGATE_DEBUG
+ qDebug() << "QHttpThreadDelegate::headerChangedSlot() thread=" << QThread::currentThreadId();
+#endif
+
#ifndef QT_NO_OPENSSL
if (ssl)
emit sslConfigurationChanged(httpReply->sslConfiguration());
@@ -452,6 +495,9 @@ void QHttpThreadDelegate::headerChangedSlot()
void QHttpThreadDelegate::synchronousHeaderChangedSlot()
{
+#ifdef QHTTPTHREADDELEGATE_DEBUG
+ qDebug() << "QHttpThreadDelegate::synchronousHeaderChangedSlot() thread=" << QThread::currentThreadId();
+#endif
// Store the information we need in this object, the QNetworkAccessHttpBackend will later read it
incomingHeaders = httpReply->header();
incomingStatusCode = httpReply->statusCode();
@@ -496,6 +542,9 @@ void QHttpThreadDelegate::sslErrorsSlot(const QList<QSslError> &errors)
void QHttpThreadDelegate::synchronousAuthenticationRequiredSlot(const QHttpNetworkRequest &request, QAuthenticator *a)
{
Q_UNUSED(request);
+#ifdef QHTTPTHREADDELEGATE_DEBUG
+ qDebug() << "QHttpThreadDelegate::synchronousAuthenticationRequiredSlot() thread=" << QThread::currentThreadId();
+#endif
// Ask the credential cache
QNetworkAuthenticationCredential credential = authenticationManager->fetchCachedCredentials(httpRequest.url(), a);
@@ -511,6 +560,9 @@ void QHttpThreadDelegate::synchronousAuthenticationRequiredSlot(const QHttpNetwo
#ifndef QT_NO_NETWORKPROXY
void QHttpThreadDelegate::synchronousProxyAuthenticationRequiredSlot(const QNetworkProxy &p, QAuthenticator *a)
{
+#ifdef QHTTPTHREADDELEGATE_DEBUG
+ qDebug() << "QHttpThreadDelegate::synchronousProxyAuthenticationRequiredSlot() thread=" << QThread::currentThreadId();
+#endif
// Ask the credential cache
QNetworkAuthenticationCredential credential = authenticationManager->fetchCachedProxyCredentials(p, a);
if (!credential.isNull()) {
diff --git a/src/network/access/qhttpthreaddelegate_p.h b/src/network/access/qhttpthreaddelegate_p.h
index 3b598aa..752bc09 100644
--- a/src/network/access/qhttpthreaddelegate_p.h
+++ b/src/network/access/qhttpthreaddelegate_p.h
@@ -110,6 +110,9 @@ public:
qint64 incomingContentLength;
QNetworkReply::NetworkError incomingErrorCode;
QString incomingErrorDetail;
+#ifndef QT_NO_BEARERMANAGEMENT
+ QSharedPointer<QNetworkSession> networkSession;
+#endif
protected:
// The zerocopy download buffer, if used:
diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp
index 5aedac9..6220abe 100644
--- a/src/network/access/qnetworkaccessbackend.cpp
+++ b/src/network/access/qnetworkaccessbackend.cpp
@@ -46,7 +46,7 @@
#include "qnetworkreply_p.h"
#include "QtCore/qhash.h"
#include "QtCore/qmutex.h"
-#include "QtNetwork/qnetworksession.h"
+#include "QtNetwork/private/qnetworksession_p.h"
#include "qnetworkaccesscachebackend_p.h"
#include "qabstractnetworkcache.h"
@@ -369,6 +369,8 @@ bool QNetworkAccessBackend::start()
if (manager->networkSession->isOpen() &&
manager->networkSession->state() == QNetworkSession::Connected) {
+ //copy network session down to the backend
+ setProperty("_q_networksession", QVariant::fromValue(manager->networkSession));
open();
return true;
}
diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp
index e34e6bb..3ad1961 100644
--- a/src/network/access/qnetworkaccessftpbackend.cpp
+++ b/src/network/access/qnetworkaccessftpbackend.cpp
@@ -153,6 +153,10 @@ void QNetworkAccessFtpBackend::open()
if (!objectCache->requestEntry(cacheKey, this,
SLOT(ftpConnectionReady(QNetworkAccessCache::CacheableObject*)))) {
ftp = new QNetworkAccessCachedFtpConnection;
+#ifndef QT_NO_BEARERMANAGEMENT
+ //copy network session down to the QFtp
+ ftp->setProperty("_q_networksession", property("_q_networksession"));
+#endif
#ifndef QT_NO_NETWORKPROXY
if (proxy.type() == QNetworkProxy::FtpCachingProxy)
ftp->setProxy(proxy.hostName(), proxy.port());
diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp
index d827b03..c619114 100644
--- a/src/network/access/qnetworkaccesshttpbackend.cpp
+++ b/src/network/access/qnetworkaccesshttpbackend.cpp
@@ -47,6 +47,7 @@
#include "qabstractnetworkcache.h"
#include "qnetworkrequest.h"
#include "qnetworkreply.h"
+#include "QtNetwork/private/qnetworksession_p.h"
#include "qnetworkrequest_p.h"
#include "qnetworkcookie_p.h"
#include "QtCore/qdatetime.h"
@@ -522,6 +523,11 @@ void QNetworkAccessHttpBackend::postRequest()
// Create the HTTP thread delegate
QHttpThreadDelegate *delegate = new QHttpThreadDelegate;
+#ifndef Q_NO_BEARERMANAGEMENT
+ QVariant v(property("_q_networksession"));
+ if (v.isValid())
+ delegate->networkSession = qvariant_cast<QSharedPointer<QNetworkSession> >(v);
+#endif
// For the synchronous HTTP, this is the normal way the delegate gets deleted
// For the asynchronous HTTP this is a safety measure, the delegate deletes itself when HTTP is finished
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 0337607..5a7521e 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -1168,8 +1168,25 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co
initializeSession = false;
- if (!config.isValid()) {
- networkSession.clear();
+ QSharedPointer<QNetworkSession> newSession;
+ if (config.isValid())
+ newSession = QSharedNetworkSessionManager::getSession(config);
+
+ if (networkSession) {
+ //do nothing if new and old session are the same
+ if (networkSession == newSession)
+ return;
+ //disconnect from old session
+ QObject::disconnect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()));
+ QObject::disconnect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()));
+ QObject::disconnect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)),
+ q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)));
+ }
+
+ //switch to new session (null if config was invalid)
+ networkSession = newSession;
+
+ if (!networkSession) {
online = false;
if (networkAccessible == QNetworkAccessManager::NotAccessible)
@@ -1180,8 +1197,7 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co
return;
}
- networkSession = QSharedNetworkSessionManager::getSession(config);
-
+ //connect to new session
QObject::connect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()), Qt::QueuedConnection);
//QueuedConnection is used to avoid deleting the networkSession inside its closed signal
QObject::connect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()), Qt::QueuedConnection);
@@ -1193,9 +1209,15 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co
void QNetworkAccessManagerPrivate::_q_networkSessionClosed()
{
+ Q_Q(QNetworkAccessManager);
if (networkSession) {
networkConfiguration = networkSession->configuration().identifier();
+ //disconnect from old session
+ QObject::disconnect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()));
+ QObject::disconnect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()));
+ QObject::disconnect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)),
+ q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)));
networkSession.clear();
}
}
@@ -1204,8 +1226,12 @@ void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession
{
Q_Q(QNetworkAccessManager);
- if (state == QNetworkSession::Connected)
+ //Do not emit the networkSessionConnected signal here, except for roaming -> connected
+ //transition, otherwise it is emitted twice in a row when opening a connection.
+ if (state == QNetworkSession::Connected && lastSessionState == QNetworkSession::Roaming)
emit q->networkSessionConnected();
+ lastSessionState = state;
+
if (online) {
if (state != QNetworkSession::Connected && state != QNetworkSession::Roaming) {
online = false;
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index 0f18221..f64cc4d 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -79,6 +79,7 @@ public:
#endif
#ifndef QT_NO_BEARERMANAGEMENT
networkSession(0),
+ lastSessionState(QNetworkSession::Invalid),
networkAccessible(QNetworkAccessManager::Accessible),
online(false),
initializeSession(true),
@@ -136,6 +137,7 @@ public:
#ifndef QT_NO_BEARERMANAGEMENT
QSharedPointer<QNetworkSession> networkSession;
+ QNetworkSession::State lastSessionState;
QString networkConfiguration;
QNetworkAccessManager::NetworkAccessibility networkAccessible;
bool online;
diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp
index c2a6925..52eb345 100644
--- a/src/network/access/qnetworkcookie.cpp
+++ b/src/network/access/qnetworkcookie.cpp
@@ -737,7 +737,7 @@ static QDateTime parseDateString(const QByteArray &dateString)
// 4 digit Year
if (isNum
&& year == -1
- && dateString.length() >= at + 3) {
+ && dateString.length() > at + 3) {
if (isNumber(dateString[at + 1])
&& isNumber(dateString[at + 2])
&& isNumber(dateString[at + 3])) {
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index c3f75a5..9eb505d 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -74,7 +74,7 @@ inline QNetworkReplyImplPrivate::QNetworkReplyImplPrivate()
void QNetworkReplyImplPrivate::_q_startOperation()
{
// ensure this function is only being called once
- if (state == Working) {
+ if (state == Working || state == Finished) {
qDebug("QNetworkReplyImpl::_q_startOperation was called more than once");
return;
}
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index 665ee28..338969a 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -524,7 +524,7 @@ void QNetworkRequest::setAttribute(Attribute code, const QVariant &value)
QSslConfiguration QNetworkRequest::sslConfiguration() const
{
if (!d->sslConfiguration)
- d->sslConfiguration = new QSslConfiguration;
+ d->sslConfiguration = new QSslConfiguration(QSslConfiguration::defaultConfiguration());
return *d->sslConfiguration;
}