summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@digia.com>2013-03-20 13:46:57 +0100
committerOswald Buddenhagen <oswald.buddenhagen@digia.com>2013-03-20 13:49:28 +0100
commit76c0be34cd4ff4564693162fa7528463e23ce9d8 (patch)
treef165b7bc319548fb0082365411a871028f92e89e /src/network
parent27b4fe96b59e9e63d1e570e802c072e9afdfb2d4 (diff)
parent36cb3f3f655a9090c82de609010cbfb88651a0f3 (diff)
Merge branch 'dev' into stable
This starts Qt 5.1 release cycle Conflicts: src/gui/text/qfontdatabase.cpp src/gui/text/qharfbuzz_copy_p.h src/widgets/kernel/qapplication.cpp src/widgets/kernel/qcoreapplication.cpp Change-Id: I72fbf83ab3c2206aeea1b089428b0fc2a89bd62b
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/qabstractnetworkcache.h4
-rw-r--r--src/network/access/qftp_p.h4
-rw-r--r--src/network/access/qhttpmultipart.h4
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp14
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h9
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp21
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel_p.h2
-rw-r--r--src/network/access/qhttpnetworkreply_p.h1
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp9
-rw-r--r--src/network/access/qhttpthreaddelegate_p.h2
-rw-r--r--src/network/access/qnetworkaccessbackend.cpp7
-rw-r--r--src/network/access/qnetworkaccessbackend_p.h1
-rw-r--r--src/network/access/qnetworkaccessdebugpipebackend.cpp2
-rw-r--r--src/network/access/qnetworkaccessfilebackend.cpp18
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp74
-rw-r--r--src/network/access/qnetworkaccessmanager.h6
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h1
-rw-r--r--src/network/access/qnetworkcookie.h4
-rw-r--r--src/network/access/qnetworkcookiejar.h4
-rw-r--r--src/network/access/qnetworkdiskcache.h4
-rw-r--r--src/network/access/qnetworkreply.cpp25
-rw-r--r--src/network/access/qnetworkreply.h5
-rw-r--r--src/network/access/qnetworkreplyfileimpl.cpp12
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp12
-rw-r--r--src/network/access/qnetworkreplyhttpimpl_p.h2
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp8
-rw-r--r--src/network/access/qnetworkreplyimpl_p.h1
-rw-r--r--src/network/access/qnetworkrequest.h4
-rw-r--r--src/network/bearer/qbearerplugin_p.h4
-rw-r--r--src/network/bearer/qnetworkconfigmanager.cpp2
-rw-r--r--src/network/bearer/qnetworkconfigmanager.h4
-rw-r--r--src/network/bearer/qnetworkconfigmanager_p.cpp2
-rw-r--r--src/network/bearer/qnetworkconfiguration.h4
-rw-r--r--src/network/bearer/qnetworksession.cpp108
-rw-r--r--src/network/bearer/qnetworksession.h4
-rw-r--r--src/network/bearer/qnetworksession_p.h2
-rw-r--r--src/network/doc/snippets/code/src_network_socket_qabstractsocket.cpp2
-rw-r--r--src/network/doc/snippets/network/tcpwait.cpp8
-rw-r--r--src/network/kernel/kernel.pri8
-rw-r--r--src/network/kernel/qauthenticator.cpp1
-rw-r--r--src/network/kernel/qauthenticator.h6
-rw-r--r--src/network/kernel/qdnslookup.h4
-rw-r--r--src/network/kernel/qhostaddress.cpp2
-rw-r--r--src/network/kernel/qhostaddress.h3
-rw-r--r--src/network/kernel/qhostinfo.cpp13
-rw-r--r--src/network/kernel/qhostinfo.h4
-rw-r--r--src/network/kernel/qhostinfo_unix.cpp2
-rw-r--r--src/network/kernel/qnetworkfunctions_wince.h4
-rw-r--r--src/network/kernel/qnetworkinterface.h6
-rw-r--r--src/network/kernel/qnetworkinterface_unix.cpp6
-rw-r--r--src/network/kernel/qnetworkinterface_win.cpp2
-rw-r--r--src/network/kernel/qnetworkinterface_win_p.h32
-rw-r--r--src/network/kernel/qnetworkproxy.cpp2
-rw-r--r--src/network/kernel/qnetworkproxy.h4
-rw-r--r--src/network/kernel/qnetworkproxy_blackberry.cpp30
-rw-r--r--src/network/kernel/qnetworkproxy_mac.cpp5
-rw-r--r--src/network/kernel/qurlinfo_p.h4
-rw-r--r--src/network/socket/qabstractsocket.h4
-rw-r--r--src/network/socket/qlocalserver.h4
-rw-r--r--src/network/socket/qlocalserver_unix.cpp4
-rw-r--r--src/network/socket/qlocalsocket.cpp75
-rw-r--r--src/network/socket/qlocalsocket.h7
-rw-r--r--src/network/socket/qlocalsocket_tcp.cpp22
-rw-r--r--src/network/socket/qlocalsocket_unix.cpp15
-rw-r--r--src/network/socket/qlocalsocket_win.cpp18
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp8
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp2
-rw-r--r--src/network/socket/qtcpserver.h4
-rw-r--r--src/network/socket/qtcpsocket.cpp2
-rw-r--r--src/network/socket/qtcpsocket.h4
-rw-r--r--src/network/socket/qudpsocket.h4
-rw-r--r--src/network/ssl/qssl.cpp2
-rw-r--r--src/network/ssl/qssl.h4
-rw-r--r--src/network/ssl/qsslcertificate.h4
-rw-r--r--src/network/ssl/qsslcertificateextension.h4
-rw-r--r--src/network/ssl/qsslcipher.cpp2
-rw-r--r--src/network/ssl/qsslcipher.h4
-rw-r--r--src/network/ssl/qsslconfiguration.cpp56
-rw-r--r--src/network/ssl/qsslconfiguration.h9
-rw-r--r--src/network/ssl/qsslconfiguration_p.h7
-rw-r--r--src/network/ssl/qsslcontext.cpp309
-rw-r--r--src/network/ssl/qsslcontext_p.h88
-rw-r--r--src/network/ssl/qsslerror.cpp4
-rw-r--r--src/network/ssl/qsslerror.h6
-rw-r--r--src/network/ssl/qsslkey.h4
-rw-r--r--src/network/ssl/qsslsocket.cpp74
-rw-r--r--src/network/ssl/qsslsocket.h7
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp272
-rw-r--r--src/network/ssl/qsslsocket_openssl_p.h5
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp48
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h4
-rw-r--r--src/network/ssl/qsslsocket_p.h11
-rw-r--r--src/network/ssl/ssl.pri6
93 files changed, 1070 insertions, 571 deletions
diff --git a/src/network/access/qabstractnetworkcache.h b/src/network/access/qabstractnetworkcache.h
index 6a4d36ced3..b9a086f047 100644
--- a/src/network/access/qabstractnetworkcache.h
+++ b/src/network/access/qabstractnetworkcache.h
@@ -47,8 +47,6 @@
#include <QtCore/qpair.h>
#include <QtNetwork/qnetworkrequest.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -141,6 +139,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif
diff --git a/src/network/access/qftp_p.h b/src/network/access/qftp_p.h
index d87a743036..ee5d124650 100644
--- a/src/network/access/qftp_p.h
+++ b/src/network/access/qftp_p.h
@@ -57,8 +57,6 @@
#include <private/qurlinfo_p.h>
#include <QtCore/qobject.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -176,6 +174,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QFTP_H
diff --git a/src/network/access/qhttpmultipart.h b/src/network/access/qhttpmultipart.h
index 9913b64de6..71075ad2f3 100644
--- a/src/network/access/qhttpmultipart.h
+++ b/src/network/access/qhttpmultipart.h
@@ -47,8 +47,6 @@
#include <QtCore/QIODevice>
#include <QtNetwork/QNetworkRequest>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -119,6 +117,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QHTTPMULTIPART_H
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index eec5cfa96d..a279990f4c 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -923,7 +923,7 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
fillPipeline(channels[i].socket);
// If there is not already any connected channels we need to connect a new one.
- // We do not pair the channel with the request until we know if it is
+ // We do not pair the channel with the request until we know if it is
// connected or not. This is to reuse connected channels before we connect new once.
int queuedRequest = highPriorityQueue.count() + lowPriorityQueue.count();
for (int i = 0; i < channelCount; ++i) {
@@ -1224,6 +1224,18 @@ void QHttpNetworkConnection::setSslConfiguration(const QSslConfiguration &config
d->channels[i].setSslConfiguration(config);
}
+QSharedPointer<QSslContext> QHttpNetworkConnection::sslContext()
+{
+ Q_D(QHttpNetworkConnection);
+ return d->sslContext;
+}
+
+void QHttpNetworkConnection::setSslContext(QSharedPointer<QSslContext> context)
+{
+ Q_D(QHttpNetworkConnection);
+ d->sslContext = context;
+}
+
void QHttpNetworkConnection::ignoreSslErrors(int channel)
{
Q_D(QHttpNetworkConnection);
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index 57d40bfcf2..956499ddab 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -62,6 +62,7 @@
#include <qnetworkproxy.h>
#include <qbuffer.h>
#include <qtimer.h>
+#include <qsharedpointer.h>
#include <private/qhttpnetworkheader_p.h>
#include <private/qhttpnetworkrequest_p.h>
@@ -72,6 +73,8 @@
#ifndef QT_NO_HTTP
#ifndef QT_NO_SSL
+# include <private/qsslcontext_p.h>
+# include <private/qsslsocket_p.h>
# include <QtNetwork/qsslsocket.h>
# include <QtNetwork/qsslerror.h>
#else
@@ -124,6 +127,8 @@ public:
void setSslConfiguration(const QSslConfiguration &config);
void ignoreSslErrors(int channel = -1);
void ignoreSslErrors(const QList<QSslError> &errors, int channel = -1);
+ QSharedPointer<QSslContext> sslContext();
+ void setSslContext(QSharedPointer<QSslContext> context);
#endif
private:
@@ -234,6 +239,10 @@ public:
QList<HttpMessagePair> highPriorityQueue;
QList<HttpMessagePair> lowPriorityQueue;
+#ifndef QT_NO_SSL
+ QSharedPointer<QSslContext> sslContext;
+#endif
+
#ifndef QT_NO_BEARERMANAGEMENT
QSharedPointer<QNetworkSession> networkSession;
#endif
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 38723a7032..4b8fe8aca7 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -622,6 +622,13 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
if (ssl) {
#ifndef QT_NO_SSL
QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket);
+
+ // check whether we can re-use an existing SSL session
+ // (meaning another socket in this connection has already
+ // performed a full handshake)
+ if (!connection->sslContext().isNull())
+ QSslSocketPrivate::checkSettingSslContext(sslSocket, connection->sslContext());
+
sslSocket->connectToHostEncrypted(connectHost, connectPort, QIODevice::ReadWrite, networkLayerPreference);
if (ignoreAllSslErrors)
sslSocket->ignoreSslErrors();
@@ -1065,7 +1072,17 @@ void QHttpNetworkConnectionChannel::_q_connected()
// ### FIXME: if the server closes the connection unexpectedly, we shouldn't send the same broken request again!
//channels[i].reconnectAttempts = 2;
- if (!pendingEncrypt) {
+ if (pendingEncrypt) {
+#ifndef QT_NO_SSL
+ if (connection->sslContext().isNull()) {
+ // this socket is making the 1st handshake for this connection,
+ // we need to set the SSL context so new sockets can reuse it
+ QSharedPointer<QSslContext> socketSslContext = QSslSocketPrivate::sslContext(static_cast<QSslSocket*>(socket));
+ if (!socketSslContext.isNull())
+ connection->setSslContext(socketSslContext);
+ }
+#endif
+ } else {
state = QHttpNetworkConnectionChannel::IdleState;
if (!reply)
connection->d_func()->dequeueRequest(socket);
@@ -1208,6 +1225,8 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
if (!reply)
connection->d_func()->dequeueRequest(socket);
if (reply)
+ emit reply->encrypted();
+ if (reply)
sendRequest();
}
diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
index 3577d76df5..c8138b5453 100644
--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
+++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
@@ -146,7 +146,7 @@ public:
QHttpNetworkConnectionChannel();
QAbstractSocket::NetworkLayerProtocol networkLayerPreference;
-
+
void setConnection(QHttpNetworkConnection *c);
QPointer<QHttpNetworkConnection> connection;
diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h
index e849c66659..7aea9f14ec 100644
--- a/src/network/access/qhttpnetworkreply_p.h
+++ b/src/network/access/qhttpnetworkreply_p.h
@@ -142,6 +142,7 @@ public:
void ignoreSslErrors(const QList<QSslError> &errors);
Q_SIGNALS:
+ void encrypted();
void sslErrors(const QList<QSslError> &errors);
#endif
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index 117265dbfb..a2cee48b22 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -315,6 +315,7 @@ void QHttpThreadDelegate::startRequest()
connect(httpReply,SIGNAL(readyRead()), this, SLOT(readyReadSlot()));
connect(httpReply,SIGNAL(dataReadProgress(qint64,qint64)), this, SLOT(dataReadProgressSlot(qint64,qint64)));
#ifndef QT_NO_SSL
+ connect(httpReply,SIGNAL(encrypted()), this, SLOT(encryptedSlot()));
connect(httpReply,SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrorsSlot(QList<QSslError>)));
#endif
@@ -589,6 +590,14 @@ void QHttpThreadDelegate::cacheCredentialsSlot(const QHttpNetworkRequest &reques
#ifndef QT_NO_SSL
+void QHttpThreadDelegate::encryptedSlot()
+{
+ if (!httpReply)
+ return;
+
+ emit encrypted();
+}
+
void QHttpThreadDelegate::sslErrorsSlot(const QList<QSslError> &errors)
{
if (!httpReply)
diff --git a/src/network/access/qhttpthreaddelegate_p.h b/src/network/access/qhttpthreaddelegate_p.h
index 86192c77cc..d9ef1a0a55 100644
--- a/src/network/access/qhttpthreaddelegate_p.h
+++ b/src/network/access/qhttpthreaddelegate_p.h
@@ -135,6 +135,7 @@ signals:
void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *);
#endif
#ifndef QT_NO_SSL
+ void encrypted();
void sslErrors(const QList<QSslError> &, bool *, QList<QSslError> *);
void sslConfigurationChanged(const QSslConfiguration);
#endif
@@ -164,6 +165,7 @@ protected slots:
void dataReadProgressSlot(qint64 done, qint64 total);
void cacheCredentialsSlot(const QHttpNetworkRequest &request, QAuthenticator *authenticator);
#ifndef QT_NO_SSL
+ void encryptedSlot();
void sslErrorsSlot(const QList<QSslError> &errors);
#endif
diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp
index 84f9b82a22..a895864d76 100644
--- a/src/network/access/qnetworkaccessbackend.cpp
+++ b/src/network/access/qnetworkaccessbackend.cpp
@@ -340,6 +340,13 @@ void QNetworkAccessBackend::redirectionRequested(const QUrl &target)
reply->redirectionRequested(target);
}
+void QNetworkAccessBackend::encrypted()
+{
+#ifndef QT_NO_SSL
+ reply->encrypted();
+#endif
+}
+
void QNetworkAccessBackend::sslErrors(const QList<QSslError> &errors)
{
#ifndef QT_NO_SSL
diff --git a/src/network/access/qnetworkaccessbackend_p.h b/src/network/access/qnetworkaccessbackend_p.h
index 23f8416e0e..bf284414e0 100644
--- a/src/network/access/qnetworkaccessbackend_p.h
+++ b/src/network/access/qnetworkaccessbackend_p.h
@@ -196,6 +196,7 @@ protected slots:
void authenticationRequired(QAuthenticator *auth);
void metaDataChanged();
void redirectionRequested(const QUrl &destination);
+ void encrypted();
void sslErrors(const QList<QSslError> &errors);
void emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal);
diff --git a/src/network/access/qnetworkaccessdebugpipebackend.cpp b/src/network/access/qnetworkaccessdebugpipebackend.cpp
index d9d3200564..b6c04dddea 100644
--- a/src/network/access/qnetworkaccessdebugpipebackend.cpp
+++ b/src/network/access/qnetworkaccessdebugpipebackend.cpp
@@ -143,7 +143,7 @@ void QNetworkAccessDebugPipeBackend::pushFromSocketToDownstream()
buffer.resize(ReadBufferSize);
qint64 haveRead = socket.read(buffer.data(), ReadBufferSize);
-
+
if (haveRead == -1) {
hasDownloadFinished = true;
// this ensures a good last downloadProgress is emitted
diff --git a/src/network/access/qnetworkaccessfilebackend.cpp b/src/network/access/qnetworkaccessfilebackend.cpp
index a7f35815f9..13428cc802 100644
--- a/src/network/access/qnetworkaccessfilebackend.cpp
+++ b/src/network/access/qnetworkaccessfilebackend.cpp
@@ -65,7 +65,11 @@ QNetworkAccessFileBackendFactory::create(QNetworkAccessManager::Operation op,
}
QUrl url = request.url();
- if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0 || url.isLocalFile()) {
+ if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0
+#if defined(Q_OS_ANDROID)
+ || url.scheme().compare(QLatin1String("assets"), Qt::CaseInsensitive) == 0
+#endif
+ || url.isLocalFile()) {
return new QNetworkAccessFileBackend;
} else if (!url.scheme().isEmpty() && url.authority().isEmpty() && (url.scheme().length() > 1)) {
// check if QFile could, in theory, open this URL via the file engines
@@ -113,10 +117,16 @@ void QNetworkAccessFileBackend::open()
QString fileName = url.toLocalFile();
if (fileName.isEmpty()) {
- if (url.scheme() == QLatin1String("qrc"))
+ if (url.scheme() == QLatin1String("qrc")) {
fileName = QLatin1Char(':') + url.path();
- else
- fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery);
+ } else {
+#if defined(Q_OS_ANDROID)
+ if (url.scheme() == QLatin1String("assets"))
+ fileName = QLatin1String("assets:") + url.path();
+ else
+#endif
+ fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery);
+ }
}
file.setFileName(fileName);
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 6899653800..83cb729589 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -374,6 +374,32 @@ static void ensureInitialized()
*/
/*!
+ \fn void QNetworkAccessManager::encrypted(QNetworkReply *reply)
+ \since 5.1
+
+ This signal is emitted when an SSL/TLS session has successfully
+ completed the initial handshake. At this point, no user data
+ has been transmitted. The signal can be used to perform
+ additional checks on the certificate chain, for example to
+ notify users when the certificate for a website has changed. The
+ \a reply parameter specifies which network reply is responsible.
+ If the reply does not match the expected criteria then it should
+ be aborted by calling QNetworkReply::abort() by a slot connected
+ to this signal. The SSL configuration in use can be inspected
+ using the QNetworkReply::sslConfiguration() method.
+
+ Internally, QNetworkAccessManager may open multiple connections
+ to a server, in order to allow it process requests in parallel.
+ These connections may be reused, which means that the encrypted()
+ signal would not be emitted. This means that you are only
+ guaranteed to receive this signal for the first connection to a
+ site in the lifespan of the QNetworkAccessManager.
+
+ \sa QSslSocket::encrypted()
+ \sa QNetworkReply::encrypted()
+*/
+
+/*!
\fn void QNetworkAccessManager::sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
This signal is emitted if the SSL/TLS session encountered errors
@@ -646,8 +672,8 @@ QNetworkReply *QNetworkAccessManager::head(const QNetworkRequest &request)
/*!
Posts a request to obtain the contents of the target \a request
- and returns a new QNetworkReply object opened for reading which emits the
- \l{QIODevice::readyRead()}{readyRead()} signal whenever new data
+ and returns a new QNetworkReply object opened for reading which emits the
+ \l{QIODevice::readyRead()}{readyRead()} signal whenever new data
arrives.
The contents as well as associated headers will be downloaded.
@@ -661,11 +687,11 @@ QNetworkReply *QNetworkAccessManager::get(const QNetworkRequest &request)
/*!
Sends an HTTP POST request to the destination specified by \a request
- and returns a new QNetworkReply object opened for reading that will
- contain the reply sent by the server. The contents of the \a data
+ and returns a new QNetworkReply object opened for reading that will
+ contain the reply sent by the server. The contents of the \a data
device will be uploaded to the server.
- \a data must be open for reading and must remain valid until the
+ \a data must be open for reading and must remain valid until the
finished() signal is emitted for this reply.
\note Sending a POST request on protocols other than HTTP and
@@ -681,7 +707,7 @@ QNetworkReply *QNetworkAccessManager::post(const QNetworkRequest &request, QIODe
/*!
\overload
- Sends the contents of the \a data byte array to the destination
+ Sends the contents of the \a data byte array to the destination
specified by \a request.
*/
QNetworkReply *QNetworkAccessManager::post(const QNetworkRequest &request, const QByteArray &data)
@@ -744,8 +770,8 @@ QNetworkReply *QNetworkAccessManager::put(const QNetworkRequest &request, QHttpM
this reply.
Whether anything will be available for reading from the returned
- object is protocol dependent. For HTTP, the server may send a
- small HTML page indicating the upload was successful (or not).
+ object is protocol dependent. For HTTP, the server may send a
+ small HTML page indicating the upload was successful (or not).
Other protocols will probably have content in their replies.
\note For HTTP, this request will send a PUT request, which most servers
@@ -781,7 +807,7 @@ QNetworkReply *QNetworkAccessManager::put(const QNetworkRequest &request, const
Sends a request to delete the resource identified by the URL of \a request.
- \note This feature is currently available for HTTP only, performing an
+ \note This feature is currently available for HTTP only, performing an
HTTP DELETE request.
\sa get(), post(), put(), sendCustomRequest()
@@ -834,10 +860,12 @@ QNetworkConfiguration QNetworkAccessManager::configuration() const
Q_D(const QNetworkAccessManager);
QSharedPointer<QNetworkSession> session(d->getNetworkSession());
- if (session)
+ if (session) {
return session->configuration();
- else
- return QNetworkConfiguration();
+ } else {
+ QNetworkConfigurationManager manager;
+ return manager.defaultConfiguration();
+ }
}
/*!
@@ -860,13 +888,12 @@ QNetworkConfiguration QNetworkAccessManager::activeConfiguration() const
Q_D(const QNetworkAccessManager);
QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
+ QNetworkConfigurationManager manager;
if (networkSession) {
- QNetworkConfigurationManager manager;
-
return manager.configurationFromIdentifier(
networkSession->sessionProperty(QLatin1String("ActiveConfiguration")).toString());
} else {
- return QNetworkConfiguration();
+ return manager.defaultConfiguration();
}
}
@@ -983,7 +1010,11 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
// fast path for GET on file:// URLs
// The QNetworkAccessFileBackend will right now only be used for PUT
if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation)
- && (isLocalFile || scheme == QLatin1String("qrc"))) {
+ && (isLocalFile || scheme == QLatin1String("qrc")
+#if defined(Q_OS_ANDROID)
+ || scheme == QLatin1String("assets")
+#endif
+ )) {
return new QNetworkReplyFileImpl(this, req, op);
}
@@ -1131,6 +1162,16 @@ void QNetworkAccessManagerPrivate::_q_replyFinished()
#endif
}
+void QNetworkAccessManagerPrivate::_q_replyEncrypted()
+{
+#ifndef QT_NO_SSL
+ Q_Q(QNetworkAccessManager);
+ QNetworkReply *reply = qobject_cast<QNetworkReply *>(q->sender());
+ if (reply)
+ emit q->encrypted(reply);
+#endif
+}
+
void QNetworkAccessManagerPrivate::_q_replySslErrors(const QList<QSslError> &errors)
{
#ifndef QT_NO_SSL
@@ -1151,6 +1192,7 @@ QNetworkReply *QNetworkAccessManagerPrivate::postProcess(QNetworkReply *reply)
#ifndef QT_NO_SSL
/* In case we're compiled without SSL support, we don't have this signal and we need to
* avoid getting a connection error. */
+ q->connect(reply, SIGNAL(encrypted()), SLOT(_q_replyEncrypted()));
q->connect(reply, SIGNAL(sslErrors(QList<QSslError>)), SLOT(_q_replySslErrors(QList<QSslError>)));
#endif
#ifndef QT_NO_BEARERMANAGEMENT
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index af5f6933a4..826c8e47d7 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -44,8 +44,6 @@
#include <QtCore/QObject>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -141,6 +139,7 @@ Q_SIGNALS:
void authenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator);
void finished(QNetworkReply *reply);
#ifndef QT_NO_SSL
+ void encrypted(QNetworkReply *reply);
void sslErrors(QNetworkReply *reply, const QList<QSslError> &errors);
#endif
@@ -161,6 +160,7 @@ private:
Q_DECLARE_PRIVATE(QNetworkAccessManager)
Q_PRIVATE_SLOT(d_func(), void _q_replyFinished())
+ Q_PRIVATE_SLOT(d_func(), void _q_replyEncrypted())
Q_PRIVATE_SLOT(d_func(), void _q_replySslErrors(QList<QSslError>))
#ifndef QT_NO_BEARERMANAGEMENT
Q_PRIVATE_SLOT(d_func(), void _q_networkSessionClosed())
@@ -170,6 +170,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index b4ad3511fa..cf756dad7b 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -90,6 +90,7 @@ public:
~QNetworkAccessManagerPrivate();
void _q_replyFinished();
+ void _q_replyEncrypted();
void _q_replySslErrors(const QList<QSslError> &errors);
QNetworkReply *postProcess(QNetworkReply *reply);
void createCookieJar() const;
diff --git a/src/network/access/qnetworkcookie.h b/src/network/access/qnetworkcookie.h
index e7f6c8fe3f..2a4e686b2c 100644
--- a/src/network/access/qnetworkcookie.h
+++ b/src/network/access/qnetworkcookie.h
@@ -47,8 +47,6 @@
#include <QtCore/QMetaType>
#include <QtCore/QObject>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -121,6 +119,4 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QNetworkCookie)
-QT_END_HEADER
-
#endif
diff --git a/src/network/access/qnetworkcookiejar.h b/src/network/access/qnetworkcookiejar.h
index 7868e1fc04..3c787c5dd8 100644
--- a/src/network/access/qnetworkcookiejar.h
+++ b/src/network/access/qnetworkcookiejar.h
@@ -45,8 +45,6 @@
#include <QtCore/QObject>
#include <QtCore/QUrl>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -79,6 +77,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif
diff --git a/src/network/access/qnetworkdiskcache.h b/src/network/access/qnetworkdiskcache.h
index 1d5f293a2c..20a412c96e 100644
--- a/src/network/access/qnetworkdiskcache.h
+++ b/src/network/access/qnetworkdiskcache.h
@@ -44,8 +44,6 @@
#include <QtNetwork/qabstractnetworkcache.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -91,6 +89,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QNETWORKDISKCACHE_H
diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp
index fd3b7760cb..dc42adc612 100644
--- a/src/network/access/qnetworkreply.cpp
+++ b/src/network/access/qnetworkreply.cpp
@@ -195,6 +195,31 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
*/
/*!
+ \fn void QNetworkReply::encrypted()
+ \since 5.1
+
+ This signal is emitted when an SSL/TLS session has successfully
+ completed the initial handshake. At this point, no user data
+ has been transmitted. The signal can be used to perform
+ additional checks on the certificate chain, for example to
+ notify users when the certificate for a website has changed.
+ If the reply does not match the expected criteria then it should
+ be aborted by calling QNetworkReply::abort() by a slot connected
+ to this signal. The SSL configuration in use can be inspected
+ using the QNetworkReply::sslConfiguration() method.
+
+ Internally, QNetworkAccessManager may open multiple connections
+ to a server, in order to allow it process requests in parallel.
+ These connections may be reused, which means that the encrypted()
+ signal would not be emitted. This means that you are only
+ guaranteed to receive this signal for the first connection to a
+ site in the lifespan of the QNetworkAccessManager.
+
+ \sa QSslSocket::encrypted()
+ \sa QNetworkAccessManager::encrypted()
+*/
+
+/*!
\fn void QNetworkReply::sslErrors(const QList<QSslError> &errors)
This signal is emitted if the SSL/TLS session encountered errors
diff --git a/src/network/access/qnetworkreply.h b/src/network/access/qnetworkreply.h
index 8e770bc96b..a7db2d189c 100644
--- a/src/network/access/qnetworkreply.h
+++ b/src/network/access/qnetworkreply.h
@@ -49,8 +49,6 @@
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkAccessManager>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -150,6 +148,7 @@ Q_SIGNALS:
void finished();
void error(QNetworkReply::NetworkError);
#ifndef QT_NO_SSL
+ void encrypted();
void sslErrors(const QList<QSslError> &errors);
#endif
@@ -182,6 +181,4 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QNetworkReply::NetworkError)
-QT_END_HEADER
-
#endif
diff --git a/src/network/access/qnetworkreplyfileimpl.cpp b/src/network/access/qnetworkreplyfileimpl.cpp
index 8a8f73c24f..f7555f8fc3 100644
--- a/src/network/access/qnetworkreplyfileimpl.cpp
+++ b/src/network/access/qnetworkreplyfileimpl.cpp
@@ -91,10 +91,16 @@ QNetworkReplyFileImpl::QNetworkReplyFileImpl(QObject *parent, const QNetworkRequ
QString fileName = url.toLocalFile();
if (fileName.isEmpty()) {
- if (url.scheme() == QLatin1String("qrc"))
+ if (url.scheme() == QLatin1String("qrc")) {
fileName = QLatin1Char(':') + url.path();
- else
- fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery);
+ } else {
+#if defined(Q_OS_ANDROID)
+ if (url.scheme() == QLatin1String("assets"))
+ fileName = QLatin1String("assets:") + url.path();
+ else
+#endif
+ fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery);
+ }
}
QFileInfo fi(fileName);
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 1520816e8d..c04421e5c7 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -610,14 +610,14 @@ void QNetworkReplyHttpImplPrivate::postRequest()
if (synchronous) {
// A synchronous HTTP request uses its own thread
thread = new QThread();
- thread->setObjectName(QStringLiteral("httpReply"));
+ thread->setObjectName(QStringLiteral("Qt HTTP synchronous thread"));
QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
} else if (!managerPrivate->httpThread) {
// We use the manager-global thread.
// At some point we could switch to having multiple threads if it makes sense.
managerPrivate->httpThread = new QThread();
- managerPrivate->httpThread->setObjectName(QStringLiteral("httpThread"));
+ managerPrivate->httpThread->setObjectName(QStringLiteral("Qt HTTP thread"));
managerPrivate->httpThread->start();
thread = managerPrivate->httpThread;
@@ -830,6 +830,8 @@ void QNetworkReplyHttpImplPrivate::postRequest()
Qt::BlockingQueuedConnection);
#endif
#ifndef QT_NO_SSL
+ QObject::connect(delegate, SIGNAL(encrypted()), q, SLOT(replyEncrypted()),
+ Qt::BlockingQueuedConnection);
QObject::connect(delegate, SIGNAL(sslErrors(QList<QSslError>,bool*,QList<QSslError>*)),
q, SLOT(replySslErrors(QList<QSslError>,bool*,QList<QSslError>*)),
Qt::BlockingQueuedConnection);
@@ -1220,6 +1222,12 @@ void QNetworkReplyHttpImplPrivate::httpError(QNetworkReply::NetworkError errorCo
}
#ifndef QT_NO_SSL
+void QNetworkReplyHttpImplPrivate::replyEncrypted()
+{
+ Q_Q(QNetworkReplyHttpImpl);
+ emit q->encrypted();
+}
+
void QNetworkReplyHttpImplPrivate::replySslErrors(
const QList<QSslError> &list, bool *ignoreAll, QList<QSslError> *toBeIgnored)
{
diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h
index 5f8f0badf7..15cc0ec476 100644
--- a/src/network/access/qnetworkreplyhttpimpl_p.h
+++ b/src/network/access/qnetworkreplyhttpimpl_p.h
@@ -116,6 +116,7 @@ public:
Q_PRIVATE_SLOT(d_func(), void httpAuthenticationRequired(const QHttpNetworkRequest &, QAuthenticator *))
Q_PRIVATE_SLOT(d_func(), void httpError(QNetworkReply::NetworkError, const QString &))
#ifndef QT_NO_SSL
+ Q_PRIVATE_SLOT(d_func(), void replyEncrypted())
Q_PRIVATE_SLOT(d_func(), void replySslErrors(const QList<QSslError> &, bool *, QList<QSslError> *))
Q_PRIVATE_SLOT(d_func(), void replySslConfigurationChanged(const QSslConfiguration&))
#endif
@@ -280,6 +281,7 @@ public:
void httpAuthenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *auth);
void httpError(QNetworkReply::NetworkError error, const QString &errorString);
#ifndef QT_NO_SSL
+ void replyEncrypted();
void replySslErrors(const QList<QSslError> &, bool *, QList<QSslError> *);
void replySslConfigurationChanged(const QSslConfiguration&);
#endif
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index e12286c459..33357293a3 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -879,6 +879,14 @@ void QNetworkReplyImplPrivate::redirectionRequested(const QUrl &target)
attributes.insert(QNetworkRequest::RedirectionTargetAttribute, target);
}
+void QNetworkReplyImplPrivate::encrypted()
+{
+#ifndef QT_NO_SSL
+ Q_Q(QNetworkReplyImpl);
+ emit q->encrypted();
+#endif
+}
+
void QNetworkReplyImplPrivate::sslErrors(const QList<QSslError> &errors)
{
#ifndef QT_NO_SSL
diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h
index ca9a3b5fd1..9edc0f6b59 100644
--- a/src/network/access/qnetworkreplyimpl_p.h
+++ b/src/network/access/qnetworkreplyimpl_p.h
@@ -176,6 +176,7 @@ public:
void error(QNetworkReply::NetworkError code, const QString &errorString);
void metaDataChanged();
void redirectionRequested(const QUrl &target);
+ void encrypted();
void sslErrors(const QList<QSslError> &errors);
QNetworkAccessBackend *backend;
diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h
index 0d3c72d18a..1512c6dadd 100644
--- a/src/network/access/qnetworkrequest.h
+++ b/src/network/access/qnetworkrequest.h
@@ -47,8 +47,6 @@
#include <QtCore/QUrl>
#include <QtCore/QVariant>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -159,6 +157,4 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QNetworkRequest)
-QT_END_HEADER
-
#endif
diff --git a/src/network/bearer/qbearerplugin_p.h b/src/network/bearer/qbearerplugin_p.h
index cd646d61a5..7b4611074b 100644
--- a/src/network/bearer/qbearerplugin_p.h
+++ b/src/network/bearer/qbearerplugin_p.h
@@ -60,8 +60,6 @@
#ifndef QT_NO_BEARERMANAGEMENT
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -79,8 +77,6 @@ public:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QT_NO_BEARERMANAGEMENT
#endif // QBEARERPLUGIN_P_H
diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp
index ec8d7894fa..49d6babb10 100644
--- a/src/network/bearer/qnetworkconfigmanager.cpp
+++ b/src/network/bearer/qnetworkconfigmanager.cpp
@@ -134,7 +134,7 @@ QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate()
\sa QNetworkConfiguration
*/
-/*!
+/*!
\fn void QNetworkConfigurationManager::configurationAdded(const QNetworkConfiguration &config)
This signal is emitted whenever a new network configuration is added to the system. The new
diff --git a/src/network/bearer/qnetworkconfigmanager.h b/src/network/bearer/qnetworkconfigmanager.h
index c1b3b57825..62b93b19c1 100644
--- a/src/network/bearer/qnetworkconfigmanager.h
+++ b/src/network/bearer/qnetworkconfigmanager.h
@@ -47,8 +47,6 @@
#ifndef QT_NO_BEARERMANAGEMENT
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QNetworkConfigurationManagerPrivate;
@@ -98,8 +96,6 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QNetworkConfigurationManager::Capabilities)
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QT_NO_BEARERMANAGEMENT
#endif // QNETWORKCONFIGMANAGER_H
diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp
index c710556f1c..192bf15b50 100644
--- a/src/network/bearer/qnetworkconfigmanager_p.cpp
+++ b/src/network/bearer/qnetworkconfigmanager_p.cpp
@@ -70,7 +70,7 @@ void QNetworkConfigurationManagerPrivate::initialize()
{
//Two stage construction, because we only want to do this heavyweight work for the winner of the Q_GLOBAL_STATIC race.
bearerThread = new QThread();
- bearerThread->setObjectName(QStringLiteral("bearerThread"));
+ bearerThread->setObjectName(QStringLiteral("Qt bearer thread"));
bearerThread->moveToThread(QCoreApplicationPrivate::mainThread()); // because cleanup() is called in main thread context.
moveToThread(bearerThread);
diff --git a/src/network/bearer/qnetworkconfiguration.h b/src/network/bearer/qnetworkconfiguration.h
index 97fb1d270b..25dafcb282 100644
--- a/src/network/bearer/qnetworkconfiguration.h
+++ b/src/network/bearer/qnetworkconfiguration.h
@@ -49,8 +49,6 @@
#include <QtCore/qlist.h>
#include <QtCore/qmetatype.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QNetworkConfigurationPrivate;
@@ -130,6 +128,4 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QNetworkConfiguration)
-QT_END_HEADER
-
#endif // QNETWORKCONFIGURATION_H
diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp
index f06a2d0df4..cca95fce8c 100644
--- a/src/network/bearer/qnetworksession.cpp
+++ b/src/network/bearer/qnetworksession.cpp
@@ -66,37 +66,37 @@ QT_BEGIN_NAMESPACE
\ingroup network
A QNetworkSession enables control over the system's network interfaces. The session's configuration
- parameter are determined via the QNetworkConfiguration object to which it is bound. Depending on the
+ parameter are determined via the QNetworkConfiguration object to which it is bound. Depending on the
type of the session (single access point or service network) a session may be linked to one or more
- network interfaces. By means of \l{open()}{opening} and \l{close()}{closing} of network sessions
- a developer can start and stop the systems network interfaces. If the configuration represents
+ network interfaces. By means of \l{open()}{opening} and \l{close()}{closing} of network sessions
+ a developer can start and stop the systems network interfaces. If the configuration represents
multiple access points (see \l QNetworkConfiguration::ServiceNetwork) more advanced features such as roaming may be supported.
- QNetworkSession supports session management within the same process and depending on the platform's
- capabilities may support out-of-process sessions. If the same
+ QNetworkSession supports session management within the same process and depending on the platform's
+ capabilities may support out-of-process sessions. If the same
network configuration is used by multiple open sessions the underlying network interface is only terminated once
the last session has been closed.
\section1 Roaming
- Applications may connect to the preferredConfigurationChanged() signal in order to
- receive notifications when a more suitable access point becomes available.
+ Applications may connect to the preferredConfigurationChanged() signal in order to
+ receive notifications when a more suitable access point becomes available.
In response to this signal the application must either initiate the roaming via migrate()
- or ignore() the new access point. Once the session has roamed the
- newConfigurationActivated() signal is emitted. The application may now test the
+ or ignore() the new access point. Once the session has roamed the
+ newConfigurationActivated() signal is emitted. The application may now test the
carrier and must either accept() or reject() it. The session will return to the previous
access point if the roaming was rejected. The subsequent state diagram depicts the required
state transitions.
-
+
\image roaming-states.png
- Some platforms may distinguish forced roaming and application level roaming (ALR).
- ALR implies that the application controls (via migrate(), ignore(), accept() and reject())
+ Some platforms may distinguish forced roaming and application level roaming (ALR).
+ ALR implies that the application controls (via migrate(), ignore(), accept() and reject())
whether a network session can roam from one access point to the next. Such control is useful
if the application maintains stateful socket connections and wants to control the transition from
- one interface to the next. Forced roaming implies that the system automatically roams to the next network without
+ one interface to the next. Forced roaming implies that the system automatically roams to the next network without
consulting the application. This has the advantage that the application can make use of roaming features
- without actually being aware of it. It is expected that the application detects that the underlying
+ without actually being aware of it. It is expected that the application detects that the underlying
socket is broken and automatically reconnects via the new network link.
If the platform supports both modes of roaming, an application indicates its preference
@@ -105,7 +105,7 @@ QT_BEGIN_NAMESPACE
level roaming. If the client does not connect to the preferredConfigurationChanged(), forced roaming
is used. If forced roaming is not supported the network session will not roam by default.
- Some applications may want to suppress any form of roaming altogether. Possible use cases may be
+ Some applications may want to suppress any form of roaming altogether. Possible use cases may be
high priority downloads or remote services which cannot handle a roaming enabled client. Clients
can suppress roaming by connecting to the preferredConfigurationChanged() signal and answer each
signal emission with ignore().
@@ -120,19 +120,19 @@ QT_BEGIN_NAMESPACE
single access point configuration the state of the session is the same as the state of the
associated network interface.
- \value Invalid The session is invalid due to an invalid configuration. This may
- happen due to a removed access point or a configuration that was
+ \value Invalid The session is invalid due to an invalid configuration. This may
+ happen due to a removed access point or a configuration that was
invalid to begin with.
\value NotAvailable The session is based on a defined but not yet discovered QNetworkConfiguration
(see \l QNetworkConfiguration::StateFlag).
\value Connecting The network session is being established.
\value Connected The network session is connected. If the current process wishes to use this session
- it has to register its interest by calling open(). A network session
+ it has to register its interest by calling open(). A network session
is considered to be ready for socket operations if it isOpen() and connected.
\value Closing The network session is in the process of being shut down.
\value Disconnected The network session is not connected. The associated QNetworkConfiguration
has the state QNetworkConfiguration::Discovered.
- \value Roaming The network session is roaming from one access point to another
+ \value Roaming The network session is roaming from one access point to another
access point.
*/
@@ -194,16 +194,16 @@ QT_BEGIN_NAMESPACE
If the roaming process is non-seamless the IP address will change which means that
a socket becomes invalid. However seamless mobility can ensure that the local IP address
does not change. This is achieved by using a virtual IP address which is bound to the actual
- link address. During the roaming process the virtual address is attached to the new link
+ link address. During the roaming process the virtual address is attached to the new link
address.
- Some platforms may support the concept of Forced Roaming and Application Level Roaming (ALR).
- Forced roaming implies that the platform may simply roam to a new configuration without
+ Some platforms may support the concept of Forced Roaming and Application Level Roaming (ALR).
+ Forced roaming implies that the platform may simply roam to a new configuration without
consulting applications. It is up to the application to detect the link layer loss and reestablish
- its sockets. In contrast ALR provides the opportunity to prevent the system from roaming.
+ its sockets. In contrast ALR provides the opportunity to prevent the system from roaming.
If this session is based on a configuration that supports roaming the application can choose
- whether it wants to be consulted (ALR use case) by connecting to this signal. For as long as this signal
- connection remains the session remains registered as a roaming stakeholder; otherwise roaming will
+ whether it wants to be consulted (ALR use case) by connecting to this signal. For as long as this signal
+ connection remains the session remains registered as a roaming stakeholder; otherwise roaming will
be enforced by the platform.
\sa migrate(), ignore(), QNetworkConfiguration::isRoamingAvailable()
@@ -214,7 +214,7 @@ QT_BEGIN_NAMESPACE
This signal is emitted once the session has roamed to the new access point.
The application may reopen its socket and test the suitability of the new network link.
- Subsequently it must either accept() or reject() the new access point.
+ Subsequently it must either accept() or reject() the new access point.
\sa accept(), reject()
*/
@@ -222,8 +222,8 @@ QT_BEGIN_NAMESPACE
/*!
\fn void QNetworkSession::opened()
- This signal is emitted when the network session has been opened.
-
+ This signal is emitted when the network session has been opened.
+
The underlying network interface will not be shut down as long as the session remains open.
Note that this feature is dependent on \l{QNetworkConfigurationManager::SystemSessionSupport}{system wide session support}.
*/
@@ -292,12 +292,12 @@ QNetworkSession::~QNetworkSession()
The system will not terminate a network interface until the session reference counter reaches zero.
Therefore an open session allows an application to register its use of the interface.
- As a result of calling open() the interface will be started if it is not connected/up yet.
+ As a result of calling open() the interface will be started if it is not connected/up yet.
Some platforms may not provide support for out-of-process sessions. On such platforms the session
- counter ignores any sessions held by another process. The platform capabilities can be
+ counter ignores any sessions held by another process. The platform capabilities can be
detected via QNetworkConfigurationManager::capabilities().
- Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired
+ Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired
by connecting to the stateChanged(), opened() or error() signals.
It is not a requirement to open a session in order to monitor the underlying network interface.
@@ -361,10 +361,10 @@ bool QNetworkSession::waitForOpened(int msecs)
\l Disconnected if the current session was the last open session.
If the platform does not support out-of-process sessions calling this function does not stop the
- interface. In this case \l{stop()} has to be used to force a shut down.
+ interface. In this case \l{stop()} has to be used to force a shut down.
The platform capabilities can be detected via QNetworkConfigurationManager::capabilities().
- Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired
+ Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired
by connecting to the stateChanged(), opened() or error() signals.
\sa open(), stop(), isOpen()
@@ -376,7 +376,7 @@ void QNetworkSession::close()
}
/*!
- Invalidates all open sessions against the network interface and therefore stops the
+ Invalidates all open sessions against the network interface and therefore stops the
underlying network interface. This function always changes the session's state() flag to
\l Disconnected.
@@ -426,15 +426,15 @@ bool QNetworkSession::isOpen() const
}
/*!
- Returns the state of the session.
-
- If the session is based on a single access point configuration the state of the
+ Returns the state of the session.
+
+ If the session is based on a single access point configuration the state of the
session is the same as the state of the associated network interface. Therefore
- a network session object can be used to monitor network interfaces.
+ a network session object can be used to monitor network interfaces.
A \l QNetworkConfiguration::ServiceNetwork based session summarizes the state of all its children
- and therefore returns the \l Connected state if at least one of the service network's
- \l {QNetworkConfiguration::children()}{children()} configurations is active.
+ and therefore returns the \l Connected state if at least one of the service network's
+ \l {QNetworkConfiguration::children()}{children()} configurations is active.
Note that it is not required to hold an open session in order to obtain the network interface state.
A connected but closed session may be used to monitor network interfaces whereas an open and connected
@@ -458,7 +458,7 @@ QNetworkSession::SessionError QNetworkSession::error() const
}
/*!
- Returns a human-readable description of the last device error that
+ Returns a human-readable description of the last device error that
occurred.
\sa error()
@@ -485,7 +485,7 @@ QString QNetworkSession::errorString() const
QNetworkConfiguration that is used by this session; otherwise an empty string.
The main purpose of this key is to determine which Internet access point is used
- if the session is based on a \l{QNetworkConfiguration::ServiceNetwork}{ServiceNetwork}.
+ if the session is based on a \l{QNetworkConfiguration::ServiceNetwork}{ServiceNetwork}.
The following code snippet highlights the difference:
\code
QNetworkConfigurationManager mgr;
@@ -512,7 +512,7 @@ QString QNetworkSession::errorString() const
this key may return an identifier for either a
\l {QNetworkConfiguration::ServiceNetwork}{service network} or a
\l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations,
- whereas \e ActiveConfiguration always returns identifiers to
+ whereas \e ActiveConfiguration always returns identifiers to
\l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations.
\row
\li ConnectInBackground
@@ -558,7 +558,7 @@ QVariant QNetworkSession::sessionProperty(const QString &key) const
/*!
Sets the property \a value on the session. The property is identified using
- \a key. Removing an already set property can be achieved by passing an
+ \a key. Removing an already set property can be achieved by passing an
invalid QVariant.
Note that the \e UserChoiceConfiguration and \e ActiveConfiguration
@@ -578,7 +578,7 @@ void QNetworkSession::setSessionProperty(const QString &key, const QVariant &val
}
/*!
- Instructs the session to roam to the new access point. The old access point remains active
+ Instructs the session to roam to the new access point. The old access point remains active
until the application calls accept().
The newConfigurationActivated() signal is emitted once roaming has been completed.
@@ -603,11 +603,11 @@ void QNetworkSession::ignore()
}
/*!
- Instructs the session to permanently accept the new access point. Once this function
+ Instructs the session to permanently accept the new access point. Once this function
has been called the session may not return to the old access point.
The old access point may be closed in the process if there are no other network sessions for it.
- Therefore any open socket that still uses the old access point
+ Therefore any open socket that still uses the old access point
may become unusable and should be closed before completing the migration.
*/
void QNetworkSession::accept()
@@ -617,7 +617,7 @@ void QNetworkSession::accept()
}
/*!
- The new access point is not suitable for the application. By calling this function the
+ The new access point is not suitable for the application. By calling this function the
session returns to the previous access point/configuration. This action may invalidate
any socket that has been created via the not desired access point.
@@ -633,10 +633,10 @@ void QNetworkSession::reject()
/*!
Returns the amount of data sent in bytes; otherwise 0.
- This field value includes the usage across all open network
+ This field value includes the usage across all open network
sessions which use the same network interface.
- If the session is based on a service network configuration the number of
+ If the session is based on a service network configuration the number of
sent bytes across all active member configurations are returned.
This function may not always be supported on all platforms and returns 0.
@@ -652,10 +652,10 @@ quint64 QNetworkSession::bytesWritten() const
/*!
Returns the amount of data received in bytes; otherwise 0.
- This field value includes the usage across all open network
+ This field value includes the usage across all open network
sessions which use the same network interface.
- If the session is based on a service network configuration the number of
+ If the session is based on a service network configuration the number of
sent bytes across all active member configurations are returned.
This function may not always be supported on all platforms and returns 0.
@@ -699,12 +699,12 @@ void QNetworkSessionPrivate::setUsagePolicies(QNetworkSession &session, QNetwork
/*!
\internal
- This function is required to detect whether the client wants to control
+ This function is required to detect whether the client wants to control
the roaming process. If he connects to preferredConfigurationChanged() signal
he intends to influence it. Otherwise QNetworkSession always roams
without registering this session as a stakeholder in the roaming process.
- For more details check the Forced vs ALR roaming section in the QNetworkSession
+ For more details check the Forced vs ALR roaming section in the QNetworkSession
class description.
*/
void QNetworkSession::connectNotify(const QMetaMethod &signal)
diff --git a/src/network/bearer/qnetworksession.h b/src/network/bearer/qnetworksession.h
index 94ab133040..1a76b232e7 100644
--- a/src/network/bearer/qnetworksession.h
+++ b/src/network/bearer/qnetworksession.h
@@ -54,8 +54,6 @@
#undef interface
#endif
-QT_BEGIN_HEADER
-
#include <QtCore/qshareddata.h>
QT_BEGIN_NAMESPACE
@@ -148,8 +146,6 @@ Q_DECLARE_METATYPE(QNetworkSession::State)
Q_DECLARE_METATYPE(QNetworkSession::SessionError)
Q_DECLARE_METATYPE(QNetworkSession::UsagePolicies)
-QT_END_HEADER
-
#endif // QT_NO_BEARERMANAGEMENT
#endif // QNETWORKSESSION_H
diff --git a/src/network/bearer/qnetworksession_p.h b/src/network/bearer/qnetworksession_p.h
index c5af8d8ca0..909cce5e4b 100644
--- a/src/network/bearer/qnetworksession_p.h
+++ b/src/network/bearer/qnetworksession_p.h
@@ -76,7 +76,7 @@ public:
//called by QNetworkSession constructor and ensures
//that the state is immediately updated (w/o actually opening
- //a session). Also this function should take care of
+ //a session). Also this function should take care of
//notification hooks to discover future state changes.
virtual void syncStateWithInterface() = 0;
diff --git a/src/network/doc/snippets/code/src_network_socket_qabstractsocket.cpp b/src/network/doc/snippets/code/src_network_socket_qabstractsocket.cpp
index 01ec19c0ba..af1273dd85 100644
--- a/src/network/doc/snippets/code/src_network_socket_qabstractsocket.cpp
+++ b/src/network/doc/snippets/code/src_network_socket_qabstractsocket.cpp
@@ -47,7 +47,7 @@ if (socket->waitForConnected(1000))
//! [1]
socket->disconnectFromHost();
- if (socket->state() == QAbstractSocket::UnconnectedState ||
+ if (socket->state() == QAbstractSocket::UnconnectedState ||
socket->waitForDisconnected(1000))
qDebug("Disconnected!");
//! [1]
diff --git a/src/network/doc/snippets/network/tcpwait.cpp b/src/network/doc/snippets/network/tcpwait.cpp
index 2be8d7c8ea..fb44e2ded9 100644
--- a/src/network/doc/snippets/network/tcpwait.cpp
+++ b/src/network/doc/snippets/network/tcpwait.cpp
@@ -49,7 +49,7 @@ int main(int argv, char **args)
QTcpSocket socket;
socket.connectToHost("localhost", 1025);
-
+
//! [0]
int numRead = 0, numReadTotal = 0;
char buffer[50];
@@ -58,12 +58,12 @@ int main(int argv, char **args)
numRead = socket.read(buffer, 50);
// do whatever with array
-
+
numReadTotal += numRead;
- if (numRead == 0 && !socket.waitForReadyRead())
+ if (numRead == 0 && !socket.waitForReadyRead())
break;
}
//! [0]
-
+
return app.exec();
}
diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri
index 57df8c8bc8..a4a19988b3 100644
--- a/src/network/kernel/kernel.pri
+++ b/src/network/kernel/kernel.pri
@@ -27,7 +27,7 @@ SOURCES += kernel/qauthenticator.cpp \
unix:SOURCES += kernel/qdnslookup_unix.cpp kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp
-linux-android* {
+android {
SOURCES -= kernel/qdnslookup_unix.cpp
SOURCES += kernel/qdnslookup_android.cpp
}
@@ -39,7 +39,11 @@ win32: {
}
integrity:SOURCES += kernel/qdnslookup_unix.cpp kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp
-mac:LIBS_PRIVATE += -framework SystemConfiguration -framework CoreFoundation -framework CoreServices
+mac {
+ LIBS_PRIVATE += -framework SystemConfiguration -framework CoreFoundation
+ !ios: LIBS_PRIVATE += -framework CoreServices
+}
+
mac:!ios:SOURCES += kernel/qnetworkproxy_mac.cpp
else:win32:SOURCES += kernel/qnetworkproxy_win.cpp
else:blackberry:SOURCES += kernel/qnetworkproxy_blackberry.cpp
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index e337a39415..73991aba96 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -852,7 +852,6 @@ QByteArray QAuthenticatorPrivate::digestMd5Response(const QByteArray &challenge,
//************************Global variables***************************
const int blockSize = 64; //As per RFC2104 Block-size is 512 bits
-const int nDigestLen = 16; //Trunctaion Length of the Hmac-Md5 digest
const quint8 respversion = 1;
const quint8 hirespversion = 1;
diff --git a/src/network/kernel/qauthenticator.h b/src/network/kernel/qauthenticator.h
index 7d199d1dce..4d96104bc0 100644
--- a/src/network/kernel/qauthenticator.h
+++ b/src/network/kernel/qauthenticator.h
@@ -45,8 +45,6 @@
#include <QtCore/qstring.h>
#include <QtCore/qvariant.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -64,7 +62,7 @@ public:
bool operator==(const QAuthenticator &other) const;
inline bool operator!=(const QAuthenticator &other) const { return !operator==(other); }
-
+
QString user() const;
void setUser(const QString &user);
@@ -86,6 +84,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif
diff --git a/src/network/kernel/qdnslookup.h b/src/network/kernel/qdnslookup.h
index 5218c2618a..1df21d866e 100644
--- a/src/network/kernel/qdnslookup.h
+++ b/src/network/kernel/qdnslookup.h
@@ -48,8 +48,6 @@
#include <QtCore/qsharedpointer.h>
#include <QtCore/qstring.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QHostAddress;
@@ -248,6 +246,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QDNSLOOKUP_H
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp
index f15c49104d..dc67b0d835 100644
--- a/src/network/kernel/qhostaddress.cpp
+++ b/src/network/kernel/qhostaddress.cpp
@@ -664,7 +664,7 @@ Q_IPV6ADDR QHostAddress::toIPv6Address() const
Returns the address as a string.
For example, if the address is the IPv4 address 127.0.0.1, the
- returned string is "127.0.0.1". For IPv6 the string format will
+ returned string is "127.0.0.1". For IPv6 the string format will
follow the RFC5952 recommendation.
For QHostAddress::Any, its IPv4 address will be returned ("0.0.0.0")
diff --git a/src/network/kernel/qhostaddress.h b/src/network/kernel/qhostaddress.h
index 0e50a677ed..77a2ec4105 100644
--- a/src/network/kernel/qhostaddress.h
+++ b/src/network/kernel/qhostaddress.h
@@ -49,8 +49,6 @@
struct sockaddr;
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -142,5 +140,4 @@ Q_NETWORK_EXPORT QDataStream &operator>>(QDataStream &, QHostAddress &);
QT_END_NAMESPACE
-QT_END_HEADER
#endif // QHOSTADDRESS_H
diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp
index 6de83c3754..d25372ece6 100644
--- a/src/network/kernel/qhostinfo.cpp
+++ b/src/network/kernel/qhostinfo.cpp
@@ -164,6 +164,9 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver,
int id = theIdCounter.fetchAndAddRelaxed(1); // generate unique ID
if (name.isEmpty()) {
+ if (!receiver)
+ return -1;
+
QHostInfo hostInfo(id);
hostInfo.setError(QHostInfo::HostNotFound);
hostInfo.setErrorString(QCoreApplication::translate("QHostInfo", "No host name given"));
@@ -183,6 +186,9 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver,
bool valid = false;
QHostInfo info = manager->cache.get(name, &valid);
if (valid) {
+ if (!receiver)
+ return -1;
+
info.setLookupId(id);
QHostInfoResult result;
QObject::connect(&result, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection);
@@ -193,7 +199,8 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver,
// cache is not enabled or it was not in the cache, do normal lookup
QHostInfoRunnable* runnable = new QHostInfoRunnable(name, id);
- QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection);
+ if (receiver)
+ QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection);
manager->scheduleLookup(runnable);
}
return id;
@@ -699,8 +706,8 @@ void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e)
}
// cache for 60 seconds
-// cache 64 items
-QHostInfoCache::QHostInfoCache() : max_age(60), enabled(true), cache(64)
+// cache 128 items
+QHostInfoCache::QHostInfoCache() : max_age(60), enabled(true), cache(128)
{
#ifdef QT_QHOSTINFO_CACHE_DISABLED_BY_DEFAULT
enabled = false;
diff --git a/src/network/kernel/qhostinfo.h b/src/network/kernel/qhostinfo.h
index 89cc5ba26b..38d55def34 100644
--- a/src/network/kernel/qhostinfo.h
+++ b/src/network/kernel/qhostinfo.h
@@ -46,8 +46,6 @@
#include <QtCore/qscopedpointer.h>
#include <QtNetwork/qhostaddress.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -98,6 +96,4 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QHostInfo)
-QT_END_HEADER
-
#endif // QHOSTINFO_H
diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp
index 0e147c4877..fac83b922b 100644
--- a/src/network/kernel/qhostinfo_unix.cpp
+++ b/src/network/kernel/qhostinfo_unix.cpp
@@ -323,7 +323,7 @@ QString QHostInfo::localHostName()
QString QHostInfo::localDomainName()
{
-#if !defined(Q_OS_VXWORKS) && !defined(Q_OS_LINUX_ANDROID)
+#if !defined(Q_OS_VXWORKS) && !defined(Q_OS_ANDROID)
resolveLibrary();
if (local_res_ninit) {
// using thread-safe version
diff --git a/src/network/kernel/qnetworkfunctions_wince.h b/src/network/kernel/qnetworkfunctions_wince.h
index 858600bcca..ccf1ed9e38 100644
--- a/src/network/kernel/qnetworkfunctions_wince.h
+++ b/src/network/kernel/qnetworkfunctions_wince.h
@@ -50,8 +50,6 @@
#include <qt_windows.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
DECLARE_HANDLE(SC_HANDLE);
@@ -96,7 +94,5 @@ typedef LPENUM_SERVICE_STATUS_PROCESSA LPENUM_SERVICE_STATUS_PROCESS;
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // Q_OS_WINCE
#endif // QNETWORKFUNCTIONS_WINCE_H
diff --git a/src/network/kernel/qnetworkinterface.h b/src/network/kernel/qnetworkinterface.h
index 9ecc371b54..53d5d6e664 100644
--- a/src/network/kernel/qnetworkinterface.h
+++ b/src/network/kernel/qnetworkinterface.h
@@ -48,8 +48,6 @@
#ifndef QT_NO_NETWORKINTERFACE
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -100,7 +98,7 @@ public:
CanMulticast = 0x20
};
Q_DECLARE_FLAGS(InterfaceFlags, InterfaceFlag)
-
+
QNetworkInterface();
QNetworkInterface(const QNetworkInterface &other);
QNetworkInterface &operator=(const QNetworkInterface &other);
@@ -137,8 +135,6 @@ Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QNetworkInterface &networ
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QT_NO_NETWORKINTERFACE
#endif
diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp
index 46eeb46f98..0ec9554c82 100644
--- a/src/network/kernel/qnetworkinterface_unix.cpp
+++ b/src/network/kernel/qnetworkinterface_unix.cpp
@@ -61,7 +61,7 @@
# define QT_NO_GETIFADDRS
#endif
-#ifdef Q_OS_LINUX_ANDROID
+#ifdef Q_OS_ANDROID
// android lacks if_nameindex
# define QT_NO_IPV6IFNAME
#endif
@@ -328,9 +328,9 @@ static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)
}
break;
}
- if ( if_it != interfaces.end() )
+ if ( if_it != interfaces.end() )
continue;
-
+
QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate;
interfaces << iface;
iface->index = ifindex;
diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp
index 0a2deb8711..02c0801cef 100644
--- a/src/network/kernel/qnetworkinterface_win.cpp
+++ b/src/network/kernel/qnetworkinterface_win.cpp
@@ -109,7 +109,7 @@ static QHash<QHostAddress, QHostAddress> ipv4Netmasks()
IP_ADAPTER_INFO staticBuf[2]; // 2 is arbitrary
PIP_ADAPTER_INFO pAdapter = staticBuf;
ULONG bufSize = sizeof staticBuf;
- QHash<QHostAddress, QHostAddress> ipv4netmasks;
+ QHash<QHostAddress, QHostAddress> ipv4netmasks;
DWORD retval = ptrGetAdaptersInfo(pAdapter, &bufSize);
if (retval == ERROR_BUFFER_OVERFLOW) {
diff --git a/src/network/kernel/qnetworkinterface_win_p.h b/src/network/kernel/qnetworkinterface_win_p.h
index 34f4e18d5e..d6a3366316 100644
--- a/src/network/kernel/qnetworkinterface_win_p.h
+++ b/src/network/kernel/qnetworkinterface_win_p.h
@@ -112,19 +112,19 @@ typedef struct {
// copied from MSDN online help
typedef enum {
- IpPrefixOriginOther = 0,
- IpPrefixOriginManual,
- IpPrefixOriginWellKnown,
- IpPrefixOriginDhcp,
+ IpPrefixOriginOther = 0,
+ IpPrefixOriginManual,
+ IpPrefixOriginWellKnown,
+ IpPrefixOriginDhcp,
IpPrefixOriginRouterAdvertisement
} IP_PREFIX_ORIGIN;
typedef enum {
- IpSuffixOriginOther = 0,
- IpSuffixOriginManual,
- IpSuffixOriginWellKnown,
- IpSuffixOriginDhcp,
- IpSuffixOriginLinkLayerAddress,
+ IpSuffixOriginOther = 0,
+ IpSuffixOriginManual,
+ IpSuffixOriginWellKnown,
+ IpSuffixOriginDhcp,
+ IpSuffixOriginLinkLayerAddress,
IpSuffixOriginRandom
} IP_SUFFIX_ORIGIN;
@@ -164,11 +164,11 @@ typedef struct _IP_ADAPTER_UNICAST_ADDRESS {
ULONG LeaseLifetime;
} IP_ADAPTER_UNICAST_ADDRESS, *PIP_ADAPTER_UNICAST_ADDRESS;
-typedef struct _IP_ADAPTER_ANYCAST_ADDRESS
+typedef struct _IP_ADAPTER_ANYCAST_ADDRESS
IP_ADAPTER_ANYCAST_ADDRESS, *PIP_ADAPTER_ANYCAST_ADDRESS;
-typedef struct _IP_ADAPTER_MULTICAST_ADDRESS
- IP_ADAPTER_MULTICAST_ADDRESS,
+typedef struct _IP_ADAPTER_MULTICAST_ADDRESS
+ IP_ADAPTER_MULTICAST_ADDRESS,
*PIP_ADAPTER_MULTICAST_ADDRESS;
typedef struct _IP_ADAPTER_DNS_SERVER_ADDRESS
@@ -186,7 +186,7 @@ typedef struct _IP_ADAPTER_PREFIX {
struct _IP_ADAPTER_PREFIX* Next;
SOCKET_ADDRESS Address;
ULONG PrefixLength;
-} IP_ADAPTER_PREFIX,
+} IP_ADAPTER_PREFIX,
*PIP_ADAPTER_PREFIX;
typedef struct _IP_ADAPTER_ADDRESSES {
@@ -215,7 +215,7 @@ typedef struct _IP_ADAPTER_ADDRESSES {
DWORD Ipv6IfIndex;
DWORD ZoneIndices[16];
PIP_ADAPTER_PREFIX FirstPrefix;
-} IP_ADAPTER_ADDRESSES,
+} IP_ADAPTER_ADDRESSES,
*PIP_ADAPTER_ADDRESSES;
typedef struct {
@@ -227,7 +227,7 @@ typedef struct _IP_ADDR_STRING {
IP_ADDRESS_STRING IpAddress;
IP_MASK_STRING IpMask;
DWORD Context;
-} IP_ADDR_STRING,
+} IP_ADDR_STRING,
*PIP_ADDR_STRING;
typedef struct _IP_ADAPTER_INFO {
@@ -249,7 +249,7 @@ typedef struct _IP_ADAPTER_INFO {
IP_ADDR_STRING SecondaryWinsServer;
time_t LeaseObtained;
time_t LeaseExpires;
-} IP_ADAPTER_INFO,
+} IP_ADAPTER_INFO,
*PIP_ADAPTER_INFO;
typedef struct {
diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp
index 54229295bb..a38655d244 100644
--- a/src/network/kernel/qnetworkproxy.cpp
+++ b/src/network/kernel/qnetworkproxy.cpp
@@ -1562,7 +1562,7 @@ void QNetworkProxyFactory::setApplicationProxyFactory(QNetworkProxyFactory *fact
\li On Windows platforms, this function may take several seconds to
execute depending on the configuration of the user's system.
- \li On BlackBerry, only UrlRequest queries are supported. SOCKS is
+ \li On BlackBerry, only UrlRequest and TcpSocket queries are supported. SOCKS is
not supported. The proxy credentials are only retrieved for the
default configuration.
\endlist
diff --git a/src/network/kernel/qnetworkproxy.h b/src/network/kernel/qnetworkproxy.h
index 081a993e33..153c84028a 100644
--- a/src/network/kernel/qnetworkproxy.h
+++ b/src/network/kernel/qnetworkproxy.h
@@ -48,8 +48,6 @@
#ifndef QT_NO_NETWORKPROXY
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -220,8 +218,6 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QNetworkProxy)
-QT_END_HEADER
-
#endif // QT_NO_NETWORKPROXY
#endif // QHOSTINFO_H
diff --git a/src/network/kernel/qnetworkproxy_blackberry.cpp b/src/network/kernel/qnetworkproxy_blackberry.cpp
index 2743b90404..c0f5c43a78 100644
--- a/src/network/kernel/qnetworkproxy_blackberry.cpp
+++ b/src/network/kernel/qnetworkproxy_blackberry.cpp
@@ -63,14 +63,36 @@ QT_BEGIN_NAMESPACE
QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &query)
{
- QNetworkProxy proxy;
+ if (query.url().scheme() == QLatin1String("file")
+ || query.url().scheme() == QLatin1String("qrc"))
+ return QList<QNetworkProxy>() << QNetworkProxy(QNetworkProxy::NoProxy);
- if (query.queryType() != QNetworkProxyQuery::UrlRequest) {
+ if (query.queryType() != QNetworkProxyQuery::UrlRequest
+ && query.queryType() != QNetworkProxyQuery::TcpSocket) {
qWarning("Unsupported query type: %d", query.queryType());
return QList<QNetworkProxy>() << QNetworkProxy(QNetworkProxy::NoProxy);
}
- QUrl url = query.url();
+ QUrl url;
+ if (query.queryType() == QNetworkProxyQuery::UrlRequest) {
+ url = query.url();
+ } else if (query.queryType() == QNetworkProxyQuery::TcpSocket
+ && !query.peerHostName().isEmpty()) {
+ url.setHost(query.peerHostName());
+ switch (query.peerPort()) {
+ case 443:
+ url.setScheme(QStringLiteral("https"));
+ break;
+ case 21:
+ url.setScheme(QStringLiteral("ftp"));
+ break;
+ default:
+ // for unknown ports, we just pretend we are dealing
+ // with a HTTP URL, otherwise we will not get a proxy
+ // from the netstatus API
+ url.setScheme(QStringLiteral("http"));
+ }
+ }
if (!url.isValid()) {
qWarning("Invalid URL: %s", qPrintable(url.toString()));
@@ -112,6 +134,8 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro
return QList<QNetworkProxy>() << QNetworkProxy(QNetworkProxy::NoProxy);
}
+ QNetworkProxy proxy;
+
QString protocol = query.protocolTag();
if (protocol.startsWith(QLatin1String("http"), Qt::CaseInsensitive)) { // http, https
proxy.setType((QNetworkProxy::HttpProxy));
diff --git a/src/network/kernel/qnetworkproxy_mac.cpp b/src/network/kernel/qnetworkproxy_mac.cpp
index a283b7ee05..4a4acb59d4 100644
--- a/src/network/kernel/qnetworkproxy_mac.cpp
+++ b/src/network/kernel/qnetworkproxy_mac.cpp
@@ -231,7 +231,6 @@ QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query)
// PAC is enabled
CFStringRef cfPacLocation = (CFStringRef)CFDictionaryGetValue(dict, kSCPropNetProxiesProxyAutoConfigURLString);
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
QCFType<CFDataRef> pacData;
QCFType<CFURLRef> pacUrl = CFURLCreateWithString(kCFAllocatorDefault, cfPacLocation, NULL);
@@ -275,9 +274,7 @@ QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query)
result << proxyFromDictionary(proxy);
}
return result;
- } else
-#endif
- {
+ } else {
QString pacLocation = QCFString::toQString(cfPacLocation);
qWarning("Mac system proxy: PAC script at \"%s\" not handled", qPrintable(pacLocation));
}
diff --git a/src/network/kernel/qurlinfo_p.h b/src/network/kernel/qurlinfo_p.h
index 955a2eb325..1aa59f25ad 100644
--- a/src/network/kernel/qurlinfo_p.h
+++ b/src/network/kernel/qurlinfo_p.h
@@ -46,8 +46,6 @@
#include <QtCore/qstring.h>
#include <QtCore/qiodevice.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -125,6 +123,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QURLINFO_H
diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h
index b7e3f2853a..46114abf73 100644
--- a/src/network/socket/qabstractsocket.h
+++ b/src/network/socket/qabstractsocket.h
@@ -48,8 +48,6 @@
#include <QtCore/qdebug.h>
#endif
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -242,6 +240,4 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QAbstractSocket::SocketState)
Q_DECLARE_METATYPE(QAbstractSocket::SocketError)
-QT_END_HEADER
-
#endif // QABSTRACTSOCKET_H
diff --git a/src/network/socket/qlocalserver.h b/src/network/socket/qlocalserver.h
index d7d6b16e10..b5791db653 100644
--- a/src/network/socket/qlocalserver.h
+++ b/src/network/socket/qlocalserver.h
@@ -44,8 +44,6 @@
#include <QtNetwork/qabstractsocket.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -109,7 +107,5 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QLocalServer::SocketOptions)
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QLOCALSERVER_H
diff --git a/src/network/socket/qlocalserver_unix.cpp b/src/network/socket/qlocalserver_unix.cpp
index 2bcf1ac83e..51a33a4b35 100644
--- a/src/network/socket/qlocalserver_unix.cpp
+++ b/src/network/socket/qlocalserver_unix.cpp
@@ -297,9 +297,9 @@ void QLocalServerPrivate::waitForNewConnection(int msec, bool *timedOut)
FD_ZERO(&readfds);
FD_SET(listenSocket, &readfds);
- timeval timeout;
+ struct timespec timeout;
timeout.tv_sec = msec / 1000;
- timeout.tv_usec = (msec % 1000) * 1000;
+ timeout.tv_nsec = (msec % 1000) * 1000 * 1000;
int result = -1;
result = qt_safe_select(listenSocket + 1, &readfds, 0, 0, (msec == -1) ? 0 : &timeout);
diff --git a/src/network/socket/qlocalsocket.cpp b/src/network/socket/qlocalsocket.cpp
index bd2c4258b5..1ce6568364 100644
--- a/src/network/socket/qlocalsocket.cpp
+++ b/src/network/socket/qlocalsocket.cpp
@@ -71,18 +71,17 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
+ \fn void QLocalSocket::open(OpenMode openMode)
- Attempts to make a connection to \a name.
+ Equivalent to connectToServer(OpenMode mode).
+ The socket is opened in the given \a openMode to the server defined by setServerName().
- The socket is opened in the given \a openMode and first enters ConnectingState.
- It then attempts to connect to the address or addresses returned by the lookup.
- Finally, if a connection is established, QLocalSocket enters ConnectedState
- and emits connected().
-
- At any point, the socket can emit error() to signal that an error occurred.
+ Note that unlike in most other QIODevice subclasses, open() may not open the device directly.
+ The function return false if the socket was already connected or if the server to connect
+ to was not defined and true in any other case. The connected() or error() signals will be
+ emitted once the device is actualy open (or the connection failed).
- See also state(), serverName(), and waitForConnected().
+ See connectToServer() for more details.
*/
/*!
@@ -354,8 +353,62 @@ QLocalSocket::~QLocalSocket()
}
/*!
- Returns the name of the peer as specified by connectToServer(), or an
- empty QString if connectToServer() has not been called or it failed.
+ \since 5.1
+
+ Attempts to make a connection to serverName().
+ setServerName() must be called before you open the connection.
+ Alternatively you can use connectToServer(const QString &name, OpenMode openMode);
+
+ The socket is opened in the given \a openMode and first enters ConnectingState.
+ If a connection is established, QLocalSocket enters ConnectedState and emits connected().
+
+ After calling this function, the socket can emit error() to signal that an error occurred.
+
+ \sa state(), serverName(), waitForConnected()
+*/
+void QLocalSocket::connectToServer(OpenMode openMode)
+{
+ open(openMode);
+}
+
+/*! \overload
+
+ Set the server \a name and attempts to make a connection to it.
+
+ The socket is opened in the given \a openMode and first enters ConnectingState.
+ If a connection is established, QLocalSocket enters ConnectedState and emits connected().
+
+ After calling this function, the socket can emit error() to signal that an error occurred.
+
+ \sa state(), serverName(), waitForConnected()
+*/
+void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
+{
+ setServerName(name);
+ open(openMode);
+}
+
+/*!
+ \since 5.1
+
+ Set the \a name of the peer to connect to.
+ On Windows name is the name of a named pipe; on Unix name is the name of a local domain socket.
+
+ This function must be called when the socket is not connected.
+*/
+void QLocalSocket::setServerName(const QString & name)
+{
+ Q_D(QLocalSocket);
+ if (d->state != UnconnectedState) {
+ qWarning("QLocalSocket::setServerName() called while not in unconnected state");
+ return;
+ }
+ d->serverName = name;
+}
+
+/*!
+ Returns the name of the peer as specified by setServerName(), or an
+ empty QString if setServerName() has not been called or connectToServer() failed.
\sa connectToServer(), fullServerName()
diff --git a/src/network/socket/qlocalsocket.h b/src/network/socket/qlocalsocket.h
index e1ee174608..427dab1def 100644
--- a/src/network/socket/qlocalsocket.h
+++ b/src/network/socket/qlocalsocket.h
@@ -45,8 +45,6 @@
#include <QtCore/qiodevice.h>
#include <QtNetwork/qabstractsocket.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -86,9 +84,11 @@ public:
QLocalSocket(QObject *parent = 0);
~QLocalSocket();
+ void connectToServer(OpenMode openMode = ReadWrite);
void connectToServer(const QString &name, OpenMode openMode = ReadWrite);
void disconnectFromServer();
+ void setServerName(const QString &name);
QString serverName() const;
QString fullServerName() const;
@@ -97,6 +97,7 @@ public:
virtual qint64 bytesAvailable() const;
virtual qint64 bytesToWrite() const;
virtual bool canReadLine() const;
+ virtual bool open(OpenMode openMode = ReadWrite) Q_DECL_OVERRIDE;
virtual void close();
LocalSocketError error() const;
bool flush();
@@ -152,6 +153,4 @@ Q_NETWORK_EXPORT QDebug operator<<(QDebug, QLocalSocket::LocalSocketState);
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QLOCALSOCKET_H
diff --git a/src/network/socket/qlocalsocket_tcp.cpp b/src/network/socket/qlocalsocket_tcp.cpp
index cbae8d58ff..edde5a4687 100644
--- a/src/network/socket/qlocalsocket_tcp.cpp
+++ b/src/network/socket/qlocalsocket_tcp.cpp
@@ -214,29 +214,30 @@ void QLocalSocketPrivate::errorOccurred(QLocalSocket::LocalSocketError error, co
q->emit stateChanged(state);
}
-void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
+bool QLocalSocket::open(OpenMode openMode)
{
Q_D(QLocalSocket);
- if (state() == ConnectedState
- || state() == ConnectingState)
- return;
+ if (state() == ConnectedState || state() == ConnectingState) {
+ setErrorString(tr("Trying to connect while connection is in progress"));
+ emit error(QLocalSocket::OperationError);
+ return false;
+ }
d->errorString.clear();
d->state = ConnectingState;
emit stateChanged(d->state);
- if (name.isEmpty()) {
+ if (d->serverName.isEmpty()) {
d->errorOccurred(ServerNotFoundError,
QLatin1String("QLocalSocket::connectToServer"));
- return;
+ return false;
}
- d->serverName = name;
const QLatin1String prefix("QLocalServer/");
if (name.startsWith(prefix))
- d->fullServerName = name;
+ d->fullServerName = d->serverName;
else
- d->fullServerName = prefix + name;
+ d->fullServerName = prefix + d->serverName;
QSettings settings(QLatin1String("QtProject"), QLatin1String("Qt"));
bool ok;
@@ -244,10 +245,11 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
if (!ok) {
d->errorOccurred(ServerNotFoundError,
QLatin1String("QLocalSocket::connectToServer"));
- return;
+ return false;
}
d->tcpSocket->connectToHost(QHostAddress::LocalHost, port, openMode);
QIODevice::open(openMode);
+ return true;
}
bool QLocalSocket::setSocketDescriptor(qintptr socketDescriptor,
diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp
index e846e43e73..67182e57b0 100644
--- a/src/network/socket/qlocalsocket_unix.cpp
+++ b/src/network/socket/qlocalsocket_unix.cpp
@@ -221,14 +221,14 @@ void QLocalSocketPrivate::errorOccurred(QLocalSocket::LocalSocketError error, co
q->emit stateChanged(state);
}
-void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
+bool QLocalSocket::open(OpenMode openMode)
{
Q_D(QLocalSocket);
if (state() == ConnectedState || state() == ConnectingState) {
QString errorString = d->generateErrorString(QLocalSocket::OperationError, QLatin1String("QLocalSocket::connectToserver"));
setErrorString(errorString);
emit error(QLocalSocket::OperationError);
- return;
+ return false;
}
d->errorString.clear();
@@ -236,17 +236,17 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
d->state = ConnectingState;
emit stateChanged(d->state);
- if (name.isEmpty()) {
+ if (d->serverName.isEmpty()) {
d->errorOccurred(ServerNotFoundError,
QLatin1String("QLocalSocket::connectToServer"));
- return;
+ return false;
}
// create the socket
if (-1 == (d->connectingSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0))) {
d->errorOccurred(UnsupportedSocketOperationError,
QLatin1String("QLocalSocket::connectToServer"));
- return;
+ return false;
}
// set non blocking so we can try to connect and it won't wait
int flags = fcntl(d->connectingSocket, F_GETFL, 0);
@@ -254,13 +254,14 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
|| -1 == (fcntl(d->connectingSocket, F_SETFL, flags | O_NONBLOCK))) {
d->errorOccurred(UnknownSocketError,
QLatin1String("QLocalSocket::connectToServer"));
- return;
+ return false;
}
// _q_connectToSocket does the actual connecting
- d->connectingName = name;
+ d->connectingName = d->serverName;
d->connectingOpenMode = openMode;
d->_q_connectToSocket();
+ return true;
}
/*!
diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp
index 660e0901f8..cdfa18377d 100644
--- a/src/network/socket/qlocalsocket_win.cpp
+++ b/src/network/socket/qlocalsocket_win.cpp
@@ -128,33 +128,33 @@ void QLocalSocketPrivate::destroyPipeHandles()
}
}
-void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
+bool QLocalSocket::open(OpenMode openMode)
{
Q_D(QLocalSocket);
if (state() == ConnectedState || state() == ConnectingState) {
setErrorString(tr("Trying to connect while connection is in progress"));
emit error(QLocalSocket::OperationError);
- return;
+ return false;
}
d->error = QLocalSocket::UnknownSocketError;
d->errorString = QString();
d->state = ConnectingState;
emit stateChanged(d->state);
- if (name.isEmpty()) {
+ if (d->serverName.isEmpty()) {
d->error = QLocalSocket::ServerNotFoundError;
setErrorString(QLocalSocket::tr("%1: Invalid name").arg(QLatin1String("QLocalSocket::connectToServer")));
d->state = UnconnectedState;
emit error(d->error);
emit stateChanged(d->state);
- return;
+ return false;
}
QString pipePath = QLatin1String("\\\\.\\pipe\\");
- if (name.startsWith(pipePath))
- d->fullServerName = name;
+ if (d->serverName.startsWith(pipePath))
+ d->fullServerName = d->serverName;
else
- d->fullServerName = pipePath + name;
+ d->fullServerName = pipePath + d->serverName;
// Try to open a named pipe
HANDLE localSocket;
forever {
@@ -184,15 +184,15 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
if (localSocket == INVALID_HANDLE_VALUE) {
d->setErrorString(QLatin1String("QLocalSocket::connectToServer"));
d->fullServerName = QString();
- return;
+ return false;
}
// we have a valid handle
- d->serverName = name;
if (setSocketDescriptor((qintptr)localSocket, ConnectedState, openMode)) {
d->handle = localSocket;
emit connected();
}
+ return true;
}
// This is reading from the buffer
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index 4f3408b067..4c94c4dbb9 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -1126,9 +1126,9 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) co
FD_ZERO(&fds);
FD_SET(socketDescriptor, &fds);
- struct timeval tv;
+ struct timespec tv;
tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
+ tv.tv_nsec = (timeout % 1000) * 1000 * 1000;
int retval;
if (selectForRead)
@@ -1152,9 +1152,9 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool c
if (checkWrite)
FD_SET(socketDescriptor, &fdwrite);
- struct timeval tv;
+ struct timespec tv;
tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
+ tv.tv_nsec = (timeout % 1000) * 1000 * 1000;
int ret;
ret = qt_safe_select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv);
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index a135abd5e3..3027b77161 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -1450,7 +1450,7 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) co
bool readEnabled = selectForRead && readNotifier && readNotifier->isEnabled();
if (readEnabled)
readNotifier->setEnabled(false);
-
+
fd_set fds;
int ret = 0;
diff --git a/src/network/socket/qtcpserver.h b/src/network/socket/qtcpserver.h
index dfabfa1be7..8e25aa5a29 100644
--- a/src/network/socket/qtcpserver.h
+++ b/src/network/socket/qtcpserver.h
@@ -46,8 +46,6 @@
#include <QtNetwork/qabstractsocket.h>
#include <QtNetwork/qhostaddress.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -108,6 +106,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QTCPSERVER_H
diff --git a/src/network/socket/qtcpsocket.cpp b/src/network/socket/qtcpsocket.cpp
index fb5d46a9f7..ce37401a89 100644
--- a/src/network/socket/qtcpsocket.cpp
+++ b/src/network/socket/qtcpsocket.cpp
@@ -41,7 +41,7 @@
//#define QTCPSOCKET_DEBUG
-/*!
+/*!
\class QTcpSocket
\brief The QTcpSocket class provides a TCP socket.
diff --git a/src/network/socket/qtcpsocket.h b/src/network/socket/qtcpsocket.h
index 44fb68a207..ed5ce4aeed 100644
--- a/src/network/socket/qtcpsocket.h
+++ b/src/network/socket/qtcpsocket.h
@@ -45,8 +45,6 @@
#include <QtNetwork/qabstractsocket.h>
#include <QtCore/qvariant.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -69,6 +67,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QTCPSOCKET_H
diff --git a/src/network/socket/qudpsocket.h b/src/network/socket/qudpsocket.h
index 7a064a3432..da6306a430 100644
--- a/src/network/socket/qudpsocket.h
+++ b/src/network/socket/qudpsocket.h
@@ -45,8 +45,6 @@
#include <QtNetwork/qabstractsocket.h>
#include <QtNetwork/qhostaddress.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -90,6 +88,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QUDPSOCKET_H
diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp
index 6fcd977759..4e33001d8d 100644
--- a/src/network/ssl/qssl.cpp
+++ b/src/network/ssl/qssl.cpp
@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
\enum QSsl::KeyType
Describes the two types of keys QSslKey supports.
-
+
\value PrivateKey A private key.
\value PublicKey A public key.
*/
diff --git a/src/network/ssl/qssl.h b/src/network/ssl/qssl.h
index 80ccfadecb..06d80965e2 100644
--- a/src/network/ssl/qssl.h
+++ b/src/network/ssl/qssl.h
@@ -46,8 +46,6 @@
#include <QtCore/qglobal.h>
#include <QtCore/QFlags>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -106,6 +104,4 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QSsl::SslOptions)
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QSSL_H
diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h
index 23f9638981..988071eb9d 100644
--- a/src/network/ssl/qsslcertificate.h
+++ b/src/network/ssl/qsslcertificate.h
@@ -56,8 +56,6 @@
#include <QtCore/qmap.h>
#include <QtNetwork/qssl.h>
-QT_BEGIN_HEADER
-
#ifndef QT_NO_SSL
QT_BEGIN_NAMESPACE
@@ -164,6 +162,4 @@ Q_DECLARE_METATYPE(QSslCertificate)
#endif // QT_NO_SSL
-QT_END_HEADER
-
#endif
diff --git a/src/network/ssl/qsslcertificateextension.h b/src/network/ssl/qsslcertificateextension.h
index ce7ff54941..080b1ccc4e 100644
--- a/src/network/ssl/qsslcertificateextension.h
+++ b/src/network/ssl/qsslcertificateextension.h
@@ -47,8 +47,6 @@
#include <QtCore/qstring.h>
#include <QtCore/qvariant.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -85,8 +83,6 @@ Q_DECLARE_SHARED(QSslCertificateExtension)
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QSSLCERTIFICATEEXTENSION_H
diff --git a/src/network/ssl/qsslcipher.cpp b/src/network/ssl/qsslcipher.cpp
index 46131fc1aa..b045d2eba9 100644
--- a/src/network/ssl/qsslcipher.cpp
+++ b/src/network/ssl/qsslcipher.cpp
@@ -194,7 +194,7 @@ QString QSslCipher::keyExchangeMethod() const
{
return d->keyExchangeMethod;
}
-
+
/*!
Returns the cipher's authentication method as a QString.
*/
diff --git a/src/network/ssl/qsslcipher.h b/src/network/ssl/qsslcipher.h
index 93ae15c3f5..e351d7949b 100644
--- a/src/network/ssl/qsslcipher.h
+++ b/src/network/ssl/qsslcipher.h
@@ -47,8 +47,6 @@
#include <QtCore/qscopedpointer.h>
#include <QtNetwork/qssl.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -97,7 +95,5 @@ Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslCipher &cipher);
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif
diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp
index 0ae67b3c1f..afbd4fac77 100644
--- a/src/network/ssl/qsslconfiguration.cpp
+++ b/src/network/ssl/qsslconfiguration.cpp
@@ -173,7 +173,7 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const
return true;
return d->peerCertificate == other.d->peerCertificate &&
d->peerCertificateChain == other.d->peerCertificateChain &&
- d->localCertificate == other.d->localCertificate &&
+ d->localCertificateChain == other.d->localCertificateChain &&
d->privateKey == other.d->privateKey &&
d->sessionCipher == other.d->sessionCipher &&
d->ciphers == other.d->ciphers &&
@@ -212,7 +212,7 @@ bool QSslConfiguration::isNull() const
d->allowRootCertOnDemandLoading == true &&
d->caCertificates.count() == 0 &&
d->ciphers.count() == 0 &&
- d->localCertificate.isNull() &&
+ d->localCertificateChain.isEmpty() &&
d->privateKey.isNull() &&
d->peerCertificate.isNull() &&
d->peerCertificateChain.count() == 0 &&
@@ -313,6 +313,45 @@ void QSslConfiguration::setPeerVerifyDepth(int depth)
}
/*!
+ Returns the certificate chain to be presented to the peer during
+ the SSL handshake process.
+
+ \sa localCertificate()
+ \since 5.1
+*/
+QList<QSslCertificate> QSslConfiguration::localCertificateChain() const
+{
+ return d->localCertificateChain;
+}
+
+/*!
+ Sets the certificate chain to be presented to the peer during the
+ SSL handshake to be \a localChain.
+
+ Setting the certificate chain once the connection has been
+ established has no effect.
+
+ A certificate is the means of identification used in the SSL
+ process. The local certificate is used by the remote end to verify
+ the local user's identity against its list of Certification
+ Authorities. In most cases, such as in HTTP web browsing, only
+ servers identify to the clients, so the client does not send a
+ certificate.
+
+ Unlike QSslConfiguration::setLocalCertificate() this method allows
+ you to specify any intermediate certificates required in order to
+ validate your certificate. The first item in the list must be the
+ leaf certificate.
+
+ \sa localCertificateChain()
+ \since 5.1
+ */
+void QSslConfiguration::setLocalCertificateChain(const QList<QSslCertificate> &localChain)
+{
+ d->localCertificateChain = localChain;
+}
+
+/*!
Returns the certificate to be presented to the peer during the SSL
handshake process.
@@ -320,7 +359,9 @@ void QSslConfiguration::setPeerVerifyDepth(int depth)
*/
QSslCertificate QSslConfiguration::localCertificate() const
{
- return d->localCertificate;
+ if (d->localCertificateChain.isEmpty())
+ return QSslCertificate();
+ return d->localCertificateChain[0];
}
/*!
@@ -341,7 +382,8 @@ QSslCertificate QSslConfiguration::localCertificate() const
*/
void QSslConfiguration::setLocalCertificate(const QSslCertificate &certificate)
{
- d->localCertificate = certificate;
+ d->localCertificateChain = QList<QSslCertificate>();
+ d->localCertificateChain += certificate;
}
/*!
@@ -584,4 +626,10 @@ void QSslConfiguration::setDefaultConfiguration(const QSslConfiguration &configu
QSslConfigurationPrivate::setDefaultConfiguration(configuration);
}
+/*! \internal
+*/
+bool QSslConfigurationPrivate::peerSessionWasShared(const QSslConfiguration &configuration) {
+ return configuration.d->peerSessionShared;
+ }
+
QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h
index ae6e225ce5..0000382ed5 100644
--- a/src/network/ssl/qsslconfiguration.h
+++ b/src/network/ssl/qsslconfiguration.h
@@ -61,8 +61,6 @@
#include <QtNetwork/qsslsocket.h>
#include <QtNetwork/qssl.h>
-QT_BEGIN_HEADER
-
#ifndef QT_NO_SSL
QT_BEGIN_NAMESPACE
@@ -101,6 +99,9 @@ public:
void setPeerVerifyDepth(int depth);
// Certificate & cipher configuration
+ QList<QSslCertificate> localCertificateChain() const;
+ void setLocalCertificateChain(const QList<QSslCertificate> &localChain);
+
QSslCertificate localCertificate() const;
void setLocalCertificate(const QSslCertificate &certificate);
@@ -129,6 +130,8 @@ public:
private:
friend class QSslSocket;
friend class QSslConfigurationPrivate;
+ friend class QSslSocketBackendPrivate;
+ friend class QSslContext;
QSslConfiguration(QSslConfigurationPrivate *dd);
QSharedDataPointer<QSslConfigurationPrivate> d;
};
@@ -141,6 +144,4 @@ Q_DECLARE_METATYPE(QSslConfiguration)
#endif // QT_NO_SSL
-QT_END_HEADER
-
#endif
diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h
index 30f1ed66f9..54b7264d3d 100644
--- a/src/network/ssl/qsslconfiguration_p.h
+++ b/src/network/ssl/qsslconfiguration_p.h
@@ -84,12 +84,14 @@ public:
peerVerifyMode(QSslSocket::AutoVerifyPeer),
peerVerifyDepth(0),
allowRootCertOnDemandLoading(true),
+ peerSessionShared(false),
sslOptions(QSslConfigurationPrivate::defaultSslOptions)
{ }
QSslCertificate peerCertificate;
QList<QSslCertificate> peerCertificateChain;
- QSslCertificate localCertificate;
+
+ QList<QSslCertificate> localCertificateChain;
QSslKey privateKey;
QSslCipher sessionCipher;
@@ -100,6 +102,9 @@ public:
QSslSocket::PeerVerifyMode peerVerifyMode;
int peerVerifyDepth;
bool allowRootCertOnDemandLoading;
+ bool peerSessionShared;
+
+ Q_AUTOTEST_EXPORT static bool peerSessionWasShared(const QSslConfiguration &configuration);
QSsl::SslOptions sslOptions;
diff --git a/src/network/ssl/qsslcontext.cpp b/src/network/ssl/qsslcontext.cpp
new file mode 100644
index 0000000000..22ad42116b
--- /dev/null
+++ b/src/network/ssl/qsslcontext.cpp
@@ -0,0 +1,309 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtNetwork/qsslsocket.h>
+#include <QtCore/qmutex.h>
+
+#include "private/qsslcontext_p.h"
+#include "private/qsslsocket_p.h"
+#include "private/qsslsocket_openssl_p.h"
+#include "private/qsslsocket_openssl_symbols_p.h"
+
+QT_BEGIN_NAMESPACE
+
+// defined in qsslsocket_openssl.cpp:
+extern int q_X509Callback(int ok, X509_STORE_CTX *ctx);
+extern QString getErrorsFromOpenSsl();
+
+QSslContext::QSslContext()
+ : ctx(0),
+ pkey(0),
+ session(0)
+{
+}
+
+QSslContext::~QSslContext()
+{
+ if (ctx)
+ // This will decrement the reference count by 1 and free the context eventually when possible
+ q_SSL_CTX_free(ctx);
+
+ if (pkey)
+ q_EVP_PKEY_free(pkey);
+
+ if (session)
+ q_SSL_SESSION_free(session);
+}
+
+QSslContext* QSslContext::fromConfiguration(QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading)
+{
+ QSslContext *sslContext = new QSslContext();
+ sslContext->sslConfiguration = configuration;
+ sslContext->errorCode = QSslError::NoError;
+
+ bool client = (mode == QSslSocket::SslClientMode);
+
+ bool reinitialized = false;
+init_context:
+ switch (sslContext->sslConfiguration.protocol()) {
+ case QSsl::SslV2:
+#ifndef OPENSSL_NO_SSL2
+ sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method());
+#else
+ sslContext->ctx = 0; // SSL 2 not supported by the system, but chosen deliberately -> error
+#endif
+ break;
+ case QSsl::SslV3:
+ sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_method());
+ break;
+ case QSsl::SecureProtocols: // SslV2 will be disabled below
+ case QSsl::TlsV1SslV3: // SslV2 will be disabled below
+ case QSsl::AnyProtocol:
+ default:
+ sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method());
+ break;
+ case QSsl::TlsV1_0:
+ sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_client_method() : q_TLSv1_server_method());
+ break;
+ case QSsl::TlsV1_1:
+#if OPENSSL_VERSION_NUMBER >= 0x10001000L
+ sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_1_client_method() : q_TLSv1_1_server_method());
+#else
+ sslContext->ctx = 0; // TLS 1.1 not supported by the system, but chosen deliberately -> error
+#endif
+ break;
+ case QSsl::TlsV1_2:
+#if OPENSSL_VERSION_NUMBER >= 0x10001000L
+ sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_2_client_method() : q_TLSv1_2_server_method());
+#else
+ sslContext->ctx = 0; // TLS 1.2 not supported by the system, but chosen deliberately -> error
+#endif
+ break;
+ }
+ if (!sslContext->ctx) {
+ // After stopping Flash 10 the SSL library looses its ciphers. Try re-adding them
+ // by re-initializing the library.
+ if (!reinitialized) {
+ reinitialized = true;
+ if (q_SSL_library_init() == 1)
+ goto init_context;
+ }
+
+ sslContext->errorStr = QSslSocket::tr("Error creating SSL context (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return sslContext;
+ }
+
+ // Enable bug workarounds.
+ long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
+ q_SSL_CTX_set_options(sslContext->ctx, options);
+
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+ // Tell OpenSSL to release memory early
+ // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html
+ if (q_SSLeay() >= 0x10000000L)
+ q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS);
+#endif
+
+ // Initialize ciphers
+ QByteArray cipherString;
+ int first = true;
+ QList<QSslCipher> ciphers = sslContext->sslConfiguration.ciphers();
+ if (ciphers.isEmpty())
+ ciphers = QSslSocketPrivate::defaultCiphers();
+ foreach (const QSslCipher &cipher, ciphers) {
+ if (first)
+ first = false;
+ else
+ cipherString.append(':');
+ cipherString.append(cipher.name().toLatin1());
+ }
+
+ if (!q_SSL_CTX_set_cipher_list(sslContext->ctx, cipherString.data())) {
+ sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return sslContext;
+ }
+
+ // Add all our CAs to this store.
+ QList<QSslCertificate> expiredCerts;
+ foreach (const QSslCertificate &caCertificate, sslContext->sslConfiguration.caCertificates()) {
+ // add expired certs later, so that the
+ // valid ones are used before the expired ones
+ if (caCertificate.expiryDate() < QDateTime::currentDateTime()) {
+ expiredCerts.append(caCertificate);
+ } else {
+ q_X509_STORE_add_cert(sslContext->ctx->cert_store, (X509 *)caCertificate.handle());
+ }
+ }
+
+ // now add the expired certs
+ foreach (const QSslCertificate &caCertificate, expiredCerts) {
+ q_X509_STORE_add_cert(sslContext->ctx->cert_store, reinterpret_cast<X509 *>(caCertificate.handle()));
+ }
+
+ if (QSslSocketPrivate::s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) {
+ // tell OpenSSL the directories where to look up the root certs on demand
+ QList<QByteArray> unixDirs = QSslSocketPrivate::unixRootCertDirectories();
+ for (int a = 0; a < unixDirs.count(); ++a)
+ q_SSL_CTX_load_verify_locations(sslContext->ctx, 0, unixDirs.at(a).constData());
+ }
+
+ // Register a custom callback to get all verification errors.
+ X509_STORE_set_verify_cb_func(sslContext->ctx->cert_store, q_X509Callback);
+
+ if (!sslContext->sslConfiguration.localCertificate().isNull()) {
+ // Require a private key as well.
+ if (sslContext->sslConfiguration.privateKey().isNull()) {
+ sslContext->errorStr = QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return sslContext;
+ }
+
+ // Load certificate
+ if (!q_SSL_CTX_use_certificate(sslContext->ctx, (X509 *)sslContext->sslConfiguration.localCertificate().handle())) {
+ sslContext->errorStr = QSslSocket::tr("Error loading local certificate, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return sslContext;
+ }
+
+ if (configuration.d->privateKey.algorithm() == QSsl::Opaque) {
+ sslContext->pkey = reinterpret_cast<EVP_PKEY *>(configuration.d->privateKey.handle());
+ } else {
+ // Load private key
+ sslContext->pkey = q_EVP_PKEY_new();
+ // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free.
+ // this lead to a memory leak. Now we use the *_set1_* functions which do not
+ // take ownership of the RSA/DSA key instance because the QSslKey already has ownership.
+ if (configuration.d->privateKey.algorithm() == QSsl::Rsa)
+ q_EVP_PKEY_set1_RSA(sslContext->pkey, reinterpret_cast<RSA *>(configuration.d->privateKey.handle()));
+ else
+ q_EVP_PKEY_set1_DSA(sslContext->pkey, reinterpret_cast<DSA *>(configuration.d->privateKey.handle()));
+ }
+
+ if (!q_SSL_CTX_use_PrivateKey(sslContext->ctx, sslContext->pkey)) {
+ sslContext->errorStr = QSslSocket::tr("Error loading private key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return sslContext;
+ }
+ if (configuration.d->privateKey.algorithm() == QSsl::Opaque)
+ sslContext->pkey = 0; // Don't free the private key, it belongs to QSslKey
+
+ // Check if the certificate matches the private key.
+ if (!q_SSL_CTX_check_private_key(sslContext->ctx)) {
+ sslContext->errorStr = QSslSocket::tr("Private key does not certify public key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return sslContext;
+ }
+
+ // If we have any intermediate certificates then we need to add them to our chain
+ bool first = true;
+ foreach (const QSslCertificate &cert, configuration.d->localCertificateChain) {
+ if (first) {
+ first = false;
+ continue;
+ }
+ q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0,
+ q_X509_dup(reinterpret_cast<X509 *>(cert.handle())));
+ }
+ }
+
+ // Initialize peer verification.
+ if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) {
+ q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, 0);
+ } else {
+ q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER, q_X509Callback);
+ }
+
+ // Set verification depth.
+ if (sslContext->sslConfiguration.peerVerifyDepth() != 0)
+ q_SSL_CTX_set_verify_depth(sslContext->ctx, sslContext->sslConfiguration.peerVerifyDepth());
+
+ return sslContext;
+}
+
+// Needs to be deleted by caller
+SSL* QSslContext::createSsl()
+{
+ SSL* ssl = q_SSL_new(ctx);
+ q_SSL_clear(ssl);
+
+ if (session) {
+ // Try to resume the last session we cached
+ if (!q_SSL_set_session(ssl, session)) {
+ qWarning("could not set SSL session");
+ q_SSL_SESSION_free(session);
+ session = 0;
+ }
+ }
+ return ssl;
+}
+
+// We cache exactly one session here
+bool QSslContext::cacheSession(SSL* ssl)
+{
+ // dont cache the same session again
+ if (session && session == q_SSL_get_session(ssl))
+ return true;
+
+ // decrease refcount of currently stored session
+ // (this might happen if there are several concurrent handshakes in flight)
+ if (session)
+ q_SSL_SESSION_free(session);
+
+ // cache the session the caller gave us and increase reference count
+ session = q_SSL_get1_session(ssl);
+ return (session != NULL);
+
+}
+
+QSslError::SslError QSslContext::error() const
+{
+ return errorCode;
+}
+
+QString QSslContext::errorString() const
+{
+ return errorStr;
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslcontext_p.h b/src/network/ssl/qsslcontext_p.h
new file mode 100644
index 0000000000..c8578d349e
--- /dev/null
+++ b/src/network/ssl/qsslcontext_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QSSLCONTEXT_H
+#define QSSLCONTEXT_H
+
+#include <QtCore/qvariant.h>
+#include <QtNetwork/qsslcertificate.h>
+#include <QtNetwork/qsslconfiguration.h>
+#include <openssl/ssl.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_SSL
+
+class QSslContextPrivate;
+
+class QSslContext
+{
+public:
+
+ ~QSslContext();
+
+ static QSslContext* fromConfiguration(QSslSocket::SslMode mode, const QSslConfiguration &configuration,
+ bool allowRootCertOnDemandLoading);
+
+ QSslError::SslError error() const;
+ QString errorString() const;
+
+ SSL* createSsl();
+ bool cacheSession(SSL*); // should be called when handshake completed
+
+protected:
+ QSslContext();
+
+private:
+ SSL_CTX* ctx;
+ EVP_PKEY *pkey;
+ SSL_SESSION *session;
+ QSslError::SslError errorCode;
+ QString errorStr;
+ QSslConfiguration sslConfiguration;
+};
+
+#endif // QT_NO_SSL
+
+QT_END_NAMESPACE
+
+#endif // QSSLCONTEXT_H
diff --git a/src/network/ssl/qsslerror.cpp b/src/network/ssl/qsslerror.cpp
index d151b376d5..bf75d2e610 100644
--- a/src/network/ssl/qsslerror.cpp
+++ b/src/network/ssl/qsslerror.cpp
@@ -61,7 +61,7 @@
\enum QSslError::SslError
Describes all recognized errors that can occur during an SSL handshake.
-
+
\value NoError
\value UnableToGetIssuerCertificate
\value UnableToDecryptCertificateSignature
@@ -108,7 +108,7 @@ public:
};
/*!
- Constructs a QSslError object with no error and default certificate.
+ Constructs a QSslError object with no error and default certificate.
*/
diff --git a/src/network/ssl/qsslerror.h b/src/network/ssl/qsslerror.h
index 847a48cbc1..73549ce648 100644
--- a/src/network/ssl/qsslerror.h
+++ b/src/network/ssl/qsslerror.h
@@ -46,8 +46,6 @@
#include <QtCore/qvariant.h>
#include <QtNetwork/qsslcertificate.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -106,7 +104,7 @@ public:
SslError error() const;
QString errorString() const;
QSslCertificate certificate() const;
-
+
private:
QScopedPointer<QSslErrorPrivate> d;
};
@@ -126,6 +124,4 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QList<QSslError>)
#endif
-QT_END_HEADER
-
#endif
diff --git a/src/network/ssl/qsslkey.h b/src/network/ssl/qsslkey.h
index 986b1c41de..145d4a28f1 100644
--- a/src/network/ssl/qsslkey.h
+++ b/src/network/ssl/qsslkey.h
@@ -48,8 +48,6 @@
#include <QtCore/qsharedpointer.h>
#include <QtNetwork/qssl.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -110,6 +108,4 @@ Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslKey &key);
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index f0c3f40a28..a8bf8f83b8 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -267,7 +267,7 @@
/*!
\fn void QSslSocket::sslErrors(const QList<QSslError> &errors);
-
+
QSslSocket emits this signal after the SSL handshake to indicate that one
or more errors have occurred while establishing the identity of the
peer. The errors are usually an indication that QSslSocket is unable to
@@ -281,7 +281,7 @@
\a errors contains one or more errors that prevent QSslSocket from
verifying the identity of the peer.
-
+
Note: You cannot use Qt::QueuedConnection when connecting to this signal,
or calling QSslSocket::ignoreSslErrors() will have no effect.
@@ -436,7 +436,7 @@ void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port, O
\overload
In addition to the original behaviour of connectToHostEncrypted,
- this overloaded method enables the usage of a different hostname
+ this overloaded method enables the usage of a different hostname
(\a sslPeerName) for the certificate validation instead of
the one used for the TCP connection (\a hostName).
@@ -827,7 +827,7 @@ bool QSslSocket::flush()
/*!
\since 4.4
- Sets the size of QSslSocket's internal read buffer to be \a size bytes.
+ Sets the size of QSslSocket's internal read buffer to be \a size bytes.
*/
void QSslSocket::setReadBufferSize(qint64 size)
{
@@ -895,7 +895,7 @@ QSslConfiguration QSslSocket::sslConfiguration() const
void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration)
{
Q_D(QSslSocket);
- d->configuration.localCertificate = configuration.localCertificate();
+ d->configuration.localCertificateChain = configuration.localCertificateChain();
d->configuration.privateKey = configuration.privateKey();
d->configuration.ciphers = configuration.ciphers();
d->configuration.caCertificates = configuration.caCertificates();
@@ -912,6 +912,32 @@ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration)
}
/*!
+ Sets the certificate chain to be presented to the peer during the
+ SSL handshake to be \a localChain.
+
+ \sa QSslConfiguration::setLocalCertificateChain()
+ \since 5.1
+ */
+void QSslSocket::setLocalCertificateChain(const QList<QSslCertificate> &localChain)
+{
+ Q_D(QSslSocket);
+ d->configuration.localCertificateChain = localChain;
+}
+
+/*!
+ Returns the socket's local \l {QSslCertificate} {certificate} chain,
+ or an empty list if no local certificates have been assigned.
+
+ \sa setLocalCertificateChain()
+ \since 5.1
+*/
+QList<QSslCertificate> QSslSocket::localCertificateChain() const
+{
+ Q_D(const QSslSocket);
+ return d->configuration.localCertificateChain;
+}
+
+/*!
Sets the socket's local certificate to \a certificate. The local
certificate is necessary if you need to confirm your identity to the
peer. It is used together with the private key; if you set the local
@@ -926,23 +952,24 @@ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration)
void QSslSocket::setLocalCertificate(const QSslCertificate &certificate)
{
Q_D(QSslSocket);
- d->configuration.localCertificate = certificate;
+ d->configuration.localCertificateChain = QList<QSslCertificate>();
+ d->configuration.localCertificateChain += certificate;
}
/*!
\overload
Sets the socket's local \l {QSslCertificate} {certificate} to the
- first one found in file \a path, which is parsed according to the
+ first one found in file \a path, which is parsed according to the
specified \a format.
*/
void QSslSocket::setLocalCertificate(const QString &path,
QSsl::EncodingFormat format)
{
- Q_D(QSslSocket);
QFile file(path);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
- d->configuration.localCertificate = QSslCertificate(file.readAll(), format);
+ setLocalCertificate(QSslCertificate(file.readAll(), format));
+
}
/*!
@@ -954,14 +981,16 @@ void QSslSocket::setLocalCertificate(const QString &path,
QSslCertificate QSslSocket::localCertificate() const
{
Q_D(const QSslSocket);
- return d->configuration.localCertificate;
+ if (d->configuration.localCertificateChain.isEmpty())
+ return QSslCertificate();
+ return d->configuration.localCertificateChain[0];
}
/*!
Returns the peer's digital certificate (i.e., the immediate
certificate of the host you are connected to), or a null
certificate, if the peer has not assigned a certificate.
-
+
The peer certificate is checked automatically during the
handshake phase, so this function is normally used to fetch
the certificate for display or for connection diagnostic
@@ -1073,7 +1102,7 @@ void QSslSocket::setPrivateKey(const QSslKey &key)
creating an SSL server socket. If you are creating an SSL client
socket, the key and local certificate are required if your client
must identify itself to an SSL server.
-
+
\sa privateKey(), setLocalCertificate()
*/
void QSslSocket::setPrivateKey(const QString &fileName, QSsl::KeyAlgorithm algorithm,
@@ -1681,7 +1710,7 @@ void QSslSocket::startClientEncryption()
subclass of QTcpServer and reimplement
QTcpServer::incomingConnection(). The returned socket descriptor
is then passed to QSslSocket::setSocketDescriptor().
-
+
\sa connectToHostEncrypted(), startClientEncryption()
*/
void QSslSocket::startServerEncryption()
@@ -2057,7 +2086,7 @@ void QSslConfigurationPrivate::deepCopyDefaultConfiguration(QSslConfigurationPri
ptr->ref.store(1);
ptr->peerCertificate = global->peerCertificate;
ptr->peerCertificateChain = global->peerCertificateChain;
- ptr->localCertificate = global->localCertificate;
+ ptr->localCertificateChain = global->localCertificateChain;
ptr->privateKey = global->privateKey;
ptr->sessionCipher = global->sessionCipher;
ptr->ciphers = global->ciphers;
@@ -2410,6 +2439,23 @@ QList<QByteArray> QSslSocketPrivate::unixRootCertDirectories()
<< "/opt/openssl/certs/"; // HP-UX
}
+/*!
+ \internal
+*/
+void QSslSocketPrivate::checkSettingSslContext(QSslSocket* socket, QSharedPointer<QSslContext> sslContext)
+{
+ if (socket->d_func()->sslContextPointer.isNull())
+ socket->d_func()->sslContextPointer = sslContext;
+}
+
+/*!
+ \internal
+*/
+QSharedPointer<QSslContext> QSslSocketPrivate::sslContext(QSslSocket *socket)
+{
+ return (socket) ? socket->d_func()->sslContextPointer : QSharedPointer<QSslContext>();
+}
+
QT_END_NAMESPACE
#include "moc_qsslsocket.cpp"
diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h
index 929e437554..d89933efda 100644
--- a/src/network/ssl/qsslsocket.h
+++ b/src/network/ssl/qsslsocket.h
@@ -50,8 +50,6 @@
# include <QtNetwork/qsslerror.h>
#endif
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -133,6 +131,9 @@ public:
void setSslConfiguration(const QSslConfiguration &config);
// Certificate & cipher accessors.
+ void setLocalCertificateChain(const QList<QSslCertificate> &localChain);
+ QList<QSslCertificate> localCertificateChain() const;
+
void setLocalCertificate(const QSslCertificate &certificate);
void setLocalCertificate(const QString &fileName, QSsl::EncodingFormat format = QSsl::Pem);
QSslCertificate localCertificate() const;
@@ -223,6 +224,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index f846bf2d8b..e8f8b294c9 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -156,6 +156,19 @@ private:
};
Q_GLOBAL_STATIC(QOpenSslLocks, openssl_locks)
+QString QSslSocketBackendPrivate::getErrorsFromOpenSsl()
+{
+ QString errorString;
+ unsigned long errNum;
+ while ((errNum = q_ERR_get_error())) {
+ if (! errorString.isEmpty())
+ errorString.append(QLatin1String(", "));
+ const char *error = q_ERR_error_string(errNum, NULL);
+ errorString.append(QString::fromLatin1(error)); // error is ascii according to man ERR_error_string
+ }
+ return errorString;
+}
+
extern "C" {
static void locking_function(int mode, int lockNumber, const char *, int)
{
@@ -175,8 +188,6 @@ static unsigned long id_function()
QSslSocketBackendPrivate::QSslSocketBackendPrivate()
: ssl(0),
- ctx(0),
- pkey(0),
readBio(0),
writeBio(0),
session(0)
@@ -240,7 +251,8 @@ struct QSslErrorList
QList<QPair<int, int> > errors;
};
Q_GLOBAL_STATIC(QSslErrorList, _q_sslErrorList)
-static int q_X509Callback(int ok, X509_STORE_CTX *ctx)
+
+int q_X509Callback(int ok, X509_STORE_CTX *ctx)
{
if (!ok) {
// Store the error and at which depth the error was detected.
@@ -311,191 +323,21 @@ bool QSslSocketBackendPrivate::initSslContext()
{
Q_Q(QSslSocket);
- // Create and initialize SSL context. Accept SSLv2, SSLv3 and TLSv1_0.
- bool client = (mode == QSslSocket::SslClientMode);
+ // If no external context was set (e.g. bei QHttpNetworkConnection) we will create a default context
+ if (!sslContextPointer)
+ sslContextPointer = QSharedPointer<QSslContext>(
+ QSslContext::fromConfiguration(mode, QSslConfiguration(&configuration), allowRootCertOnDemandLoading));
- bool reinitialized = false;
-
-init_context:
- switch (configuration.protocol) {
- case QSsl::SslV2:
-#ifndef OPENSSL_NO_SSL2
- ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method());
-#else
- ctx = 0; // SSL 2 not supported by the system, but chosen deliberately -> error
-#endif
- break;
- case QSsl::SslV3:
- ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_method());
- break;
- case QSsl::SecureProtocols: // SslV2 will be disabled below
- case QSsl::TlsV1SslV3: // SslV2 will be disabled below
- case QSsl::AnyProtocol:
- default:
- ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method());
- break;
- case QSsl::TlsV1_0:
- ctx = q_SSL_CTX_new(client ? q_TLSv1_client_method() : q_TLSv1_server_method());
- break;
- case QSsl::TlsV1_1:
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
- ctx = q_SSL_CTX_new(client ? q_TLSv1_1_client_method() : q_TLSv1_1_server_method());
-#else
- ctx = 0; // TLS 1.1 not supported by the system, but chosen deliberately -> error
-#endif
- break;
- case QSsl::TlsV1_2:
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
- ctx = q_SSL_CTX_new(client ? q_TLSv1_2_client_method() : q_TLSv1_2_server_method());
-#else
- ctx = 0; // TLS 1.2 not supported by the system, but chosen deliberately -> error
-#endif
- break;
- }
- if (!ctx) {
- // After stopping Flash 10 the SSL library looses its ciphers. Try re-adding them
- // by re-initializing the library.
- if (!reinitialized) {
- reinitialized = true;
- if (q_SSL_library_init() == 1)
- goto init_context;
- }
-
- q->setErrorString(QSslSocket::tr("Error creating SSL context (%1)").arg(getErrorsFromOpenSsl()));
- q->setSocketError(QAbstractSocket::SslInternalError);
- emit q->error(QAbstractSocket::SslInternalError);
- return false;
- }
-
- // Enable bug workarounds.
- long options = setupOpenSslOptions(configuration.protocol, configuration.sslOptions);
- q_SSL_CTX_set_options(ctx, options);
-
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
- // Tell OpenSSL to release memory early
- // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html
- if (q_SSLeay() >= 0x10000000L)
- q_SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);
-#endif
-
- // Initialize ciphers
- QByteArray cipherString;
- int first = true;
- QList<QSslCipher> ciphers = configuration.ciphers;
- if (ciphers.isEmpty())
- ciphers = defaultCiphers();
- foreach (const QSslCipher &cipher, ciphers) {
- if (first)
- first = false;
- else
- cipherString.append(':');
- cipherString.append(cipher.name().toLatin1());
- }
-
- if (!q_SSL_CTX_set_cipher_list(ctx, cipherString.data())) {
- q->setErrorString(QSslSocket::tr("Invalid or empty cipher list (%1)").arg(getErrorsFromOpenSsl()));
+ if (sslContextPointer->error() != QSslError::NoError) {
+ q->setErrorString(sslContextPointer->errorString());
q->setSocketError(QAbstractSocket::SslInvalidUserDataError);
emit q->error(QAbstractSocket::SslInvalidUserDataError);
+ sslContextPointer.clear(); // deletes the QSslContext
return false;
}
- // Add all our CAs to this store.
- QList<QSslCertificate> expiredCerts;
- foreach (const QSslCertificate &caCertificate, q->caCertificates()) {
- // add expired certs later, so that the
- // valid ones are used before the expired ones
- if (caCertificate.expiryDate() < QDateTime::currentDateTime()) {
- expiredCerts.append(caCertificate);
- } else {
- q_X509_STORE_add_cert(ctx->cert_store, reinterpret_cast<X509 *>(caCertificate.handle()));
- }
- }
-
- bool addExpiredCerts = true;
-#if defined(Q_OS_MAC) && (MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5)
- //On Leopard SSL does not work if we add the expired certificates.
- if (QSysInfo::MacintoshVersion == QSysInfo::MV_10_5)
- addExpiredCerts = false;
-#endif
- // now add the expired certs
- if (addExpiredCerts) {
- foreach (const QSslCertificate &caCertificate, expiredCerts) {
- q_X509_STORE_add_cert(ctx->cert_store, reinterpret_cast<X509 *>(caCertificate.handle()));
- }
- }
-
- if (s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) {
- // tell OpenSSL the directories where to look up the root certs on demand
- QList<QByteArray> unixDirs = unixRootCertDirectories();
- for (int a = 0; a < unixDirs.count(); ++a)
- q_SSL_CTX_load_verify_locations(ctx, 0, unixDirs.at(a).constData());
- }
-
- // Register a custom callback to get all verification errors.
- X509_STORE_set_verify_cb_func(ctx->cert_store, q_X509Callback);
-
- if (!configuration.localCertificate.isNull()) {
- // Require a private key as well.
- if (configuration.privateKey.isNull()) {
- q->setErrorString(QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(getErrorsFromOpenSsl()));
- q->setSocketError(QAbstractSocket::SslInvalidUserDataError);
- emit q->error(QAbstractSocket::SslInvalidUserDataError);
- return false;
- }
-
- // Load certificate
- if (!q_SSL_CTX_use_certificate(ctx, reinterpret_cast<X509 *>(configuration.localCertificate.handle()))) {
- q->setErrorString(QSslSocket::tr("Error loading local certificate, %1").arg(getErrorsFromOpenSsl()));
- q->setSocketError(QAbstractSocket::SslInternalError);
- emit q->error(QAbstractSocket::SslInternalError);
- return false;
- }
-
- if (configuration.privateKey.algorithm() == QSsl::Opaque) {
- pkey = reinterpret_cast<EVP_PKEY *>(configuration.privateKey.handle());
- } else {
- // Load private key
- pkey = q_EVP_PKEY_new();
- // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free.
- // this lead to a memory leak. Now we use the *_set1_* functions which do not
- // take ownership of the RSA/DSA key instance because the QSslKey already has ownership.
- if (configuration.privateKey.algorithm() == QSsl::Rsa)
- q_EVP_PKEY_set1_RSA(pkey, reinterpret_cast<RSA *>(configuration.privateKey.handle()));
- else
- q_EVP_PKEY_set1_DSA(pkey, reinterpret_cast<DSA *>(configuration.privateKey.handle()));
- }
-
- if (!q_SSL_CTX_use_PrivateKey(ctx, pkey)) {
- q->setErrorString(QSslSocket::tr("Error loading private key, %1").arg(getErrorsFromOpenSsl()));
- q->setSocketError(QAbstractSocket::SslInternalError);
- emit q->error(QAbstractSocket::SslInternalError);
- return false;
- }
- if (configuration.privateKey.algorithm() == QSsl::Opaque)
- pkey = 0; // Don't free the private key, it belongs to QSslKey
-
- // Check if the certificate matches the private key.
- if (!q_SSL_CTX_check_private_key(ctx)) {
- q->setErrorString(QSslSocket::tr("Private key does not certify public key, %1").arg(getErrorsFromOpenSsl()));
- q->setSocketError(QAbstractSocket::SslInvalidUserDataError);
- emit q->error(QAbstractSocket::SslInvalidUserDataError);
- return false;
- }
- }
-
- // Initialize peer verification.
- if (configuration.peerVerifyMode == QSslSocket::VerifyNone) {
- q_SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
- } else {
- q_SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, q_X509Callback);
- }
-
- // Set verification depth.
- if (configuration.peerVerifyDepth != 0)
- q_SSL_CTX_set_verify_depth(ctx, configuration.peerVerifyDepth);
-
// Create and initialize SSL session
- if (!(ssl = q_SSL_new(ctx))) {
+ if (!(ssl = sslContextPointer->createSsl())) {
// ### Bad error code
q->setErrorString(QSslSocket::tr("Error creating SSL session, %1").arg(getErrorsFromOpenSsl()));
q->setSocketError(QAbstractSocket::SslInternalError);
@@ -510,7 +352,7 @@ init_context:
configuration.protocol == QSsl::TlsV1_2 ||
configuration.protocol == QSsl::SecureProtocols ||
configuration.protocol == QSsl::AnyProtocol) &&
- client && q_SSLeay() >= 0x00090806fL) {
+ mode == QSslSocket::SslClientMode && q_SSLeay() >= 0x00090806fL) {
// Set server hostname on TLS extension. RFC4366 section 3.1 requires it in ACE format.
QString tlsHostName = verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName;
if (tlsHostName.isEmpty())
@@ -527,7 +369,6 @@ init_context:
#endif
// Clear the session.
- q_SSL_clear(ssl);
errorList.clear();
// Initialize memory BIOs for encryption and decryption.
@@ -557,14 +398,7 @@ void QSslSocketBackendPrivate::destroySslContext()
q_SSL_free(ssl);
ssl = 0;
}
- if (ctx) {
- q_SSL_CTX_free(ctx);
- ctx = 0;
- }
- if (pkey) {
- q_EVP_PKEY_free(pkey);
- pkey = 0;
- }
+ sslContextPointer.clear();
}
/*!
@@ -847,10 +681,19 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
}
#elif defined(Q_OS_UNIX)
QSet<QString> certFiles;
+# ifdef Q_OS_ANDROID
+ QList<QByteArray> directories;
+ directories << qgetenv("MINISTRO_SSL_CERTS_PATH"); // Set by Ministro
+# else
QList<QByteArray> directories = unixRootCertDirectories();
+# endif
QDir currentDir;
QStringList nameFilters;
+# ifdef Q_OS_ANDROID
+ nameFilters << QLatin1String("*.der");
+#else
nameFilters << QLatin1String("*.pem") << QLatin1String("*.crt");
+# endif
currentDir.setNameFilters(nameFilters);
for (int a = 0; a < directories.count(); a++) {
currentDir.setPath(QLatin1String(directories.at(a)));
@@ -863,10 +706,16 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
}
QSetIterator<QString> it(certFiles);
while(it.hasNext()) {
- systemCerts.append(QSslCertificate::fromPath(it.next()));
+# ifdef Q_OS_ANDROID
+ systemCerts.append(QSslCertificate::fromPath(it.next(), QSsl::Der));
+# else
+ systemCerts.append(QSslCertificate::fromPath(it.next(), QSsl::Pem));
+# endif
}
+# ifndef Q_OS_ANDROID
systemCerts.append(QSslCertificate::fromPath(QLatin1String("/etc/pki/tls/certs/ca-bundle.crt"), QSsl::Pem)); // Fedora, Mandriva
systemCerts.append(QSslCertificate::fromPath(QLatin1String("/usr/local/share/certs/ca-root-nss.crt"), QSsl::Pem)); // FreeBSD's ca_root_nss
+# endif
#endif
#ifdef QSSLSOCKET_DEBUG
qDebug() << "systemCaCertificates retrieval time " << timer.elapsed() << "ms";
@@ -1102,7 +951,7 @@ void QSslSocketBackendPrivate::transmit()
break;
}
} while (ssl && readBytes > 0);
- } while (ssl && ctx && transmitting);
+ } while (ssl && transmitting);
}
static QSslError _q_OpenSSL_to_QSslError(int errorCode, const QSslCertificate &cert)
@@ -1308,7 +1157,6 @@ bool QSslSocketBackendPrivate::startHandshake()
}
}
#endif
-
if (!checkSslErrors())
return false;
} else {
@@ -1532,7 +1380,7 @@ void QSslSocketBackendPrivate::disconnected()
QSslCipher QSslSocketBackendPrivate::sessionCipher() const
{
- if (!ssl || !ctx)
+ if (!ssl)
return QSslCipher();
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
// FIXME This is fairly evil, but needed to keep source level compatibility
@@ -1552,6 +1400,15 @@ void QSslSocketBackendPrivate::continueHandshake()
if (readBufferMaxSize)
plainSocket->setReadBufferSize(readBufferMaxSize);
+ if (q_SSL_ctrl((ssl), SSL_CTRL_GET_SESSION_REUSED, 0, NULL))
+ configuration.peerSessionShared = true;
+
+ // Cache this SSL session inside the QSslContext
+ if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionTickets)) {
+ if (!sslContextPointer->cacheSession(ssl))
+ sslContextPointer.clear(); // we could not cache the session
+ }
+
connectionEncrypted = true;
emit q->encrypted();
if (autoStartHandshake && pendingClose) {
@@ -1571,19 +1428,6 @@ QList<QSslCertificate> QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates
return certificates;
}
-QString QSslSocketBackendPrivate::getErrorsFromOpenSsl()
-{
- QString errorString;
- unsigned long errNum;
- while((errNum = q_ERR_get_error())) {
- if (! errorString.isEmpty())
- errorString.append(QLatin1String(", "));
- const char *error = q_ERR_error_string(errNum, NULL);
- errorString.append(QString::fromLatin1(error)); // error is ascii according to man ERR_error_string
- }
- return errorString;
-}
-
bool QSslSocketBackendPrivate::isMatchingHostname(const QSslCertificate &cert, const QString &peerName)
{
QStringList commonNameList = cert.subjectInfo(QSslCertificate::CommonName);
@@ -1675,17 +1519,9 @@ QList<QSslError> QSslSocketBackendPrivate::verify(QList<QSslCertificate> certifi
}
}
- bool addExpiredCerts = true;
-#if defined(Q_OS_MAC) && (MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5)
- //On Leopard SSL does not work if we add the expired certificates.
- if (QSysInfo::MacintoshVersion == QSysInfo::MV_10_5)
- addExpiredCerts = false;
-#endif
// now add the expired certs
- if (addExpiredCerts) {
- foreach (const QSslCertificate &caCertificate, expiredCerts) {
- q_X509_STORE_add_cert(certStore, reinterpret_cast<X509 *>(caCertificate.handle()));
- }
+ foreach (const QSslCertificate &caCertificate, expiredCerts) {
+ q_X509_STORE_add_cert(certStore, reinterpret_cast<X509 *>(caCertificate.handle()));
}
QMutexLocker sslErrorListMutexLocker(&_q_sslErrorList()->mutex);
diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h
index d6675197b4..c8b23e6cad 100644
--- a/src/network/ssl/qsslsocket_openssl_p.h
+++ b/src/network/ssl/qsslsocket_openssl_p.h
@@ -75,7 +75,10 @@
#if defined(OCSP_RESPONSE)
#undef OCSP_RESPONSE
#endif
+#if defined(X509_NAME)
+#undef X509_NAME
#endif
+#endif // Q_OS_WIN
#include <openssl/asn1.h>
#include <openssl/bio.h>
@@ -115,8 +118,6 @@ public:
bool initSslContext();
void destroySslContext();
SSL *ssl;
- SSL_CTX *ctx;
- EVP_PKEY *pkey;
BIO *readBio;
BIO *writeBio;
SSL_SESSION *session;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 9f271f863a..fed99752b0 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -67,7 +67,7 @@
#if defined(Q_OS_UNIX)
#include <QtCore/qdir.h>
#endif
-#ifdef Q_OS_LINUX
+#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID_NO_SDK)
#include <link.h>
#endif
@@ -245,6 +245,10 @@ DEFINEFUNC3(void, SSL_set_bio, SSL *a, a, BIO *b, b, BIO *c, c, return, DUMMYARG
DEFINEFUNC(void, SSL_set_accept_state, SSL *a, a, return, DUMMYARG)
DEFINEFUNC(void, SSL_set_connect_state, SSL *a, a, return, DUMMYARG)
DEFINEFUNC(int, SSL_shutdown, SSL *a, a, return -1, return)
+DEFINEFUNC2(int, SSL_set_session, SSL* to, to, SSL_SESSION *session, session, return -1, return)
+DEFINEFUNC(void, SSL_SESSION_free, SSL_SESSION *ses, ses, return, DUMMYARG)
+DEFINEFUNC(SSL_SESSION*, SSL_get1_session, SSL *ssl, ssl, return 0, return)
+DEFINEFUNC(SSL_SESSION*, SSL_get_session, const SSL *ssl, ssl, return 0, return)
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
#ifndef OPENSSL_NO_SSL2
DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return)
@@ -379,7 +383,7 @@ static bool libGreaterThan(const QString &lhs, const QString &rhs)
return true;
}
-#ifdef Q_OS_LINUX
+#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID_NO_SDK)
static int dlIterateCallback(struct dl_phdr_info *info, size_t size, void *data)
{
if (size < sizeof (info->dlpi_addr) + sizeof (info->dlpi_name))
@@ -410,7 +414,9 @@ static QStringList libraryPathList()
paths << QLatin1String("/lib64") << QLatin1String("/usr/lib64") << QLatin1String("/usr/local/lib64");
paths << QLatin1String("/lib32") << QLatin1String("/usr/lib32") << QLatin1String("/usr/local/lib32");
-#ifdef Q_OS_LINUX
+#if defined(Q_OS_ANDROID_NO_SDK)
+ paths << QLatin1String("/system/lib");
+#elif defined(Q_OS_LINUX)
// discover paths of already loaded libraries
QSet<QString> loadedPaths;
dl_iterate_phdr(dlIterateCallback, &loadedPaths);
@@ -457,28 +463,46 @@ static QStringList findAllLibCrypto()
# endif
#ifdef Q_OS_WIN
-static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32()
+static bool tryToLoadOpenSslWin32Library(QLatin1String ssleay32LibName, QLatin1String libeay32LibName, QPair<QSystemLibrary*, QSystemLibrary*> &pair)
{
- QPair<QSystemLibrary*,QSystemLibrary*> pair;
pair.first = 0;
pair.second = 0;
- QSystemLibrary *ssleay32 = new QSystemLibrary(QLatin1String("ssleay32"));
+ QSystemLibrary *ssleay32 = new QSystemLibrary(ssleay32LibName);
if (!ssleay32->load(false)) {
- // Cannot find ssleay32.dll
delete ssleay32;
- return pair;
+ return FALSE;
}
- QSystemLibrary *libeay32 = new QSystemLibrary(QLatin1String("libeay32"));
+ QSystemLibrary *libeay32 = new QSystemLibrary(libeay32LibName);
if (!libeay32->load(false)) {
delete ssleay32;
delete libeay32;
- return pair;
+ return FALSE;
}
pair.first = ssleay32;
pair.second = libeay32;
+ return TRUE;
+}
+
+static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32()
+{
+ QPair<QSystemLibrary*,QSystemLibrary*> pair;
+ pair.first = 0;
+ pair.second = 0;
+
+ // When OpenSSL is built using MSVC then the libraries are named 'ssleay32.dll' and 'libeay32'dll'.
+ // When OpenSSL is built using GCC then different library names are used (depending on the OpenSSL version)
+ // The oldest version of a GCC-based OpenSSL which can be detected by the code below is 0.9.8g (released in 2007)
+ if (!tryToLoadOpenSslWin32Library(QLatin1String("ssleay32"), QLatin1String("libeay32"), pair)) {
+ if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-10"), QLatin1String("libcrypto-10"), pair)) {
+ if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-8"), QLatin1String("libcrypto-8"), pair)) {
+ tryToLoadOpenSslWin32Library(QLatin1String("libssl-7"), QLatin1String("libcrypto-7"), pair);
+ }
+ }
+ }
+
return pair;
}
#else
@@ -699,6 +723,10 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_set_bio)
RESOLVEFUNC(SSL_set_connect_state)
RESOLVEFUNC(SSL_shutdown)
+ RESOLVEFUNC(SSL_set_session)
+ RESOLVEFUNC(SSL_SESSION_free)
+ RESOLVEFUNC(SSL_get1_session)
+ RESOLVEFUNC(SSL_get_session)
RESOLVEFUNC(SSL_write)
#ifndef OPENSSL_NO_SSL2
RESOLVEFUNC(SSLv2_client_method)
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index ccd9d3cfb9..62648e3e37 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -347,6 +347,10 @@ void q_SSL_set_bio(SSL *a, BIO *b, BIO *c);
void q_SSL_set_accept_state(SSL *a);
void q_SSL_set_connect_state(SSL *a);
int q_SSL_shutdown(SSL *a);
+int q_SSL_set_session(SSL *to, SSL_SESSION *session);
+void q_SSL_SESSION_free(SSL_SESSION *ses);
+SSL_SESSION *q_SSL_get1_session(SSL *ssl);
+SSL_SESSION *q_SSL_get_session(const SSL *ssl);
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
const SSL_METHOD *q_SSLv2_client_method();
const SSL_METHOD *q_SSLv3_client_method();
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index 851dec5840..72117353ac 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -59,6 +59,7 @@
#include <private/qtcpsocket_p.h>
#include "qsslkey.h"
#include "qsslconfiguration_p.h"
+#include <private/qsslcontext_p.h>
#include <QtCore/qstringlist.h>
@@ -114,6 +115,7 @@ public:
QSslConfigurationPrivate configuration;
QList<QSslError> sslErrors;
+ QSharedPointer<QSslContext> sslContextPointer;
// if set, this hostname is used for certificate validation instead of the hostname
// that was used for connecting to.
@@ -121,6 +123,8 @@ public:
bool allowRootCertOnDemandLoading;
+ static bool s_loadRootCertsOnDemand;
+
static bool supportsSsl();
static long sslLibraryVersionNumber();
static QString sslLibraryVersionString();
@@ -155,6 +159,9 @@ public:
void createPlainSocket(QIODevice::OpenMode openMode);
static void pauseSocketNotifiers(QSslSocket*);
static void resumeSocketNotifiers(QSslSocket*);
+ // ### The 2 methods below should be made member methods once the QSslContext class is made public
+ static void checkSettingSslContext(QSslSocket*, QSharedPointer<QSslContext>);
+ static QSharedPointer<QSslContext> sslContext(QSslSocket *socket);
bool isPaused() const;
void _q_connectedSlot();
void _q_hostFoundSlot();
@@ -170,6 +177,8 @@ public:
virtual void _q_caRootLoaded(QSslCertificate,QSslCertificate) = 0;
#endif
+ static QList<QByteArray> unixRootCertDirectories(); // used also by QSslContext
+
virtual qint64 peek(char *data, qint64 maxSize);
virtual QByteArray peek(qint64 maxSize);
@@ -192,8 +201,6 @@ private:
static bool s_loadedCiphersAndCerts;
protected:
bool verifyErrorsHaveBeenIgnored();
- static bool s_loadRootCertsOnDemand;
- static QList<QByteArray> unixRootCertDirectories();
bool paused;
};
diff --git a/src/network/ssl/ssl.pri b/src/network/ssl/ssl.pri
index 8ebb4b29af..f5afb43759 100644
--- a/src/network/ssl/ssl.pri
+++ b/src/network/ssl/ssl.pri
@@ -14,7 +14,8 @@ contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) {
ssl/qsslsocket_openssl_symbols_p.h \
ssl/qsslsocket_p.h \
ssl/qsslcertificateextension.h \
- ssl/qsslcertificateextension_p.h
+ ssl/qsslcertificateextension_p.h \
+ ssl/qsslcontext_p.h
SOURCES += ssl/qssl.cpp \
ssl/qsslcertificate.cpp \
ssl/qsslconfiguration.cpp \
@@ -24,7 +25,8 @@ contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) {
ssl/qsslsocket.cpp \
ssl/qsslsocket_openssl.cpp \
ssl/qsslsocket_openssl_symbols.cpp \
- ssl/qsslcertificateextension.cpp
+ ssl/qsslcertificateextension.cpp \
+ ssl/qsslcontext.cpp
# Add optional SSL libs
# Static linking of OpenSSL with msvc: