summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2012-04-17 12:58:41 +0200
committerLars Knoll <lars.knoll@nokia.com>2012-04-17 12:58:52 +0200
commit64255ef6502b1144f7b0aa4b2bf62803e0d4788b (patch)
tree29bf116bfda2ccf61057115690d14f85cc9b085b /src/network
parent4a9fb41a7947d0bb7a47a9625603a436df288b24 (diff)
parent7e0beba891cb963a1d535bd45b0be78b43b8d07f (diff)
Merge remote-tracking branch 'origin/api_changes'
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/qhttpmultipart.h4
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp15
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp16
-rw-r--r--src/network/access/qnetworkaccessdebugpipebackend.cpp3
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp11
-rw-r--r--src/network/access/qnetworkaccessmanager.h1
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h1
-rw-r--r--src/network/access/qnetworkcookie.h2
-rw-r--r--src/network/access/qnetworkcookiejar.h2
-rw-r--r--src/network/access/qnetworkreply.cpp6
-rw-r--r--src/network/access/qnetworkreply.h4
-rw-r--r--src/network/access/qnetworkreplydataimpl.cpp2
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp41
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp33
-rw-r--r--src/network/access/qnetworkrequest.cpp8
-rw-r--r--src/network/access/qnetworkrequest.h1
-rw-r--r--src/network/bearer/qnetworksession.cpp40
-rw-r--r--src/network/bearer/qnetworksession.h13
-rw-r--r--src/network/bearer/qnetworksession_p.h5
-rw-r--r--src/network/kernel/qdnslookup.h2
-rw-r--r--src/network/kernel/qhostaddress.cpp168
-rw-r--r--src/network/kernel/qhostaddress.h4
-rw-r--r--src/network/kernel/qhostinfo.h2
-rw-r--r--src/network/kernel/qnetworkproxy.h4
-rw-r--r--src/network/socket/qlocalserver.h2
-rw-r--r--src/network/ssl/qsslcertificate.h4
-rw-r--r--src/network/ssl/qsslsocket.h2
27 files changed, 206 insertions, 190 deletions
diff --git a/src/network/access/qhttpmultipart.h b/src/network/access/qhttpmultipart.h
index c25beb7ae3..aea8421d30 100644
--- a/src/network/access/qhttpmultipart.h
+++ b/src/network/access/qhttpmultipart.h
@@ -92,8 +92,8 @@ public:
AlternativeType
};
- QHttpMultiPart(QObject *parent = 0);
- QHttpMultiPart(ContentType contentType, QObject *parent = 0);
+ explicit QHttpMultiPart(QObject *parent = 0);
+ explicit QHttpMultiPart(ContentType contentType, QObject *parent = 0);
~QHttpMultiPart();
void append(const QHttpPart &httpPart);
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index f32251935b..1325f105cf 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -116,19 +116,18 @@ QByteArray QHttpNetworkRequestPrivate::methodName() const
QByteArray QHttpNetworkRequestPrivate::uri(bool throughProxy) const
{
- QUrl::FormattingOptions format(QUrl::RemoveFragment);
+ QUrl::FormattingOptions format(QUrl::RemoveFragment | QUrl::RemoveUserInfo | QUrl::FullyEncoded);
// for POST, query data is send as content
if (operation == QHttpNetworkRequest::Post && !uploadByteDevice)
format |= QUrl::RemoveQuery;
// for requests through proxy, the Request-URI contains full url
- if (throughProxy)
- format |= QUrl::RemoveUserInfo;
- else
+ if (!throughProxy)
format |= QUrl::RemoveScheme | QUrl::RemoveAuthority;
- QByteArray uri = url.toEncoded(format);
- if (uri.isEmpty() || (throughProxy && url.path().isEmpty()))
- uri += '/';
+ QUrl copy = url;
+ if (copy.path().isEmpty())
+ copy.setPath(QStringLiteral("/"));
+ QByteArray uri = copy.toEncoded(format);
return uri;
}
@@ -163,7 +162,7 @@ QByteArray QHttpNetworkRequestPrivate::header(const QHttpNetworkRequest &request
ba += "Content-Type: application/octet-stream\r\n";
}
if (!request.d->uploadByteDevice && request.d->url.hasQuery()) {
- QByteArray query = request.d->url.encodedQuery();
+ QByteArray query = request.d->url.query(QUrl::FullyEncoded).toLatin1();
ba += "Content-Length: ";
ba += QByteArray::number(query.size());
ba += "\r\n\r\n";
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index c8b4c51e23..634340bb54 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -105,12 +105,12 @@ static QNetworkReply::NetworkError statusCodeFromHttp(int httpStatusCode, const
static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy)
{
- QByteArray result;
+ QString result;
QUrl copy = url;
bool isEncrypted = copy.scheme().toLower() == QLatin1String("https");
copy.setPort(copy.port(isEncrypted ? 443 : 80));
- result = copy.toEncoded(QUrl::RemoveUserInfo | QUrl::RemovePath |
- QUrl::RemoveQuery | QUrl::RemoveFragment);
+ result = copy.toString(QUrl::RemoveUserInfo | QUrl::RemovePath |
+ QUrl::RemoveQuery | QUrl::RemoveFragment | QUrl::FullyEncoded);
#ifndef QT_NO_NETWORKPROXY
if (proxy && proxy->type() != QNetworkProxy::NoProxy) {
@@ -134,15 +134,15 @@ static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy)
key.setUserName(proxy->user());
key.setHost(proxy->hostName());
key.setPort(proxy->port());
- key.setEncodedQuery(result);
- result = key.toEncoded();
+ key.setQuery(result);
+ result = key.toString(QUrl::FullyEncoded);
}
}
#else
Q_UNUSED(proxy)
#endif
- return "http-connection:" + result;
+ return "http-connection:" + result.toLatin1();
}
class QNetworkAccessCachedHttpConnection: public QHttpNetworkConnection,
@@ -386,7 +386,7 @@ void QHttpThreadDelegate::finishedSlot()
// it's an error reply
QString msg = QLatin1String(QT_TRANSLATE_NOOP("QNetworkReply",
"Error downloading %1 - server replied: %2"));
- msg = msg.arg(QString::fromAscii(httpRequest.url().toEncoded()), httpReply->reasonPhrase());
+ msg = msg.arg(httpRequest.url().toString(), httpReply->reasonPhrase());
emit error(statusCodeFromHttp(httpReply->statusCode(), httpRequest.url()), msg);
}
@@ -406,7 +406,7 @@ void QHttpThreadDelegate::synchronousFinishedSlot()
// it's an error reply
QString msg = QLatin1String(QT_TRANSLATE_NOOP("QNetworkReply",
"Error downloading %1 - server replied: %2"));
- incomingErrorDetail = msg.arg(QString::fromAscii(httpRequest.url().toEncoded()), httpReply->reasonPhrase());
+ incomingErrorDetail = msg.arg(httpRequest.url().toString(), httpReply->reasonPhrase());
incomingErrorCode = statusCodeFromHttp(httpReply->statusCode(), httpRequest.url());
}
diff --git a/src/network/access/qnetworkaccessdebugpipebackend.cpp b/src/network/access/qnetworkaccessdebugpipebackend.cpp
index 5a4cd7b20d..3fb882b5e4 100644
--- a/src/network/access/qnetworkaccessdebugpipebackend.cpp
+++ b/src/network/access/qnetworkaccessdebugpipebackend.cpp
@@ -42,6 +42,7 @@
#include "qnetworkaccessdebugpipebackend_p.h"
#include "QtCore/qdatastream.h"
#include <QCoreApplication>
+#include <QUrlQuery>
#include "private/qnoncontiguousbytedevice_p.h"
QT_BEGIN_NAMESPACE
@@ -99,7 +100,7 @@ void QNetworkAccessDebugPipeBackend::open()
// socket bytes written -> we can push more from upstream to socket
connect(&socket, SIGNAL(bytesWritten(qint64)), SLOT(socketBytesWritten(qint64)));
- bareProtocol = url().queryItemValue(QLatin1String("bare")) == QLatin1String("1");
+ bareProtocol = QUrlQuery(url()).queryItemValue(QLatin1String("bare")) == QLatin1String("1");
if (operation() == QNetworkAccessManager::PutOperation) {
uploadByteDevice = createUploadByteDevice();
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 3a69ec4056..8d68f439f1 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -907,6 +907,17 @@ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccess
}
}
+/*!
+ \internal
+
+ Returns the network session currently in use.
+ This can be changed at any time, ownership remains with the QNetworkAccessManager
+*/
+const QWeakPointer<const QNetworkSession> QNetworkAccessManagerPrivate::getNetworkSession(const QNetworkAccessManager *q)
+{
+ return q->d_func()->networkSession.toWeakRef();
+}
+
#endif // QT_NO_BEARERMANAGEMENT
/*!
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index 4d23fcbcdc..85f963b52a 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -157,6 +157,7 @@ protected:
private:
friend class QNetworkReplyImplPrivate;
friend class QNetworkReplyHttpImpl;
+ friend class QNetworkReplyHttpImplPrivate;
Q_DECLARE_PRIVATE(QNetworkAccessManager)
Q_PRIVATE_SLOT(d_func(), void _q_replyFinished())
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index b0bcaabacc..8d62e78902 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -162,6 +162,7 @@ public:
static inline QNetworkAccessCache *getObjectCache(QNetworkAccessBackend *backend)
{ return &backend->manager->objectCache; }
Q_AUTOTEST_EXPORT static void clearCache(QNetworkAccessManager *manager);
+ Q_AUTOTEST_EXPORT static const QWeakPointer<const QNetworkSession> getNetworkSession(const QNetworkAccessManager *manager);
Q_DECLARE_PUBLIC(QNetworkAccessManager)
};
diff --git a/src/network/access/qnetworkcookie.h b/src/network/access/qnetworkcookie.h
index 32307e305e..5553e857de 100644
--- a/src/network/access/qnetworkcookie.h
+++ b/src/network/access/qnetworkcookie.h
@@ -66,7 +66,7 @@ public:
Full
};
- QNetworkCookie(const QByteArray &name = QByteArray(), const QByteArray &value = QByteArray());
+ explicit QNetworkCookie(const QByteArray &name = QByteArray(), const QByteArray &value = QByteArray());
QNetworkCookie(const QNetworkCookie &other);
~QNetworkCookie();
QNetworkCookie &operator=(const QNetworkCookie &other);
diff --git a/src/network/access/qnetworkcookiejar.h b/src/network/access/qnetworkcookiejar.h
index 513fb3b66c..8e6fa45ac5 100644
--- a/src/network/access/qnetworkcookiejar.h
+++ b/src/network/access/qnetworkcookiejar.h
@@ -57,7 +57,7 @@ class Q_NETWORK_EXPORT QNetworkCookieJar: public QObject
{
Q_OBJECT
public:
- QNetworkCookieJar(QObject *parent = 0);
+ explicit QNetworkCookieJar(QObject *parent = 0);
virtual ~QNetworkCookieJar();
virtual QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const;
diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp
index ac38f2efec..aefe07223f 100644
--- a/src/network/access/qnetworkreply.cpp
+++ b/src/network/access/qnetworkreply.cpp
@@ -131,6 +131,12 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
roaming to another access point. The request should be resubmitted
and will be processed as soon as the connection is re-established.
+ \value NetworkSessionFailedError the connection was broken due
+ to disconnection from the network or failure to start the network.
+
+ \value BackgroundRequestNotAllowedError the background request
+ is not currently allowed due to platform policy.
+
\value ProxyConnectionRefusedError the connection to the proxy
server was refused (the proxy server is not accepting requests)
diff --git a/src/network/access/qnetworkreply.h b/src/network/access/qnetworkreply.h
index b8d606c260..e514779a0a 100644
--- a/src/network/access/qnetworkreply.h
+++ b/src/network/access/qnetworkreply.h
@@ -77,6 +77,8 @@ public:
OperationCanceledError,
SslHandshakeFailedError,
TemporaryNetworkFailureError,
+ NetworkSessionFailedError,
+ BackgroundRequestNotAllowedError,
UnknownNetworkError = 99,
// proxy errors (101-199):
@@ -155,7 +157,7 @@ Q_SIGNALS:
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
protected:
- QNetworkReply(QObject *parent = 0);
+ explicit QNetworkReply(QObject *parent = 0);
QNetworkReply(QNetworkReplyPrivate &dd, QObject *parent);
virtual qint64 writeData(const char *data, qint64 len);
diff --git a/src/network/access/qnetworkreplydataimpl.cpp b/src/network/access/qnetworkreplydataimpl.cpp
index ab2c97b653..7a8d4ee3e0 100644
--- a/src/network/access/qnetworkreplydataimpl.cpp
+++ b/src/network/access/qnetworkreplydataimpl.cpp
@@ -88,7 +88,7 @@ QNetworkReplyDataImpl::QNetworkReplyDataImpl(QObject *parent, const QNetworkRequ
} else {
// something wrong with this URI
const QString msg = QCoreApplication::translate("QNetworkAccessDataBackend",
- "Invalid URI: %1").arg(QString::fromLatin1(url.toEncoded()));
+ "Invalid URI: %1").arg(url.toString());
setError(QNetworkReply::ProtocolFailure, msg);
QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProtocolFailure));
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 7977704e38..cac8098057 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -1041,7 +1041,7 @@ void QNetworkReplyHttpImplPrivate::checkForRedirect(const int statusCode)
// The response to a 303 MUST NOT be cached, while the response to
// all of the others is cacheable if the headers indicate it to be
QByteArray header = q->rawHeader("location");
- QUrl url = QUrl::fromEncoded(header);
+ QUrl url = QUrl(QString::fromUtf8(header));
if (!url.isValid())
url = QUrl(QLatin1String(header));
// FIXME?
@@ -1531,6 +1531,8 @@ bool QNetworkReplyHttpImplPrivate::start()
void QNetworkReplyHttpImplPrivate::_q_startOperation()
{
+ Q_Q(QNetworkReplyHttpImpl);
+
// ensure this function is only being called once
if (state == Working) {
qDebug("QNetworkReplyImpl::_q_startOperation was called more than once");
@@ -1538,6 +1540,19 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation()
}
state = Working;
+#ifndef QT_NO_BEARERMANAGEMENT
+ // Do not start background requests if they are not allowed by session policy
+ QSharedPointer<QNetworkSession> session(manager->d_func()->networkSession);
+ QVariant isBackground = request.attribute(QNetworkRequest::BackgroundRequestAttribute, QVariant::fromValue(false));
+ if (isBackground.toBool() && session && session->usagePolicies().testFlag(QNetworkSession::NoBackgroundTrafficPolicy)) {
+ QMetaObject::invokeMethod(q, "_q_error", synchronous ? Qt::DirectConnection : Qt::QueuedConnection,
+ Q_ARG(QNetworkReply::NetworkError, QNetworkReply::BackgroundRequestNotAllowedError),
+ Q_ARG(QString, QCoreApplication::translate("QNetworkReply", "Background request not allowed.")));
+ QMetaObject::invokeMethod(q, "_q_finished", synchronous ? Qt::DirectConnection : Qt::QueuedConnection);
+ return;
+ }
+#endif
+
if (!start()) {
#ifndef QT_NO_BEARERMANAGEMENT
// backend failed to start because the session state is not Connected.
@@ -1547,8 +1562,6 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation()
QNetworkSession *session = managerPrivate->networkSession.data();
if (session) {
- Q_Q(QNetworkReplyHttpImpl);
-
QObject::connect(session, SIGNAL(error(QNetworkSession::SessionError)),
q, SLOT(_q_networkSessionFailed()));
@@ -1556,9 +1569,20 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation()
session->open();
} else {
qWarning("Backend is waiting for QNetworkSession to connect, but there is none!");
+ QMetaObject::invokeMethod(q, "_q_error", synchronous ? Qt::DirectConnection : Qt::QueuedConnection,
+ Q_ARG(QNetworkReply::NetworkError, QNetworkReply::NetworkSessionFailedError),
+ Q_ARG(QString, QCoreApplication::translate("QNetworkReply", "Network session error.")));
+ QMetaObject::invokeMethod(q, "_q_finished", synchronous ? Qt::DirectConnection : Qt::QueuedConnection);
+ return;
}
-#endif
+#else
+ qWarning("Backend start failed");
+ QMetaObject::invokeMethod(q, "_q_error", synchronous ? Qt::DirectConnection : Qt::QueuedConnection,
+ Q_ARG(QNetworkReply::NetworkError, QNetworkReply::UnknownNetworkError),
+ Q_ARG(QString, QCoreApplication::translate("QNetworkReply", "backend start error.")));
+ QMetaObject::invokeMethod(q, "_q_finished", synchronous ? Qt::DirectConnection : Qt::QueuedConnection);
return;
+#endif
}
if (synchronous) {
@@ -1728,8 +1752,13 @@ void QNetworkReplyHttpImplPrivate::_q_networkSessionFailed()
// Abort waiting and working replies.
if (state == WaitingForSession || state == Working) {
state = Working;
- error(QNetworkReplyImpl::UnknownNetworkError,
- QCoreApplication::translate("QNetworkReply", "Network session error."));
+ QSharedPointer<QNetworkSession> session(manager->d_func()->networkSession);
+ QString errorStr;
+ if (session)
+ errorStr = session->errorString();
+ else
+ errorStr = QCoreApplication::translate("QNetworkReply", "Network session error.");
+ error(QNetworkReplyImpl::NetworkSessionFailedError, errorStr);
finished();
}
}
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index 3ab846439b..5cdee5d040 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -90,6 +90,18 @@ void QNetworkReplyImplPrivate::_q_startOperation()
return;
}
+#ifndef QT_NO_BEARERMANAGEMENT
+ // Do not start background requests if they are not allowed by session policy
+ QSharedPointer<QNetworkSession> session(manager->d_func()->networkSession);
+ QVariant isBackground = backend->request().attribute(QNetworkRequest::BackgroundRequestAttribute, QVariant::fromValue(false));
+ if (isBackground.toBool() && session && session->usagePolicies().testFlag(QNetworkSession::NoBackgroundTrafficPolicy)) {
+ error(QNetworkReply::BackgroundRequestNotAllowedError,
+ QCoreApplication::translate("QNetworkReply", "Background request not allowed."));
+ finished();
+ return;
+ }
+#endif
+
if (!backend->start()) {
#ifndef QT_NO_BEARERMANAGEMENT
// backend failed to start because the session state is not Connected.
@@ -97,20 +109,20 @@ void QNetworkReplyImplPrivate::_q_startOperation()
// state changes.
state = WaitingForSession;
- QNetworkSession *session = manager->d_func()->networkSession.data();
-
if (session) {
Q_Q(QNetworkReplyImpl);
- QObject::connect(session, SIGNAL(error(QNetworkSession::SessionError)),
+ QObject::connect(session.data(), SIGNAL(error(QNetworkSession::SessionError)),
q, SLOT(_q_networkSessionFailed()));
- if (!session->isOpen())
+ if (!session->isOpen()) {
+ session->setSessionProperty(QStringLiteral("ConnectInBackground"), isBackground);
session->open();
+ }
} else {
qWarning("Backend is waiting for QNetworkSession to connect, but there is none!");
state = Working;
- error(QNetworkReplyImpl::UnknownNetworkError,
+ error(QNetworkReplyImpl::NetworkSessionFailedError,
QCoreApplication::translate("QNetworkReply", "Network session error."));
finished();
}
@@ -296,8 +308,13 @@ void QNetworkReplyImplPrivate::_q_networkSessionFailed()
// Abort waiting and working replies.
if (state == WaitingForSession || state == Working) {
state = Working;
- error(QNetworkReplyImpl::UnknownNetworkError,
- QCoreApplication::translate("QNetworkReply", "Network session error."));
+ QSharedPointer<QNetworkSession> session(manager->d_func()->networkSession);
+ QString errorStr;
+ if (session)
+ errorStr = session->errorString();
+ else
+ errorStr = QCoreApplication::translate("QNetworkReply", "Network session error.");
+ error(QNetworkReplyImpl::NetworkSessionFailedError, errorStr);
finished();
}
}
@@ -970,7 +987,7 @@ qint64 QNetworkReplyImpl::readData(char *data, qint64 maxlen)
if (maxAvail == 0)
return d->state == QNetworkReplyImplPrivate::Finished ? -1 : 0;
// FIXME what about "Aborted" state?
- qMemCopy(data, d->downloadBuffer + d->downloadBufferReadPosition, maxAvail);
+ memcpy(data, d->downloadBuffer + d->downloadBufferReadPosition, maxAvail);
d->downloadBufferReadPosition += maxAvail;
return maxAvail;
}
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index f94337eaeb..1c8655e9ae 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -237,6 +237,14 @@ QT_BEGIN_NAMESPACE
\omitvalue SynchronousRequestAttribute
+ \value BackgroundRequestAttribute
+ Type: QVariant::Bool (default: false)
+ Indicates that this is a background transfer, rather than a user initiated
+ transfer. Depending on the platform, background transfers may be subject
+ to different policies.
+ The QNetworkSession ConnectInBackground property will be set according to
+ this attribute.
+
\value User
Special type. Additional information can be passed in
QVariants with types ranging from User to UserMax. The default
diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h
index 7f51826d17..68fc655b7a 100644
--- a/src/network/access/qnetworkrequest.h
+++ b/src/network/access/qnetworkrequest.h
@@ -87,6 +87,7 @@ public:
MaximumDownloadBufferSizeAttribute, // internal
DownloadBufferAttribute, // internal
SynchronousRequestAttribute, // internal
+ BackgroundRequestAttribute,
User = 1000,
UserMax = 32767
diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp
index ccf794633d..1a3c25a97f 100644
--- a/src/network/bearer/qnetworksession.cpp
+++ b/src/network/bearer/qnetworksession.cpp
@@ -149,6 +149,17 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \enum QNetworkSession::UsagePolicies
+
+ These flags allow the system to inform the application of network usage restrictions that
+ may be in place.
+
+ \value NoPolicy No policy in force, usage is unrestricted.
+ \value NoBackgroundTrafficPolicy Background network traffic (not user initiated) should be avoided
+ for example to save battery or data charges
+*/
+
+/*!
\fn void QNetworkSession::stateChanged(QNetworkSession::State state)
This signal is emitted whenever the state of the network session changes.
@@ -222,6 +233,12 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \fn void QNetworkSession::usagePoliciesChanged(UsagePolicies)
+
+ This signal is emitted when the usage policies in force are changed by the system.
+*/
+
+/*!
Constructs a session based on \a connectionConfig with the given \a parent.
\sa QNetworkConfiguration
@@ -247,6 +264,8 @@ QNetworkSession::QNetworkSession(const QNetworkConfiguration &connectionConfig,
this, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool)));
connect(d, SIGNAL(newConfigurationActivated()),
this, SIGNAL(newConfigurationActivated()));
+ connect(d, SIGNAL(usagePoliciesChanged(QNetworkSession::UsagePolicies)),
+ this, SIGNAL(usagePoliciesChanged(QNetworkSession::UsagePolicies)));
break;
}
}
@@ -254,6 +273,7 @@ QNetworkSession::QNetworkSession(const QNetworkConfiguration &connectionConfig,
qRegisterMetaType<QNetworkSession::State>();
qRegisterMetaType<QNetworkSession::SessionError>();
+ qRegisterMetaType<QNetworkSession::UsagePolicies>();
}
/*!
@@ -654,6 +674,26 @@ quint64 QNetworkSession::activeTime() const
}
/*!
+ Returns the network usage policies currently in force by the system.
+*/
+QNetworkSession::UsagePolicies QNetworkSession::usagePolicies() const
+{
+ return d ? d->usagePolicies() : QNetworkSession::NoPolicy;
+}
+
+/*!
+ \internal
+ Change usage policies for unit testing.
+ In normal use, the policies are published by the bearer plugin
+*/
+void QNetworkSessionPrivate::setUsagePolicies(QNetworkSession &session, QNetworkSession::UsagePolicies policies)
+{
+ if (!session.d)
+ return;
+ session.d->setUsagePolicies(policies);
+}
+
+/*!
\internal
This function is required to detect whether the client wants to control
diff --git a/src/network/bearer/qnetworksession.h b/src/network/bearer/qnetworksession.h
index 21d568ca13..d72fe0e759 100644
--- a/src/network/bearer/qnetworksession.h
+++ b/src/network/bearer/qnetworksession.h
@@ -83,6 +83,13 @@ public:
InvalidConfigurationError
};
+ enum UsagePolicy {
+ NoPolicy = 0,
+ NoBackgroundTrafficPolicy = 1
+ };
+
+ Q_DECLARE_FLAGS(UsagePolicies, UsagePolicy)
+
explicit QNetworkSession(const QNetworkConfiguration &connConfig, QObject *parent = 0);
virtual ~QNetworkSession();
@@ -101,7 +108,9 @@ public:
quint64 bytesWritten() const;
quint64 bytesReceived() const;
quint64 activeTime() const;
-
+
+ QNetworkSession::UsagePolicies usagePolicies() const;
+
bool waitForOpened(int msecs = 30000);
public Q_SLOTS:
@@ -122,6 +131,7 @@ Q_SIGNALS:
void error(QNetworkSession::SessionError);
void preferredConfigurationChanged(const QNetworkConfiguration &config, bool isSeamless);
void newConfigurationActivated();
+ void usagePoliciesChanged(QNetworkSession::UsagePolicies);
protected:
virtual void connectNotify(const char *signal);
@@ -136,6 +146,7 @@ private:
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QNetworkSession::State)
Q_DECLARE_METATYPE(QNetworkSession::SessionError)
+Q_DECLARE_METATYPE(QNetworkSession::UsagePolicies)
QT_END_HEADER
diff --git a/src/network/bearer/qnetworksession_p.h b/src/network/bearer/qnetworksession_p.h
index 0eea06b085..4d036d601d 100644
--- a/src/network/bearer/qnetworksession_p.h
+++ b/src/network/bearer/qnetworksession_p.h
@@ -103,6 +103,10 @@ public:
virtual quint64 bytesReceived() const = 0;
virtual quint64 activeTime() const = 0;
+ virtual QNetworkSession::UsagePolicies usagePolicies() const = 0;
+ virtual void setUsagePolicies(QNetworkSession::UsagePolicies) = 0;
+
+ static void setUsagePolicies(QNetworkSession&, QNetworkSession::UsagePolicies); //for unit testing
protected:
inline QNetworkConfigurationPrivatePointer privateConfiguration(const QNetworkConfiguration &config) const
{
@@ -124,6 +128,7 @@ Q_SIGNALS:
void closed();
void newConfigurationActivated();
void preferredConfigurationChanged(const QNetworkConfiguration &config, bool isSeamless);
+ void usagePoliciesChanged(QNetworkSession::UsagePolicies);
protected:
QNetworkSession *q;
diff --git a/src/network/kernel/qdnslookup.h b/src/network/kernel/qdnslookup.h
index 198b19d8a8..89e8cbb852 100644
--- a/src/network/kernel/qdnslookup.h
+++ b/src/network/kernel/qdnslookup.h
@@ -191,7 +191,7 @@ public:
TXT = 16
};
- QDnsLookup(QObject *parent = 0);
+ explicit QDnsLookup(QObject *parent = 0);
QDnsLookup(Type type, const QString &name, QObject *parent = 0);
~QDnsLookup();
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp
index 230abb86aa..3c08717d11 100644
--- a/src/network/kernel/qhostaddress.cpp
+++ b/src/network/kernel/qhostaddress.cpp
@@ -41,6 +41,7 @@
#include "qhostaddress.h"
#include "qhostaddress_p.h"
+#include "private/qipaddress_p.h"
#include "qdebug.h"
#if defined(Q_OS_WIN)
#include <winsock2.h>
@@ -107,13 +108,14 @@ public:
bool parse();
void clear();
+ QString ipString;
+ QString scopeId;
+
quint32 a; // IPv4 address
Q_IPV6ADDR a6; // IPv6 address
QAbstractSocket::NetworkLayerProtocol protocol;
- QString ipString;
bool isParsed;
- QString scopeId;
friend class QHostAddress;
};
@@ -175,28 +177,7 @@ void QHostAddressPrivate::setAddress(const Q_IPV6ADDR &a_)
isParsed = true;
}
-static bool parseIp4(const QString& address, quint32 *addr)
-{
- QStringList ipv4 = address.split(QLatin1String("."));
- if (ipv4.count() != 4)
- return false;
-
- quint32 ipv4Address = 0;
- for (int i = 0; i < 4; ++i) {
- bool ok = false;
- uint byteValue = ipv4.at(i).toUInt(&ok);
- if (!ok || byteValue > 255)
- return false;
-
- ipv4Address <<= 8;
- ipv4Address += byteValue;
- }
-
- *addr = ipv4Address;
- return true;
-}
-
-static bool parseIp6(const QString &address, quint8 *addr, QString *scopeId)
+static bool parseIp6(const QString &address, QIPAddressUtils::IPv6Address &addr, QString *scopeId)
{
QString tmp = address;
int scopeIdPos = tmp.lastIndexOf(QLatin1Char('%'));
@@ -206,77 +187,7 @@ static bool parseIp6(const QString &address, quint8 *addr, QString *scopeId)
} else {
scopeId->clear();
}
-
- QStringList ipv6 = tmp.split(QLatin1String(":"));
- int count = ipv6.count();
- if (count < 3 || count > 8)
- return false;
-
- int colonColon = tmp.count(QLatin1String("::"));
- if(count == 8 && colonColon > 1)
- return false;
-
- // address can be compressed with a "::", but that
- // may only appear once (see RFC 1884)
- // the statement below means:
- // if(shortened notation is not used AND
- // ((pure IPv6 notation AND less than 8 parts) OR
- // ((mixed IPv4/6 notation AND less than 7 parts)))
- if(colonColon != 1 && count < (tmp.contains(QLatin1Char('.')) ? 7 : 8))
- return false;
-
- int mc = 16;
- int fillCount = 9 - count; // number of 0 words to fill in the middle
- for (int i = count - 1; i >= 0; --i) {
- if (mc <= 0)
- return false;
-
- if (ipv6.at(i).isEmpty()) {
- if (i == count - 1) {
- // special case: ":" is last character
- if (!ipv6.at(i - 1).isEmpty())
- return false;
- addr[--mc] = 0;
- addr[--mc] = 0;
- } else if (i == 0) {
- // special case: ":" is first character
- if (!ipv6.at(i + 1).isEmpty())
- return false;
- addr[--mc] = 0;
- addr[--mc] = 0;
- } else {
- for (int j = 0; j < fillCount; ++j) {
- if (mc <= 0)
- return false;
- addr[--mc] = 0;
- addr[--mc] = 0;
- }
- }
- } else {
- bool ok = false;
- uint byteValue = ipv6.at(i).toUInt(&ok, 16);
- if (ok && byteValue <= 0xffff) {
- addr[--mc] = byteValue & 0xff;
- addr[--mc] = (byteValue >> 8) & 0xff;
- } else {
- if (i != count - 1)
- return false;
-
- // parse the ipv4 part of a mixed type
- quint32 maybeIp4;
- if (!parseIp4(ipv6.at(i), &maybeIp4))
- return false;
-
- addr[--mc] = maybeIp4 & 0xff;
- addr[--mc] = (maybeIp4 >> 8) & 0xff;
- addr[--mc] = (maybeIp4 >> 16) & 0xff;
- addr[--mc] = (maybeIp4 >> 24) & 0xff;
- --fillCount;
- }
- }
- }
-
- return true;
+ return QIPAddressUtils::parseIp6(addr, tmp.constBegin(), tmp.constEnd());
}
bool QHostAddressPrivate::parse()
@@ -284,6 +195,8 @@ bool QHostAddressPrivate::parse()
isParsed = true;
protocol = QAbstractSocket::UnknownNetworkLayerProtocol;
QString a = ipString.simplified();
+ if (a.isEmpty())
+ return false;
// All IPv6 addresses contain a ':', and may contain a '.'.
if (a.contains(QLatin1Char(':'))) {
@@ -295,14 +208,11 @@ bool QHostAddressPrivate::parse()
}
}
- // All IPv4 addresses contain a '.'.
- if (a.contains(QLatin1Char('.'))) {
- quint32 maybeIp4 = 0;
- if (parseIp4(a, &maybeIp4)) {
- setAddress(maybeIp4);
- protocol = QAbstractSocket::IPv4Protocol;
- return true;
- }
+ quint32 maybeIp4 = 0;
+ if (QIPAddressUtils::parseIp4(maybeIp4, a.constBegin(), a.constEnd())) {
+ setAddress(maybeIp4);
+ protocol = QAbstractSocket::IPv4Protocol;
+ return true;
}
return false;
@@ -556,23 +466,27 @@ QHostAddress::QHostAddress(const QHostAddress &address)
QHostAddress::QHostAddress(SpecialAddress address)
: d(new QHostAddressPrivate)
{
+ Q_IPV6ADDR ip6;
+ memset(&ip6, 0, sizeof ip6);
+
switch (address) {
case Null:
break;
case Broadcast:
- setAddress(QLatin1String("255.255.255.255"));
+ d->setAddress(quint32(-1));
break;
case LocalHost:
- setAddress(QLatin1String("127.0.0.1"));
+ d->setAddress(0x7f000001);
break;
case LocalHostIPv6:
- setAddress(QLatin1String("::1"));
+ ip6[15] = 1;
+ d->setAddress(ip6);
break;
case AnyIPv4:
- setAddress(QLatin1String("0.0.0.0"));
+ setAddress(0u);
break;
case AnyIPv6:
- setAddress(QLatin1String("::"));
+ d->setAddress(ip6);
break;
case Any:
d->clear();
@@ -761,42 +675,13 @@ QString QHostAddress::toString() const
|| d->protocol == QAbstractSocket::AnyIPProtocol) {
quint32 i = toIPv4Address();
QString s;
- s.sprintf("%d.%d.%d.%d", (i>>24) & 0xff, (i>>16) & 0xff,
- (i >> 8) & 0xff, i & 0xff);
+ QIPAddressUtils::toString(s, i);
return s;
}
if (d->protocol == QAbstractSocket::IPv6Protocol) {
- quint16 ugle[8];
- for (int i = 0; i < 8; i++) {
- ugle[i] = (quint16(d->a6[2*i]) << 8) | quint16(d->a6[2*i+1]);
- }
QString s;
- QString temp;
- bool zeroDetected = false;
- bool zeroShortened = false;
- for (int i = 0; i < 8; i++) {
- if ((ugle[i] != 0) || zeroShortened) {
- temp.sprintf("%X", ugle[i]);
- s.append(temp);
- if (zeroDetected)
- zeroShortened = true;
- } else {
- if (!zeroDetected) {
- if (i<7 && (ugle[i+1] == 0)) {
- s.append(QLatin1Char(':'));
- zeroDetected = true;
- } else {
- temp.sprintf("%X", ugle[i]);
- s.append(temp);
- if (i<7)
- s.append(QLatin1Char(':'));
- }
- }
- }
- if (i<7 && ((ugle[i] != 0) || zeroShortened || (i==0 && zeroDetected)))
- s.append(QLatin1Char(':'));
- }
+ QIPAddressUtils::toString(s, d->a6.c);
if (!d->scopeId.isEmpty())
s.append(QLatin1Char('%') + d->scopeId);
@@ -1142,9 +1027,10 @@ QDebug operator<<(QDebug d, const QHostAddress &address)
}
#endif
-uint qHash(const QHostAddress &key)
+uint qHash(const QHostAddress &key, uint seed)
{
- return qHash(key.toString());
+ QT_ENSURE_PARSED(&key);
+ return qHash(QByteArray::fromRawData(reinterpret_cast<const char *>(key.d->a6.c), 16), seed);
}
#ifndef QT_NO_DATASTREAM
diff --git a/src/network/kernel/qhostaddress.h b/src/network/kernel/qhostaddress.h
index fdf09ecc82..ce4470d32e 100644
--- a/src/network/kernel/qhostaddress.h
+++ b/src/network/kernel/qhostaddress.h
@@ -123,6 +123,7 @@ public:
static QPair<QHostAddress, int> parseSubnet(const QString &subnet);
+ friend Q_NETWORK_EXPORT uint qHash(const QHostAddress &key, uint seed = 0);
protected:
QScopedPointer<QHostAddressPrivate> d;
};
@@ -134,9 +135,6 @@ inline bool operator ==(QHostAddress::SpecialAddress address1, const QHostAddres
Q_NETWORK_EXPORT QDebug operator<<(QDebug, const QHostAddress &);
#endif
-
-Q_NETWORK_EXPORT uint qHash(const QHostAddress &key);
-
#ifndef QT_NO_DATASTREAM
Q_NETWORK_EXPORT QDataStream &operator<<(QDataStream &, const QHostAddress &);
Q_NETWORK_EXPORT QDataStream &operator>>(QDataStream &, QHostAddress &);
diff --git a/src/network/kernel/qhostinfo.h b/src/network/kernel/qhostinfo.h
index df377872c8..2fc87f3bdc 100644
--- a/src/network/kernel/qhostinfo.h
+++ b/src/network/kernel/qhostinfo.h
@@ -63,7 +63,7 @@ public:
UnknownError
};
- QHostInfo(int lookupId = -1);
+ explicit QHostInfo(int lookupId = -1);
QHostInfo(const QHostInfo &d);
QHostInfo &operator=(const QHostInfo &d);
~QHostInfo();
diff --git a/src/network/kernel/qnetworkproxy.h b/src/network/kernel/qnetworkproxy.h
index 805f5cdb5c..2e5c3ed687 100644
--- a/src/network/kernel/qnetworkproxy.h
+++ b/src/network/kernel/qnetworkproxy.h
@@ -68,10 +68,10 @@ public:
};
QNetworkProxyQuery();
- QNetworkProxyQuery(const QUrl &requestUrl, QueryType queryType = UrlRequest);
+ explicit QNetworkProxyQuery(const QUrl &requestUrl, QueryType queryType = UrlRequest);
QNetworkProxyQuery(const QString &hostname, int port, const QString &protocolTag = QString(),
QueryType queryType = TcpSocket);
- QNetworkProxyQuery(quint16 bindPort, const QString &protocolTag = QString(),
+ explicit QNetworkProxyQuery(quint16 bindPort, const QString &protocolTag = QString(),
QueryType queryType = TcpServer);
QNetworkProxyQuery(const QNetworkProxyQuery &other);
#ifndef QT_NO_BEARERMANAGEMENT
diff --git a/src/network/socket/qlocalserver.h b/src/network/socket/qlocalserver.h
index 291122e10d..f9499c69ba 100644
--- a/src/network/socket/qlocalserver.h
+++ b/src/network/socket/qlocalserver.h
@@ -74,7 +74,7 @@ public:
};
Q_DECLARE_FLAGS(SocketOptions, SocketOption)
- QLocalServer(QObject *parent = 0);
+ explicit QLocalServer(QObject *parent = 0);
~QLocalServer();
void close();
diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h
index b15d6e97bb..fbb38a9b46 100644
--- a/src/network/ssl/qsslcertificate.h
+++ b/src/network/ssl/qsslcertificate.h
@@ -82,8 +82,8 @@ public:
EmailAddress
};
- QSslCertificate(QIODevice *device, QSsl::EncodingFormat format = QSsl::Pem);
- QSslCertificate(const QByteArray &data = QByteArray(), QSsl::EncodingFormat format = QSsl::Pem);
+ explicit QSslCertificate(QIODevice *device, QSsl::EncodingFormat format = QSsl::Pem);
+ explicit QSslCertificate(const QByteArray &data = QByteArray(), QSsl::EncodingFormat format = QSsl::Pem);
QSslCertificate(const QSslCertificate &other);
~QSslCertificate();
QSslCertificate &operator=(const QSslCertificate &other);
diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h
index e420972041..195cbdf7c7 100644
--- a/src/network/ssl/qsslsocket.h
+++ b/src/network/ssl/qsslsocket.h
@@ -80,7 +80,7 @@ public:
AutoVerifyPeer
};
- QSslSocket(QObject *parent = 0);
+ explicit QSslSocket(QObject *parent = 0);
~QSslSocket();
void resume(); // to continue after proxy authentication required, SSL errors etc.