summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/access/qhttp.cpp2
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp157
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h36
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp36
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel_p.h7
-rw-r--r--src/network/access/qhttpnetworkreply.cpp5
-rw-r--r--src/network/access/qhttpnetworkreply_p.h8
-rw-r--r--src/network/access/qnetworkaccessbackend.cpp2
-rw-r--r--src/network/access/qnetworkaccesshttpbackend.cpp52
-rw-r--r--src/network/access/qnetworkaccesshttpbackend_p.h1
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp28
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h6
-rw-r--r--src/network/access/qnetworkrequest.cpp10
-rw-r--r--src/network/kernel/qauthenticator.cpp14
-rw-r--r--src/network/kernel/qauthenticator_p.h1
-rw-r--r--src/network/socket/qabstractsocket.cpp30
-rw-r--r--src/network/socket/qabstractsocket_p.h7
-rw-r--r--src/network/socket/qlocalserver_unix.cpp2
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp2
-rw-r--r--src/network/ssl/qsslsocket.cpp14
-rw-r--r--src/network/ssl/qsslsocket_p.h2
-rw-r--r--src/plugins/bearer/connman/qconnmanengine.cpp83
-rw-r--r--src/plugins/bearer/connman/qconnmanengine.h27
-rw-r--r--src/plugins/bearer/connman/qconnmanservice_linux.cpp21
-rw-r--r--src/plugins/bearer/connman/qofonoservice_linux.cpp12
-rw-r--r--src/script/api/qscriptvalue.cpp13
-rw-r--r--tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp54
-rw-r--r--tests/auto/qscriptvalue/tst_qscriptvalue.cpp25
-rw-r--r--tests/auto/qscriptvalue/tst_qscriptvalue.h1
29 files changed, 297 insertions, 361 deletions
diff --git a/src/network/access/qhttp.cpp b/src/network/access/qhttp.cpp
index 13375f8..9c2f79a 100644
--- a/src/network/access/qhttp.cpp
+++ b/src/network/access/qhttp.cpp
@@ -2442,7 +2442,7 @@ void QHttpPrivate::_q_slotSendRequest()
if (proxy.hostName().isEmpty()) {
proxy.setType(QNetworkProxy::NoProxy);
} else if (sslInUse) {
- // Disallow use of cacheing proxy with HTTPS; instead fall back to
+ // Disallow use of caching proxy with HTTPS; instead fall back to
// transparent HTTP CONNECT proxying.
transparentProxyInUse = true;
} else {
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index ccdbb20..89f9b03 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include <private/qabstractsocket_p.h>
#include "qhttpnetworkconnection_p.h"
#include "qhttpnetworkconnectionchannel_p.h"
#include "private/qnoncontiguousbytedevice_p.h"
@@ -56,6 +57,7 @@
#ifndef QT_NO_HTTP
#ifndef QT_NO_OPENSSL
+# include <private/qsslsocket_p.h>
# include <QtNetwork/qsslkey.h>
# include <QtNetwork/qsslcipher.h>
# include <QtNetwork/qsslconfiguration.h>
@@ -79,9 +81,9 @@ const int QHttpNetworkConnectionPrivate::defaultRePipelineLength = 2;
QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt)
-: hostName(hostName), port(port), encrypt(encrypt),
- channelCount(defaultChannelCount),
- pendingAuthSignal(false), pendingProxyAuthSignal(false)
+: state(RunningState),
+ hostName(hostName), port(port), encrypt(encrypt),
+ channelCount(defaultChannelCount)
#ifndef QT_NO_NETWORKPROXY
, networkProxy(QNetworkProxy::NoProxy)
#endif
@@ -90,9 +92,9 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host
}
QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt)
-: hostName(hostName), port(port), encrypt(encrypt),
- channelCount(channelCount),
- pendingAuthSignal(false), pendingProxyAuthSignal(false)
+: state(RunningState),
+ hostName(hostName), port(port), encrypt(encrypt),
+ channelCount(channelCount)
#ifndef QT_NO_NETWORKPROXY
, networkProxy(QNetworkProxy::NoProxy)
#endif
@@ -121,6 +123,42 @@ void QHttpNetworkConnectionPrivate::init()
}
}
+void QHttpNetworkConnectionPrivate::pauseConnection()
+{
+ state = PausedState;
+
+ // Disable all socket notifiers
+ for (int i = 0; i < channelCount; i++) {
+#ifndef QT_NO_OPENSSL
+ if (encrypt)
+ QSslSocketPrivate::pauseSocketNotifiers(static_cast<QSslSocket*>(channels[i].socket));
+ else
+#endif
+ QAbstractSocketPrivate::pauseSocketNotifiers(channels[i].socket);
+ }
+}
+
+void QHttpNetworkConnectionPrivate::resumeConnection()
+{
+ state = RunningState;
+ // Enable all socket notifiers
+ for (int i = 0; i < channelCount; i++) {
+#ifndef QT_NO_OPENSSL
+ if (encrypt)
+ QSslSocketPrivate::resumeSocketNotifiers(static_cast<QSslSocket*>(channels[i].socket));
+ else
+#endif
+ QAbstractSocketPrivate::resumeSocketNotifiers(channels[i].socket);
+
+ // Resume pending upload if needed
+ if (channels[i].state == QHttpNetworkConnectionChannel::WritingState)
+ QMetaObject::invokeMethod(&channels[i], "_q_uploadDataReadyRead", Qt::QueuedConnection);
+ }
+
+ // queue _q_startNextRequest
+ QMetaObject::invokeMethod(this->q_func(), "_q_startNextRequest", Qt::QueuedConnection);
+}
+
int QHttpNetworkConnectionPrivate::indexOf(QAbstractSocket *socket) const
{
for (int i = 0; i < channelCount; ++i)
@@ -257,6 +295,13 @@ void QHttpNetworkConnectionPrivate::copyCredentials(int fromChannel, QAuthentica
{
Q_ASSERT(auth);
+ // NTLM is a multi phase authentication. Copying credentials between authenticators would mess things up.
+ if (!isProxy && channels[fromChannel].authMethod == QAuthenticatorPrivate::Ntlm)
+ return;
+ if (isProxy && channels[fromChannel].proxyAuthMethod == QAuthenticatorPrivate::Ntlm)
+ return;
+
+
// select another channel
QAuthenticator* otherAuth = 0;
for (int i = 0; i < channelCount; ++i) {
@@ -296,10 +341,10 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket
QAuthenticator* auth = 0;
if (isProxy) {
auth = &channels[i].proxyAuthenticator;
- channels[i].proxyAuthMehtod = authMethod;
+ channels[i].proxyAuthMethod = authMethod;
} else {
auth = &channels[i].authenticator;
- channels[i].authMehtod = authMethod;
+ channels[i].authMethod = authMethod;
}
//proceed with the authentication.
if (auth->isNull())
@@ -308,43 +353,23 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket
priv->parseHttpResponse(fields, isProxy);
if (priv->phase == QAuthenticatorPrivate::Done) {
- if ((isProxy && pendingProxyAuthSignal) ||(!isProxy && pendingAuthSignal)) {
- // drop the request
- reply->d_func()->eraseData();
- channels[i].close();
- channels[i].lastStatus = 0;
- channels[i].state = QHttpNetworkConnectionChannel::Wait4AuthState;
- return false;
- }
- // cannot use this socket until the slot returns
- channels[i].state = QHttpNetworkConnectionChannel::WaitingState;
- socket->blockSignals(true);
+ pauseConnection();
if (!isProxy) {
- pendingAuthSignal = true;
- emit q->authenticationRequired(reply->request(), auth, q);
- pendingAuthSignal = false;
+ emit reply->authenticationRequired(reply->request(), auth);
#ifndef QT_NO_NETWORKPROXY
} else {
- pendingProxyAuthSignal = true;
- emit q->proxyAuthenticationRequired(networkProxy, auth, q);
- pendingProxyAuthSignal = false;
+ emit reply->proxyAuthenticationRequired(networkProxy, auth);
#endif
}
- socket->blockSignals(false);
- // socket free to use
- channels[i].state = QHttpNetworkConnectionChannel::IdleState;
+ resumeConnection();
+
if (priv->phase != QAuthenticatorPrivate::Done) {
// send any pending requests
copyCredentials(i, auth, isProxy);
- QMetaObject::invokeMethod(q, "_q_restartAuthPendingRequests", Qt::QueuedConnection);
}
- } else if (priv->phase == QAuthenticatorPrivate::Start) {
- // If the url's authenticator has a 'user' set we will end up here (phase is only set to 'Done' by
- // parseHttpResponse above if 'user' is empty). So if credentials were supplied with the request,
- // such as in the case of an XMLHttpRequest, this is our only opportunity to cache them.
- emit q->cacheCredentials(reply->request(), auth, q);
}
- // - Changing values in QAuthenticator will reset the 'phase'.
+ // - Changing values in QAuthenticator will reset the 'phase'. Therefore if it is still "Done"
+ // then nothing was filled in by the user or the cache
// - If withCredentials has been set to false (e.g. by QtWebKit for a cross-origin XMLHttpRequest) then
// we need to bail out if authentication is required.
if (priv->phase == QAuthenticatorPrivate::Done || !reply->request().withCredentials()) {
@@ -356,15 +381,9 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket
? QNetworkReply::ProxyAuthenticationRequiredError
: QNetworkReply::AuthenticationRequiredError;
reply->d_func()->errorString = errorDetail(errorCode, socket);
- emit q->error(errorCode, reply->d_func()->errorString);
- emit channels[i].reply->finished();
+ emit reply->finishedWithError(errorCode, reply->d_func()->errorString);
// ### at this point the reply could be deleted
socket->close();
- // remove pending request on the other channels
- for (int j = 0; j < channelCount; ++j) {
- if (j != i && channels[j].state == QHttpNetworkConnectionChannel::Wait4AuthState)
- channels[j].state = QHttpNetworkConnectionChannel::IdleState;
- }
return true;
}
//resend the request
@@ -380,8 +399,9 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket,
int i = indexOf(socket);
- if (channels[i].authMehtod != QAuthenticatorPrivate::None) {
- if (!(channels[i].authMehtod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 401)) {
+ // Send "Authorization" header, but not if it's NTLM and the socket is already authenticated.
+ if (channels[i].authMethod != QAuthenticatorPrivate::None) {
+ if (!(channels[i].authMethod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 401)) {
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].authenticator);
if (priv && priv->method != QAuthenticatorPrivate::None) {
QByteArray response = priv->calculateResponse(request.d->methodName(), request.d->uri(false));
@@ -389,8 +409,10 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket,
}
}
}
- if (channels[i].proxyAuthMehtod != QAuthenticatorPrivate::None) {
- if (!(channels[i].proxyAuthMehtod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 407)) {
+
+ // Send "Proxy-Authorization" header, but not if it's NTLM and the socket is already authenticated.
+ if (channels[i].proxyAuthMethod != QAuthenticatorPrivate::None) {
+ if (!(channels[i].proxyAuthMethod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 407)) {
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].proxyAuthenticator);
if (priv && priv->method != QAuthenticatorPrivate::None) {
QByteArray response = priv->calculateResponse(request.d->methodName(), request.d->uri(false));
@@ -723,6 +745,10 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply)
// although it is called _q_startNextRequest, it will actually start multiple requests when possible
void QHttpNetworkConnectionPrivate::_q_startNextRequest()
{
+ // If the QHttpNetworkConnection is currently paused then bail out immediately
+ if (state == PausedState)
+ return;
+
//resend the necessary ones.
for (int i = 0; i < channelCount; ++i) {
if (channels[i].resendCurrent) {
@@ -773,17 +799,6 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
fillPipeline(channels[i].socket);
}
-void QHttpNetworkConnectionPrivate::_q_restartAuthPendingRequests()
-{
- // send the request using the idle socket
- for (int i = 0 ; i < channelCount; ++i) {
- if (channels[i].state == QHttpNetworkConnectionChannel::Wait4AuthState) {
- channels[i].state = QHttpNetworkConnectionChannel::IdleState;
- if (channels[i].reply)
- channels[i].sendRequest();
- }
- }
-}
void QHttpNetworkConnectionPrivate::readMoreLater(QHttpNetworkReply *reply)
{
@@ -832,33 +847,12 @@ QHttpNetworkReply* QHttpNetworkConnection::sendRequest(const QHttpNetworkRequest
return d->queueRequest(request);
}
-void QHttpNetworkConnection::enableEncryption()
-{
- Q_D(QHttpNetworkConnection);
- d->encrypt = true;
-}
-
bool QHttpNetworkConnection::isEncrypted() const
{
Q_D(const QHttpNetworkConnection);
return d->encrypt;
}
-void QHttpNetworkConnection::setProxyAuthentication(QAuthenticator *authenticator)
-{
- Q_D(QHttpNetworkConnection);
- for (int i = 0; i < d->channelCount; ++i)
- d->channels[i].proxyAuthenticator = *authenticator;
-}
-
-void QHttpNetworkConnection::setAuthentication(const QString &domain, QAuthenticator *authenticator)
-{
- Q_UNUSED(domain); // ### domain ?
- Q_D(QHttpNetworkConnection);
- for (int i = 0; i < d->channelCount; ++i)
- d->channels[i].authenticator = *authenticator;
-}
-
#ifndef QT_NO_NETWORKPROXY
void QHttpNetworkConnection::setCacheProxy(const QNetworkProxy &networkProxy)
{
@@ -951,8 +945,11 @@ void QHttpNetworkConnection::ignoreSslErrors(const QList<QSslError> &errors, int
// e.g. it is for SOCKS proxies which require authentication.
void QHttpNetworkConnectionPrivate::emitProxyAuthenticationRequired(const QHttpNetworkConnectionChannel *chan, const QNetworkProxy &proxy, QAuthenticator* auth)
{
- Q_Q(QHttpNetworkConnection);
- emit q->proxyAuthenticationRequired(proxy, auth, q);
+ // Also pause the connection because socket notifiers may fire while an user
+ // dialog is displaying
+ pauseConnection();
+ emit chan->reply->proxyAuthenticationRequired(proxy, auth);
+ resumeConnection();
int i = indexOf(chan->socket);
copyCredentials(i, auth, true);
}
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index 51666d6..8461426c 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -108,43 +108,22 @@ public:
QNetworkProxy transparentProxy() const;
#endif
- //enable encryption
- void enableEncryption();
bool isEncrypted() const;
- //authentication parameters
- void setProxyAuthentication(QAuthenticator *authenticator);
- void setAuthentication(const QString &domain, QAuthenticator *authenticator);
-
#ifndef QT_NO_OPENSSL
void setSslConfiguration(const QSslConfiguration &config);
void ignoreSslErrors(int channel = -1);
void ignoreSslErrors(const QList<QSslError> &errors, int channel = -1);
-
-Q_SIGNALS:
- void sslErrors(const QList<QSslError> &errors);
-#endif
-
-Q_SIGNALS:
-#ifndef QT_NO_NETWORKPROXY
- //cannot be used with queued connection.
- void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator,
- const QHttpNetworkConnection *connection = 0);
#endif
- void authenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *authenticator,
- const QHttpNetworkConnection *connection = 0);
- void cacheCredentials(const QHttpNetworkRequest &request, QAuthenticator *authenticator,
- const QHttpNetworkConnection *connection = 0);
- void error(QNetworkReply::NetworkError errorCode, const QString &detail = QString());
private:
Q_DECLARE_PRIVATE(QHttpNetworkConnection)
Q_DISABLE_COPY(QHttpNetworkConnection)
friend class QHttpNetworkReply;
+ friend class QHttpNetworkReplyPrivate;
friend class QHttpNetworkConnectionChannel;
Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest())
- Q_PRIVATE_SLOT(d_func(), void _q_restartAuthPendingRequests())
};
@@ -160,11 +139,20 @@ public:
static const int defaultPipelineLength;
static const int defaultRePipelineLength;
+ enum ConnectionState {
+ RunningState = 0,
+ PausedState = 1,
+ };
+
QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt);
QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt);
~QHttpNetworkConnectionPrivate();
void init();
+ void pauseConnection();
+ void resumeConnection();
+ ConnectionState state;
+
enum { ChunkSize = 4096 };
int indexOf(QAbstractSocket *socket) const;
@@ -184,7 +172,6 @@ public:
// private slots
void _q_startNextRequest(); // send the next request from the queue
- void _q_restartAuthPendingRequests(); // send the currently blocked request
void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request);
@@ -203,9 +190,6 @@ public:
const int channelCount;
QHttpNetworkConnectionChannel *channels; // parallel connections to the server
- bool pendingAuthSignal; // there is an incomplete authentication signal
- bool pendingProxyAuthSignal; // there is an incomplete proxy authentication signal
-
qint64 uncompressedBytesAvailable(const QHttpNetworkReply &reply) const;
qint64 uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const;
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index d10f951..4e5de53 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -68,8 +68,8 @@ QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel()
, lastStatus(0)
, pendingEncrypt(false)
, reconnectAttempts(2)
- , authMehtod(QAuthenticatorPrivate::None)
- , proxyAuthMehtod(QAuthenticatorPrivate::None)
+ , authMethod(QAuthenticatorPrivate::None)
+ , proxyAuthMethod(QAuthenticatorPrivate::None)
#ifndef QT_NO_OPENSSL
, ignoreAllSslErrors(false)
#endif
@@ -190,6 +190,7 @@ bool QHttpNetworkConnectionChannel::sendRequest()
|| (!url.password().isEmpty() && url.password() != auth.password())) {
auth.setUser(url.userName());
auth.setPassword(url.password());
+ emit reply->cacheCredentials(request, &auth);
connection->d_func()->copyCredentials(connection->d_func()->indexOf(socket), &auth, false);
}
// clear the userinfo, since we use the same request for resending
@@ -309,7 +310,6 @@ bool QHttpNetworkConnectionChannel::sendRequest()
break;
}
case QHttpNetworkConnectionChannel::ReadingState:
- case QHttpNetworkConnectionChannel::Wait4AuthState:
// ignore _q_bytesWritten in these states
// fall through
default:
@@ -797,8 +797,7 @@ void QHttpNetworkConnectionChannel::handleStatus()
? QNetworkReply::ProxyAuthenticationRequiredError
: QNetworkReply::AuthenticationRequiredError;
reply->d_func()->errorString = connection->d_func()->errorDetail(errorCode, socket);
- emit connection->error(errorCode, reply->d_func()->errorString);
- emit reply->finished();
+ emit reply->finishedWithError(errorCode, reply->d_func()->errorString);
}
break;
default:
@@ -945,7 +944,6 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
{
if (!socket)
return;
- bool send2Reply = false;
QNetworkReply::NetworkError errorCode = QNetworkReply::UnknownNetworkError;
switch (socketError) {
@@ -963,7 +961,6 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
closeAndResendCurrentRequest();
return;
} else {
- send2Reply = true;
errorCode = QNetworkReply::RemoteHostClosedError;
}
} else {
@@ -976,7 +973,6 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
closeAndResendCurrentRequest();
return;
}
- send2Reply = true;
errorCode = QNetworkReply::TimeoutError;
break;
case QAbstractSocket::ProxyAuthenticationRequiredError:
@@ -992,18 +988,14 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
}
QPointer<QHttpNetworkConnection> that = connection;
QString errorString = connection->d_func()->errorDetail(errorCode, socket, socket->errorString());
- if (send2Reply) {
- if (reply) {
- reply->d_func()->errorString = errorString;
- // this error matters only to this reply
- emit reply->finishedWithError(errorCode, errorString);
- }
- // send the next request
- QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection);
- } else {
- // the failure affects all requests.
- emit connection->error(errorCode, errorString);
+
+ if (reply) {
+ reply->d_func()->errorString = errorString;
+ emit reply->finishedWithError(errorCode, errorString);
}
+ // send the next request
+ QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection);
+
if (that) //signal emission triggered event loop
close();
}
@@ -1034,7 +1026,11 @@ void QHttpNetworkConnectionChannel::_q_sslErrors(const QList<QSslError> &errors)
if (!socket)
return;
//QNetworkReply::NetworkError errorCode = QNetworkReply::ProtocolFailure;
- emit connection->sslErrors(errors);
+ // Also pause the connection because socket notifiers may fire while an user
+ // dialog is displaying
+ connection->d_func()->pauseConnection();
+ emit reply->sslErrors(errors);
+ connection->d_func()->resumeConnection();
}
void QHttpNetworkConnectionChannel::_q_encryptedBytesWritten(qint64 bytes)
diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
index 41a896d..442086a 100644
--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
+++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
@@ -95,8 +95,7 @@ public:
WritingState = 2, // writing the data
WaitingState = 4, // waiting for reply
ReadingState = 8, // reading the reply
- Wait4AuthState = 0x10, // blocked for send till the current authentication slot is done
- BusyState = (ConnectingState|WritingState|WaitingState|ReadingState|Wait4AuthState)
+ BusyState = (ConnectingState|WritingState|WaitingState|ReadingState)
};
QAbstractSocket *socket;
ChannelState state;
@@ -108,8 +107,8 @@ public:
int lastStatus; // last status received on this channel
bool pendingEncrypt; // for https (send after encrypted)
int reconnectAttempts; // maximum 2 reconnection attempts
- QAuthenticatorPrivate::Method authMehtod;
- QAuthenticatorPrivate::Method proxyAuthMehtod;
+ QAuthenticatorPrivate::Method authMethod;
+ QAuthenticatorPrivate::Method proxyAuthMethod;
QAuthenticator authenticator;
QAuthenticator proxyAuthenticator;
#ifndef QT_NO_OPENSSL
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index 108ba8a..e4eb7c4 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -205,6 +205,11 @@ bool QHttpNetworkReply::isPipeliningUsed() const
return d_func()->pipeliningUsed;
}
+QHttpNetworkConnection* QHttpNetworkReply::connection()
+{
+ return d_func()->connection;
+}
+
QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl)
: QHttpNetworkHeaderPrivate(newUrl), state(NothingDoneState), statusCode(100),
diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h
index 4011c78..3f79d81 100644
--- a/src/network/access/qhttpnetworkreply_p.h
+++ b/src/network/access/qhttpnetworkreply_p.h
@@ -132,6 +132,8 @@ public:
bool isPipeliningUsed() const;
+ QHttpNetworkConnection* connection();
+
#ifndef QT_NO_OPENSSL
QSslConfiguration sslConfiguration() const;
void setSslConfiguration(const QSslConfiguration &config);
@@ -149,7 +151,11 @@ Q_SIGNALS:
void headerChanged();
void dataReadProgress(int done, int total);
void dataSendProgress(qint64 done, qint64 total);
-
+ void cacheCredentials(const QHttpNetworkRequest &request, QAuthenticator *authenticator);
+#ifndef QT_NO_NETWORKPROXY
+ void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
+#endif
+ void authenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *authenticator);
private:
Q_DECLARE_PRIVATE(QHttpNetworkReply)
friend class QHttpNetworkConnection;
diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp
index 60f7dc6..0a0987a 100644
--- a/src/network/access/qnetworkaccessbackend.cpp
+++ b/src/network/access/qnetworkaccessbackend.cpp
@@ -329,7 +329,7 @@ void QNetworkAccessBackend::authenticationRequired(QAuthenticator *authenticator
void QNetworkAccessBackend::cacheCredentials(QAuthenticator *authenticator)
{
- manager->addCredentials(this->reply->url, authenticator);
+ manager->cacheCredentials(this->reply->url, authenticator);
}
void QNetworkAccessBackend::metaDataChanged()
diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp
index f617244..2a0daf8 100644
--- a/src/network/access/qnetworkaccesshttpbackend.cpp
+++ b/src/network/access/qnetworkaccesshttpbackend.cpp
@@ -338,24 +338,6 @@ void QNetworkAccessHttpBackend::finished()
QNetworkAccessBackend::finished();
}
-void QNetworkAccessHttpBackend::setupConnection()
-{
-#ifndef QT_NO_NETWORKPROXY
- connect(http, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
- SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
-#endif
- connect(http, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
- SLOT(httpAuthenticationRequired(QHttpNetworkRequest,QAuthenticator*)));
- connect(http, SIGNAL(cacheCredentials(QHttpNetworkRequest,QAuthenticator*)),
- SLOT(httpCacheCredentials(QHttpNetworkRequest,QAuthenticator*)));
- connect(http, SIGNAL(error(QNetworkReply::NetworkError,QString)),
- SLOT(httpError(QNetworkReply::NetworkError,QString)));
-#ifndef QT_NO_OPENSSL
- connect(http, SIGNAL(sslErrors(QList<QSslError>)),
- SLOT(sslErrors(QList<QSslError>)));
-#endif
-}
-
/*
For a given httpRequest
1) If AlwaysNetwork, return
@@ -593,6 +575,8 @@ void QNetworkAccessHttpBackend::postRequest()
if (pendingIgnoreAllSslErrors)
httpReply->ignoreSslErrors();
httpReply->ignoreSslErrors(pendingIgnoreSslErrorsList);
+ connect(httpReply, SIGNAL(sslErrors(QList<QSslError>)),
+ SLOT(sslErrors(QList<QSslError>)));
#endif
connect(httpReply, SIGNAL(readyRead()), SLOT(replyReadyRead()));
@@ -600,6 +584,14 @@ void QNetworkAccessHttpBackend::postRequest()
connect(httpReply, SIGNAL(finishedWithError(QNetworkReply::NetworkError,QString)),
SLOT(httpError(QNetworkReply::NetworkError,QString)));
connect(httpReply, SIGNAL(headerChanged()), SLOT(replyHeaderChanged()));
+ connect(httpReply, SIGNAL(cacheCredentials(QHttpNetworkRequest,QAuthenticator*)),
+ SLOT(httpCacheCredentials(QHttpNetworkRequest,QAuthenticator*)));
+#ifndef QT_NO_NETWORKPROXY
+ connect(httpReply, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
+ SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
+#endif
+ connect(httpReply, SIGNAL(authenticationRequired(const QHttpNetworkRequest,QAuthenticator*)),
+ SLOT(httpAuthenticationRequired(const QHttpNetworkRequest,QAuthenticator*)));
}
void QNetworkAccessHttpBackend::invalidateCache()
@@ -674,7 +666,6 @@ void QNetworkAccessHttpBackend::open()
cache->addEntry(cacheKey, http);
}
- setupConnection();
postRequest();
}
@@ -880,29 +871,6 @@ void QNetworkAccessHttpBackend::httpError(QNetworkReply::NetworkError errorCode,
#if defined(QNETWORKACCESSHTTPBACKEND_DEBUG)
qDebug() << "http error!" << errorCode << errorString;
#endif
-#if 0
- static const QNetworkReply::NetworkError conversionTable[] = {
- QNetworkReply::ConnectionRefusedError,
- QNetworkReply::RemoteHostClosedError,
- QNetworkReply::HostNotFoundError,
- QNetworkReply::UnknownNetworkError, // SocketAccessError
- QNetworkReply::UnknownNetworkError, // SocketResourceError
- QNetworkReply::TimeoutError, // SocketTimeoutError
- QNetworkReply::UnknownNetworkError, // DatagramTooLargeError
- QNetworkReply::UnknownNetworkError, // NetworkError
- QNetworkReply::UnknownNetworkError, // AddressInUseError
- QNetworkReply::UnknownNetworkError, // SocketAddressNotAvailableError
- QNetworkReply::UnknownNetworkError, // UnsupportedSocketOperationError
- QNetworkReply::UnknownNetworkError, // UnfinishedSocketOperationError
- QNetworkReply::ProxyAuthenticationRequiredError
- };
- QNetworkReply::NetworkError code;
- if (int(errorCode) >= 0 &&
- uint(errorCode) < (sizeof conversionTable / sizeof conversionTable[0]))
- code = conversionTable[errorCode];
- else
- code = QNetworkReply::UnknownNetworkError;
-#endif
error(errorCode, errorString);
finished();
}
diff --git a/src/network/access/qnetworkaccesshttpbackend_p.h b/src/network/access/qnetworkaccesshttpbackend_p.h
index c4c88ae..568b2ee 100644
--- a/src/network/access/qnetworkaccesshttpbackend_p.h
+++ b/src/network/access/qnetworkaccesshttpbackend_p.h
@@ -125,7 +125,6 @@ private:
quint64 resumeOffset;
void disconnectFromHttp();
- void setupConnection();
void validateCache(QHttpNetworkRequest &httpRequest, bool &loadedFromCache);
void invalidateCache();
void postRequest();
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 12fe094..e5f4d5a 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -1025,16 +1025,8 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
priv->manager = this;
// second step: fetch cached credentials
- if (static_cast<QNetworkRequest::LoadControl>
- (request.attribute(QNetworkRequest::AuthenticationReuseAttribute,
- QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Automatic) {
- QNetworkAuthenticationCredential *cred = d->fetchCachedCredentials(url);
- if (cred) {
- url.setUserName(cred->user);
- url.setPassword(cred->password);
- priv->urlForLastAuthentication = url;
- }
- }
+ // This is not done for the time being, we should use signal emissions to request
+ // the credentials from cache.
// third step: find a backend
priv->backend = d->findBackend(op, request);
@@ -1116,7 +1108,9 @@ void QNetworkAccessManagerPrivate::authenticationRequired(QNetworkAccessBackend
// don't try the cache for the same URL twice in a row
// being called twice for the same URL means the authentication failed
- if (url != backend->reply->urlForLastAuthentication) {
+ // also called when last URL is empty, e.g. on first call
+ if (backend->reply->urlForLastAuthentication.isEmpty()
+ || url != backend->reply->urlForLastAuthentication) {
QNetworkAuthenticationCredential *cred = fetchCachedCredentials(url, authenticator);
if (cred) {
authenticator->setUser(cred->user);
@@ -1128,7 +1122,7 @@ void QNetworkAccessManagerPrivate::authenticationRequired(QNetworkAccessBackend
backend->reply->urlForLastAuthentication = url;
emit q->authenticationRequired(backend->reply->q_func(), authenticator);
- addCredentials(url, authenticator);
+ cacheCredentials(url, authenticator);
}
#ifndef QT_NO_NETWORKPROXY
@@ -1145,7 +1139,7 @@ void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(QNetworkAccessBac
// possible solution: some tracking inside the authenticator
// or a new function proxyAuthenticationSucceeded(true|false)
if (proxy != backend->reply->lastProxyAuthentication) {
- QNetworkAuthenticationCredential *cred = fetchCachedCredentials(proxy);
+ QNetworkAuthenticationCredential *cred = fetchCachedProxyCredentials(proxy);
if (cred) {
authenticator->setUser(cred->user);
authenticator->setPassword(cred->password);
@@ -1155,10 +1149,10 @@ void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(QNetworkAccessBac
backend->reply->lastProxyAuthentication = proxy;
emit q->proxyAuthenticationRequired(proxy, authenticator);
- addCredentials(proxy, authenticator);
+ cacheProxyCredentials(proxy, authenticator);
}
-void QNetworkAccessManagerPrivate::addCredentials(const QNetworkProxy &p,
+void QNetworkAccessManagerPrivate::cacheProxyCredentials(const QNetworkProxy &p,
const QAuthenticator *authenticator)
{
Q_ASSERT(authenticator);
@@ -1195,7 +1189,7 @@ void QNetworkAccessManagerPrivate::addCredentials(const QNetworkProxy &p,
}
QNetworkAuthenticationCredential *
-QNetworkAccessManagerPrivate::fetchCachedCredentials(const QNetworkProxy &p,
+QNetworkAccessManagerPrivate::fetchCachedProxyCredentials(const QNetworkProxy &p,
const QAuthenticator *authenticator)
{
QNetworkProxy proxy = p;
@@ -1247,7 +1241,7 @@ QList<QNetworkProxy> QNetworkAccessManagerPrivate::queryProxy(const QNetworkProx
}
#endif
-void QNetworkAccessManagerPrivate::addCredentials(const QUrl &url,
+void QNetworkAccessManagerPrivate::cacheCredentials(const QUrl &url,
const QAuthenticator *authenticator)
{
Q_ASSERT(authenticator);
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index 695842c..2c6ee10 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -91,15 +91,15 @@ public:
void createCookieJar() const;
void authenticationRequired(QNetworkAccessBackend *backend, QAuthenticator *authenticator);
- void addCredentials(const QUrl &url, const QAuthenticator *auth);
+ void cacheCredentials(const QUrl &url, const QAuthenticator *auth);
QNetworkAuthenticationCredential *fetchCachedCredentials(const QUrl &url,
const QAuthenticator *auth = 0);
#ifndef QT_NO_NETWORKPROXY
void proxyAuthenticationRequired(QNetworkAccessBackend *backend, const QNetworkProxy &proxy,
QAuthenticator *authenticator);
- void addCredentials(const QNetworkProxy &proxy, const QAuthenticator *auth);
- QNetworkAuthenticationCredential *fetchCachedCredentials(const QNetworkProxy &proxy,
+ void cacheProxyCredentials(const QNetworkProxy &proxy, const QAuthenticator *auth);
+ QNetworkAuthenticationCredential *fetchCachedProxyCredentials(const QNetworkProxy &proxy,
const QAuthenticator *auth = 0);
QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query);
#endif
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index d3084cf..b761af5 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -194,16 +194,12 @@ QT_BEGIN_NAMESPACE
\value CookieLoadControlAttribute
Requests only, type: QVariant::Int (default: QNetworkRequest::Automatic)
Indicates whether to send 'Cookie' headers in the request.
-
This attribute is set to false by QtWebKit when creating a cross-origin
XMLHttpRequest where withCredentials has not been set explicitly to true by the
Javascript that created the request.
-
See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag}{here} for more information.
-
(This value was introduced in 4.7.)
-
\value CookieSaveControlAttribute
Requests only, type: QVariant::Int (default: QNetworkRequest::Automatic)
Indicates whether to save 'Cookie' headers received from the server in reply
@@ -211,9 +207,7 @@ QT_BEGIN_NAMESPACE
This attribute is set to false by QtWebKit when creating a cross-origin
XMLHttpRequest where withCredentials has not been set explicitly to true by the
Javascript that created the request.
-
See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag} {here} for more information.
-
(This value was introduced in 4.7.)
\value AuthenticationReuseAttribute
@@ -225,16 +219,12 @@ QT_BEGIN_NAMESPACE
This attribute is set to QNetworkRequest::Manual by QtWebKit when creating a cross-origin
XMLHttpRequest where withCredentials has not been set explicitly to true by the
Javascript that created the request.
-
See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag} {here} for more information.
-
(This value was introduced in 4.7.)
\omitvalue MaximumDownloadBufferSizeAttribute
- (This value was introduced in 4.7.)
\omitvalue DownloadBufferAttribute
- (This value was introduced in 4.7.)
\value User
Special type. Additional information can be passed in
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index f97d833..220f7da 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -232,19 +232,21 @@ void QAuthenticator::setUser(const QString &user)
//domain name is present
d->realm.clear();
d->userDomain = user.left(separatorPosn);
- d->user = user.mid(separatorPosn + 1);
+ d->extractedUser = user.mid(separatorPosn + 1);
+ d->user = user;
} else if((separatorPosn = user.indexOf(QLatin1String("@"))) != -1) {
//domain name is present
d->realm.clear();
d->userDomain = user.left(separatorPosn);
- d->user = user.left(separatorPosn);
+ d->extractedUser = user.left(separatorPosn);
+ d->user = user;
} else {
+ d->extractedUser = user;
d->user = user;
d->realm.clear();
d->userDomain.clear();
}
break;
- // For other auth mechanisms, domain name will be part of username
default:
d->user = user;
break;
@@ -1196,7 +1198,7 @@ static QByteArray qCreatev2Hash(const QAuthenticatorPrivate *ctx,
Q_ASSERT(hashKey.size() == 16);
// Assuming the user and domain is always unicode in challenge
QByteArray message =
- qStringAsUcs2Le(ctx->user.toUpper()) +
+ qStringAsUcs2Le(ctx->extractedUser.toUpper()) +
qStringAsUcs2Le(phase3->domainStr);
phase3->v2Hash = qEncodeHmacMd5(hashKey, message);
@@ -1401,8 +1403,8 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas
pb.domainStr = ctx->userDomain;
}
- offset = qEncodeNtlmString(pb.user, offset, ctx->user, unicode);
- pb.userStr = ctx->user;
+ offset = qEncodeNtlmString(pb.user, offset, ctx->extractedUser, unicode);
+ pb.userStr = ctx->extractedUser;
offset = qEncodeNtlmString(pb.workstation, offset, ctx->workstation, unicode);
pb.workstationStr = ctx->workstation;
diff --git a/src/network/kernel/qauthenticator_p.h b/src/network/kernel/qauthenticator_p.h
index 4e09360..9f2e607 100644
--- a/src/network/kernel/qauthenticator_p.h
+++ b/src/network/kernel/qauthenticator_p.h
@@ -71,6 +71,7 @@ public:
QAtomicInt ref;
QString user;
+ QString extractedUser;
QString password;
QVariantHash options;
Method method;
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 505db71..f03d102 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -1212,6 +1212,36 @@ void QAbstractSocketPrivate::fetchConnectionParameters()
#endif
}
+
+void QAbstractSocketPrivate::pauseSocketNotifiers(QAbstractSocket *socket)
+{
+ QAbstractSocketEngine *socketEngine = socket->d_func()->socketEngine;
+ if (!socketEngine)
+ return;
+ socket->d_func()->prePauseReadSocketNotifierState = socketEngine->isReadNotificationEnabled();
+ socket->d_func()->prePauseWriteSocketNotifierState = socketEngine->isWriteNotificationEnabled();
+ socket->d_func()->prePauseExceptionSocketNotifierState = socketEngine->isExceptionNotificationEnabled();
+ socketEngine->setReadNotificationEnabled(false);
+ socketEngine->setWriteNotificationEnabled(false);
+ socketEngine->setExceptionNotificationEnabled(false);
+}
+
+void QAbstractSocketPrivate::resumeSocketNotifiers(QAbstractSocket *socket)
+{
+ QAbstractSocketEngine *socketEngine = socket->d_func()->socketEngine;
+ if (!socketEngine)
+ return;
+ socketEngine->setReadNotificationEnabled(socket->d_func()->prePauseReadSocketNotifierState);
+ socketEngine->setWriteNotificationEnabled(socket->d_func()->prePauseWriteSocketNotifierState);
+ socketEngine->setExceptionNotificationEnabled(socket->d_func()->prePauseExceptionSocketNotifierState);
+}
+
+QAbstractSocketEngine* QAbstractSocketPrivate::getSocketEngine(QAbstractSocket *socket)
+{
+ return socket->d_func()->socketEngine;
+}
+
+
/*! \internal
Constructs a new abstract socket of type \a socketType. The \a
diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h
index b51c301..7fba0fe 100644
--- a/src/network/socket/qabstractsocket_p.h
+++ b/src/network/socket/qabstractsocket_p.h
@@ -158,6 +158,13 @@ public:
QAbstractSocket::SocketState state;
QAbstractSocket::SocketError socketError;
+
+ bool prePauseReadSocketNotifierState;
+ bool prePauseWriteSocketNotifierState;
+ bool prePauseExceptionSocketNotifierState;
+ static void pauseSocketNotifiers(QAbstractSocket*);
+ static void resumeSocketNotifiers(QAbstractSocket*);
+ static QAbstractSocketEngine* getSocketEngine(QAbstractSocket*);
};
QT_END_NAMESPACE
diff --git a/src/network/socket/qlocalserver_unix.cpp b/src/network/socket/qlocalserver_unix.cpp
index 560f5f6..c218d89 100644
--- a/src/network/socket/qlocalserver_unix.cpp
+++ b/src/network/socket/qlocalserver_unix.cpp
@@ -119,7 +119,7 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName)
// subsequent call to accept will not block in any case
//
// This change can be removed once more generic fix to select thread
- // syncronization problem is implemented.
+ // synchronization problem is implemented.
int flags = fcntl(listenSocket, F_GETFL, 0);
if (-1 == flags
|| -1 == (fcntl(listenSocket, F_SETFL, flags | O_NONBLOCK))) {
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index 477ef45..c1a4cfc 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -733,7 +733,7 @@ int QNativeSocketEnginePrivate::nativeAccept()
{
int acceptedDescriptor = WSAAccept(socketDescriptor, 0,0,0,0);
if (acceptedDescriptor != -1 && QAbstractEventDispatcher::instance()) {
- // Becuase of WSAAsyncSelect() WSAAccept returns a non blocking socket
+ // Because of WSAAsyncSelect() WSAAccept returns a non blocking socket
// with the same attributes as the listening socket including the current
// WSAAsyncSelect(). To be able to change the socket to blocking mode the
// WSAAsyncSelect() call must be cancled.
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index c9f421f..a752720 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -2035,6 +2035,20 @@ void QSslSocketPrivate::createPlainSocket(QIODevice::OpenMode openMode)
q->setReadBufferSize(readBufferMaxSize);
}
+void QSslSocketPrivate::pauseSocketNotifiers(QSslSocket *socket)
+{
+ if (!socket->d_func()->plainSocket)
+ return;
+ QAbstractSocketPrivate::pauseSocketNotifiers(socket->d_func()->plainSocket);
+}
+
+void QSslSocketPrivate::resumeSocketNotifiers(QSslSocket *socket)
+{
+ if (!socket->d_func()->plainSocket)
+ return;
+ QAbstractSocketPrivate::resumeSocketNotifiers(socket->d_func()->plainSocket);
+}
+
/*!
\internal
*/
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index 72b3ef7..94f5f39 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -142,6 +142,8 @@ public:
// The socket itself, including private slots.
QTcpSocket *plainSocket;
void createPlainSocket(QIODevice::OpenMode openMode);
+ static void pauseSocketNotifiers(QSslSocket*);
+ static void resumeSocketNotifiers(QSslSocket*);
void _q_connectedSlot();
void _q_hostFoundSlot();
void _q_disconnectedSlot();
diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp
index a8b8911..184ceb4 100644
--- a/src/plugins/bearer/connman/qconnmanengine.cpp
+++ b/src/plugins/bearer/connman/qconnmanengine.cpp
@@ -170,13 +170,26 @@ bool QConnmanEngine::hasIdentifier(const QString &id)
void QConnmanEngine::connectToId(const QString &id)
{
QMutexLocker locker(&mutex);
- QConnmanConnectThread *thread;
- thread = new QConnmanConnectThread(this);
- thread->setServicePath(serviceFromId(id));
- thread->setIdentifier(id);
- connect(thread,SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)),
- this,SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)));
- thread->start();
+ QString servicePath = serviceFromId(id);
+ QConnmanServiceInterface serv(servicePath);
+ if(!serv.isValid()) {
+ emit connectionError(id, QBearerEngineImpl::InterfaceLookupError);
+ } else {
+ if(serv.getType() != "cellular") {
+
+ serv.connect();
+ } else {
+ QOfonoManagerInterface ofonoManager(0);
+ QString modemPath = ofonoManager.currentModem().path();
+ QOfonoDataConnectionManagerInterface dc(modemPath,0);
+ foreach(const QDBusObjectPath dcPath,dc.getPrimaryContexts()) {
+ if(dcPath.path().contains(servicePath.section("_",-1))) {
+ QOfonoPrimaryDataContextInterface primaryContext(dcPath.path(),0);
+ primaryContext.setActive(true);
+ }
+ }
+ }
+ }
}
void QConnmanEngine::disconnectFromId(const QString &id)
@@ -791,62 +804,6 @@ bool QConnmanEngine::requiresPolling() const
return false;
}
-
-QConnmanConnectThread::QConnmanConnectThread(QObject *parent)
- :QThread(parent),
- servicePath(), identifier()
-{
-}
-
-QConnmanConnectThread::~QConnmanConnectThread()
-{
-}
-
-void QConnmanConnectThread::stop()
-{
- if(currentThread() != this) {
- QMetaObject::invokeMethod(this, "quit",
- Qt::QueuedConnection);
- } else {
- quit();
- }
- wait();
-}
-
-void QConnmanConnectThread::run()
-{
- QConnmanServiceInterface serv(servicePath);
- if(!serv.isValid()) {
- emit connectionError(identifier, QBearerEngineImpl::InterfaceLookupError);
- } else {
- if(serv.getType() != "cellular") {
- serv.connect();
- } else {
- QOfonoManagerInterface ofonoManager(0);
- QString modemPath = ofonoManager.currentModem().path();
- QOfonoDataConnectionManagerInterface dc(modemPath,0);
- foreach(const QDBusObjectPath dcPath,dc.getPrimaryContexts()) {
- if(dcPath.path().contains(servicePath.section("_",-1))) {
- QOfonoPrimaryDataContextInterface primaryContext(dcPath.path(),0);
- primaryContext.setActive(true);
- }
- }
- }
- }
-}
-
-void QConnmanConnectThread::setServicePath(const QString &path)
-{
- QMutexLocker locker(&mutex);
- servicePath = path;
-}
-
-void QConnmanConnectThread::setIdentifier(const QString &id)
-{
- QMutexLocker locker(&mutex);
- identifier = id;
-}
-
QT_END_NAMESPACE
#endif // QT_NO_DBUS
diff --git a/src/plugins/bearer/connman/qconnmanengine.h b/src/plugins/bearer/connman/qconnmanengine.h
index 569bbc7..2a2308f 100644
--- a/src/plugins/bearer/connman/qconnmanengine.h
+++ b/src/plugins/bearer/connman/qconnmanengine.h
@@ -59,14 +59,12 @@
#include <QMap>
#include <QVariant>
-#include <QtCore/qthread.h>
#ifndef QT_NO_BEARERMANAGEMENT
#ifndef QT_NO_DBUS
QT_BEGIN_NAMESPACE
-class QConnmanConnectThread;
class QConnmanEngine : public QBearerEngineImpl
{
Q_OBJECT
@@ -141,33 +139,8 @@ private:
bool isRoamingAllowed(const QString &context);
protected:
bool requiresPolling() const;
- QConnmanConnectThread *connThread;
};
-class QConnmanConnectThread : public QThread
-{
- Q_OBJECT
-
-public:
- QConnmanConnectThread(QObject *parent = 0);
- ~QConnmanConnectThread();
- bool keepRunning;
- void stop();
- void setServicePath(const QString &path);
- void setIdentifier(const QString &id);
-
-Q_SIGNALS:
- void connectionError(const QString &id, QBearerEngineImpl::ConnectionError error);
-
-protected:
- void run();
- QString servicePath;
- QString identifier;
-
-private:
- QMutex mutex;
-
-};
QT_END_NAMESPACE
diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp
index 549a07a..46b6e80 100644
--- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp
+++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp
@@ -79,7 +79,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) {
QLatin1String(CONNMAN_MANAGER_PATH),
QLatin1String(CONNMAN_MANAGER_INTERFACE),
QLatin1String("PropertyChanged"),
- this,SIGNAL(propertyChanged(const QString &, const QDBusVariant & )))) {
+ this,SIGNAL(propertyChanged(const QString &, const QDBusVariant & ))), Qt::UniqueConnection) {
qWarning() << "PropertyCHanged not connected";
}
}
@@ -89,7 +89,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) {
QLatin1String(CONNMAN_MANAGER_PATH),
QLatin1String(CONNMAN_MANAGER_INTERFACE),
QLatin1String("StateChanged"),
- this,SIGNAL(stateChanged(const QString&)))) {
+ this,SIGNAL(stateChanged(const QString&))), Qt::UniqueConnection) {
qWarning() << "StateChanged not connected";
}
@@ -106,7 +106,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) {
QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)),
- this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)));
+ this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection);
}
}
@@ -338,7 +338,7 @@ void QConnmanNetworkInterface::connectNotify(const char *signal)
this->path(),
QLatin1String(CONNMAN_NETWORK_INTERFACE),
QLatin1String("PropertyChanged"),
- this,SIGNAL(propertyChanged(QString,QDBusVariant))) ) {
+ this,SIGNAL(propertyChanged(QString,QDBusVariant))), Qt::UniqueConnection) {
qWarning() << "network properties not connected";
}
}
@@ -350,10 +350,10 @@ void QConnmanNetworkInterface::connectNotify(const char *signal)
this->path(),
QLatin1String(CONNMAN_NETWORK_INTERFACE),
QLatin1String("PropertyChanged"),
- helper,SLOT(propertyChanged(QString,QDBusVariant)));
+ helper,SLOT(propertyChanged(QString,QDBusVariant))), Qt::UniqueConnection;
QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)),
- this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)));
+ this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection);
}
}
@@ -538,7 +538,7 @@ void QConnmanServiceInterface::connectNotify(const char *signal)
helper,SLOT(propertyChanged(QString,QDBusVariant)));
QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)),
- this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)));
+ this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection);
}
}
@@ -569,10 +569,9 @@ QVariant QConnmanServiceInterface::getProperty(const QString &property)
return var;
}
-// clearProperty
void QConnmanServiceInterface::connect()
{
- QDBusReply<QVariantMap> reply = this->call(QLatin1String("Connect"));
+ this->asyncCall(QLatin1String("Connect"));
}
void QConnmanServiceInterface::disconnect()
@@ -866,7 +865,7 @@ void QConnmanTechnologyInterface::connectNotify(const char *signal)
helper,SLOT(propertyChanged(QString,QDBusVariant)));
QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)),
- this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)));
+ this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection);
}
}
@@ -1031,7 +1030,7 @@ void QConnmanDeviceInterface::connectNotify(const char *signal)
helper,SLOT(propertyChanged(QString,QDBusVariant)));
QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)),
- this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)));
+ this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection);
}
}
diff --git a/src/plugins/bearer/connman/qofonoservice_linux.cpp b/src/plugins/bearer/connman/qofonoservice_linux.cpp
index 955f4b1..52f596b 100644
--- a/src/plugins/bearer/connman/qofonoservice_linux.cpp
+++ b/src/plugins/bearer/connman/qofonoservice_linux.cpp
@@ -262,7 +262,7 @@ void QOfonoModemInterface::connectNotify(const char *signal)
QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)),
- this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)));
+ this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection);
}}
void QOfonoModemInterface::disconnectNotify(const char *signal)
@@ -385,7 +385,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) {
QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)),
- this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)));
+ this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection);
}
}
@@ -483,7 +483,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) {
QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)),
- this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)));
+ this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection);
}
}
@@ -586,7 +586,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) {
QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)),
- this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)));
+ this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection);
}
}
@@ -675,7 +675,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) {
QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)),
- this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)));
+ this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection);
}
}
@@ -794,7 +794,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) {
QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)),
- this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)));
+ this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection);
}
}
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp
index f6390bb..f494106 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -1736,10 +1736,12 @@ QScriptValue QScriptValue::construct(const QScriptValueList &args)
JSC::JSValue savedException;
QScriptEnginePrivate::saveException(exec, &savedException);
- JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, jscArgs);
+ JSC::JSValue result;
+ JSC::JSObject *newObject = JSC::construct(exec, callee, constructType, constructData, jscArgs);
if (exec->hadException()) {
- result = JSC::asObject(exec->exception());
+ result = exec->exception();
} else {
+ result = newObject;
QScriptEnginePrivate::restoreException(exec, savedException);
}
return d->engine->scriptValueFromJSCValue(result);
@@ -1796,11 +1798,12 @@ QScriptValue QScriptValue::construct(const QScriptValue &arguments)
JSC::JSValue savedException;
QScriptEnginePrivate::saveException(exec, &savedException);
- JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, applyArgs);
+ JSC::JSValue result;
+ JSC::JSObject *newObject = JSC::construct(exec, callee, constructType, constructData, applyArgs);
if (exec->hadException()) {
- if (exec->exception().isObject())
- result = JSC::asObject(exec->exception());
+ result = exec->exception();
} else {
+ result = newObject;
QScriptEnginePrivate::restoreException(exec, savedException);
}
return d->engine->scriptValueFromJSCValue(result);
diff --git a/tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp b/tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp
index 89f608e..4a32a5a 100644
--- a/tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp
+++ b/tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp
@@ -57,7 +57,7 @@ public:
public Q_SLOTS:
void finishedReply();
void finishedWithError(QNetworkReply::NetworkError errorCode, const QString &detail);
- void challenge401(const QHttpNetworkRequest &request, QAuthenticator *authenticator, const QHttpNetworkConnection *connection);
+ void challenge401(const QHttpNetworkRequest &request, QAuthenticator *authenticator);
#ifndef QT_NO_OPENSSL
void sslErrors(const QList<QSslError> &errors);
#endif
@@ -175,11 +175,9 @@ void tst_QHttpNetworkConnection::head()
QFETCH(QString, statusString);
QFETCH(int, contentLength);
- QHttpNetworkConnection connection(host);
+ QHttpNetworkConnection connection(host, port, encrypt);
QCOMPARE(connection.port(), port);
QCOMPARE(connection.hostName(), host);
- if (encrypt)
- connection.enableEncryption();
QCOMPARE(connection.isEncrypted(), encrypt);
QHttpNetworkRequest request(protocol + host + path, QHttpNetworkRequest::Head);
@@ -235,11 +233,9 @@ void tst_QHttpNetworkConnection::get()
QFETCH(int, contentLength);
QFETCH(int, downloadSize);
- QHttpNetworkConnection connection(host);
+ QHttpNetworkConnection connection(host, port, encrypt);
QCOMPARE(connection.port(), port);
QCOMPARE(connection.hostName(), host);
- if (encrypt)
- connection.enableEncryption();
QCOMPARE(connection.isEncrypted(), encrypt);
QHttpNetworkRequest request(protocol + host + path);
@@ -315,11 +311,9 @@ void tst_QHttpNetworkConnection::put()
QFETCH(QString, data);
QFETCH(bool, succeed);
- QHttpNetworkConnection connection(host);
+ QHttpNetworkConnection connection(host, port, encrypt);
QCOMPARE(connection.port(), port);
QCOMPARE(connection.hostName(), host);
- if (encrypt)
- connection.enableEncryption();
QCOMPARE(connection.isEncrypted(), encrypt);
QHttpNetworkRequest request(protocol + host + path, QHttpNetworkRequest::Put);
@@ -336,8 +330,6 @@ void tst_QHttpNetworkConnection::put()
connect(reply, SIGNAL(finished()), SLOT(finishedReply()));
connect(reply, SIGNAL(finishedWithError(QNetworkReply::NetworkError, const QString &)),
SLOT(finishedWithError(QNetworkReply::NetworkError, const QString &)));
- connect(&connection, SIGNAL(error(QNetworkReply::NetworkError, const QString &)),
- SLOT(finishedWithError(QNetworkReply::NetworkError, const QString &)));
QTime stopWatch;
stopWatch.start();
@@ -407,11 +399,9 @@ void tst_QHttpNetworkConnection::post()
QFETCH(int, contentLength);
QFETCH(int, downloadSize);
- QHttpNetworkConnection connection(host);
+ QHttpNetworkConnection connection(host, port, encrypt);
QCOMPARE(connection.port(), port);
QCOMPARE(connection.hostName(), host);
- if (encrypt)
- connection.enableEncryption();
QCOMPARE(connection.isEncrypted(), encrypt);
QHttpNetworkRequest request(protocol + host + path, QHttpNetworkRequest::Post);
@@ -496,14 +486,14 @@ void tst_QHttpNetworkConnection::_connect()
}
void tst_QHttpNetworkConnection::challenge401(const QHttpNetworkRequest &request,
- QAuthenticator *authenticator,
- const QHttpNetworkConnection *connection)
+ QAuthenticator *authenticator)
{
Q_UNUSED(request)
- Q_UNUSED(connection)
- QHttpNetworkConnection *c = qobject_cast<QHttpNetworkConnection*>(sender());
- if (connection) {
+ QHttpNetworkReply *reply = qobject_cast<QHttpNetworkReply*>(sender());
+ if (reply) {
+ QHttpNetworkConnection *c = reply->connection();
+
QVariant val = c->property("setCredentials");
if (val.toBool()) {
QVariant user = c->property("username");
@@ -549,17 +539,15 @@ void tst_QHttpNetworkConnection::get401()
QHttpNetworkConnection connection(host, port, encrypt);
QCOMPARE(connection.port(), port);
QCOMPARE(connection.hostName(), host);
- if (encrypt)
- connection.enableEncryption();
QCOMPARE(connection.isEncrypted(), encrypt);
- connect(&connection, SIGNAL(authenticationRequired(const QHttpNetworkRequest&, QAuthenticator *, const QHttpNetworkConnection*)),
- SLOT(challenge401(const QHttpNetworkRequest&, QAuthenticator *, const QHttpNetworkConnection*)));
connection.setProperty("setCredentials", setCredentials);
connection.setProperty("username", username);
connection.setProperty("password", password);
QHttpNetworkRequest request(protocol + host + path);
QHttpNetworkReply *reply = connection.sendRequest(request);
+ connect(reply, SIGNAL(authenticationRequired(const QHttpNetworkRequest&, QAuthenticator *)),
+ SLOT(challenge401(const QHttpNetworkRequest&, QAuthenticator *)));
finishedCalled = false;
finishedWithErrorCalled = false;
@@ -618,11 +606,9 @@ void tst_QHttpNetworkConnection::compression()
QFETCH(bool, autoCompress);
QFETCH(QString, contentCoding);
- QHttpNetworkConnection connection(host);
+ QHttpNetworkConnection connection(host, port, encrypt);
QCOMPARE(connection.port(), port);
QCOMPARE(connection.hostName(), host);
- if (encrypt)
- connection.enableEncryption();
QCOMPARE(connection.isEncrypted(), encrypt);
QHttpNetworkRequest request(protocol + host + path);
@@ -668,8 +654,10 @@ void tst_QHttpNetworkConnection::sslErrors(const QList<QSslError> &errors)
{
Q_UNUSED(errors)
- QHttpNetworkConnection *connection = qobject_cast<QHttpNetworkConnection*>(sender());
- if (connection) {
+ QHttpNetworkReply *reply = qobject_cast<QHttpNetworkReply*>(sender());
+ if (reply) {
+ QHttpNetworkConnection *connection = reply->connection();
+
QVariant val = connection->property("ignoreFromSignal");
if (val.toBool())
connection->ignoreSslErrors();
@@ -711,17 +699,15 @@ void tst_QHttpNetworkConnection::ignoresslerror()
QHttpNetworkConnection connection(host, port, encrypt);
QCOMPARE(connection.port(), port);
QCOMPARE(connection.hostName(), host);
- if (encrypt)
- connection.enableEncryption();
if (ignoreInit)
connection.ignoreSslErrors();
QCOMPARE(connection.isEncrypted(), encrypt);
- connect(&connection, SIGNAL(sslErrors(const QList<QSslError>&)),
- SLOT(sslErrors(const QList<QSslError>&)));
connection.setProperty("ignoreFromSignal", ignoreFromSignal);
QHttpNetworkRequest request(protocol + host + path);
QHttpNetworkReply *reply = connection.sendRequest(request);
+ connect(reply, SIGNAL(sslErrors(const QList<QSslError>&)),
+ SLOT(sslErrors(const QList<QSslError>&)));
finishedWithErrorCalled = false;
@@ -769,8 +755,6 @@ void tst_QHttpNetworkConnection::nossl()
QHttpNetworkConnection connection(host, port, encrypt);
QCOMPARE(connection.port(), port);
QCOMPARE(connection.hostName(), host);
- if (encrypt)
- connection.enableEncryption();
QHttpNetworkRequest request(protocol + host + path);
QHttpNetworkReply *reply = connection.sendRequest(request);
diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
index 83a3388..639df36 100644
--- a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
+++ b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
@@ -2739,6 +2739,31 @@ void tst_QScriptValue::construct()
QVERIFY(!QScriptValue(QScriptValue::NullValue).construct().isValid());
}
+void tst_QScriptValue::construct_constructorThrowsPrimitive()
+{
+ QScriptEngine eng;
+ QScriptValue fun = eng.evaluate("(function() { throw 123; })");
+ QVERIFY(fun.isFunction());
+ // construct(QScriptValueList)
+ {
+ QScriptValue ret = fun.construct();
+ QVERIFY(ret.isNumber());
+ QCOMPARE(ret.toNumber(), 123.0);
+ QVERIFY(eng.hasUncaughtException());
+ QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
+ eng.clearExceptions();
+ }
+ // construct(QScriptValue)
+ {
+ QScriptValue ret = fun.construct(eng.newArray());
+ QVERIFY(ret.isNumber());
+ QCOMPARE(ret.toNumber(), 123.0);
+ QVERIFY(eng.hasUncaughtException());
+ QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
+ eng.clearExceptions();
+ }
+}
+
void tst_QScriptValue::lessThan_old()
{
QScriptEngine eng;
diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.h b/tests/auto/qscriptvalue/tst_qscriptvalue.h
index 8bfaa6a..462749a 100644
--- a/tests/auto/qscriptvalue/tst_qscriptvalue.h
+++ b/tests/auto/qscriptvalue/tst_qscriptvalue.h
@@ -219,6 +219,7 @@ private slots:
void getSetScriptClass();
void call();
void construct();
+ void construct_constructorThrowsPrimitive();
void castToPointer();
void prettyPrinter_data();
void prettyPrinter();