Merge branch 'master' of git://scm.dev.nokia.troll.no/qt/qtbase-earth-staging
* 'master' of git://scm.dev.nokia.troll.no/qt/qtbase-earth-staging: Skip test on MacOS due to problems with corewlan plugin Fix QNetworkConfigurationManager usage outside main thread first Update QTBUG-17223 for Qt 4.8 fix tst_qnetworkreply::httpProxyCommands autotest Send User-Agent from the network request in http proxy CONNECT command Add autotests for configuration dependent network proxies Fix QNetworkReplyImpl error handling Enable per network configuration proxy settings in QNetworkAccessManager Allow a network configuration to be included in a proxy query Fix error handling in write for socks socket engine
This commit is contained in:
commit
e8aceff195
@ -520,6 +520,15 @@ bool QHttpNetworkConnectionPrivate::dequeueRequest(QAbstractSocket *socket)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QHttpNetworkRequest QHttpNetworkConnectionPrivate::predictNextRequest()
|
||||||
|
{
|
||||||
|
if (!highPriorityQueue.isEmpty())
|
||||||
|
return highPriorityQueue.last().first;
|
||||||
|
if (!lowPriorityQueue.isEmpty())
|
||||||
|
return lowPriorityQueue.last().first;
|
||||||
|
return QHttpNetworkRequest();
|
||||||
|
}
|
||||||
|
|
||||||
// this is called from _q_startNextRequest and when a request has been sent down a socket from the channel
|
// this is called from _q_startNextRequest and when a request has been sent down a socket from the channel
|
||||||
void QHttpNetworkConnectionPrivate::fillPipeline(QAbstractSocket *socket)
|
void QHttpNetworkConnectionPrivate::fillPipeline(QAbstractSocket *socket)
|
||||||
{
|
{
|
||||||
|
@ -169,6 +169,7 @@ public:
|
|||||||
void requeueRequest(const HttpMessagePair &pair); // e.g. after pipeline broke
|
void requeueRequest(const HttpMessagePair &pair); // e.g. after pipeline broke
|
||||||
bool dequeueRequest(QAbstractSocket *socket);
|
bool dequeueRequest(QAbstractSocket *socket);
|
||||||
void prepareRequest(HttpMessagePair &request);
|
void prepareRequest(HttpMessagePair &request);
|
||||||
|
QHttpNetworkRequest predictNextRequest();
|
||||||
|
|
||||||
void fillPipeline(QAbstractSocket *socket);
|
void fillPipeline(QAbstractSocket *socket);
|
||||||
bool fillPipeline(QList<HttpMessagePair> &queue, QHttpNetworkConnectionChannel &channel);
|
bool fillPipeline(QList<HttpMessagePair> &queue, QHttpNetworkConnectionChannel &channel);
|
||||||
|
@ -579,6 +579,17 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
|
|||||||
connectHost = connection->d_func()->networkProxy.hostName();
|
connectHost = connection->d_func()->networkProxy.hostName();
|
||||||
connectPort = connection->d_func()->networkProxy.port();
|
connectPort = connection->d_func()->networkProxy.port();
|
||||||
}
|
}
|
||||||
|
if (socket->proxy().type() == QNetworkProxy::HttpProxy) {
|
||||||
|
// Make user-agent field available to HTTP proxy socket engine (QTBUG-17223)
|
||||||
|
QByteArray value;
|
||||||
|
// ensureConnection is called before any request has been assigned, but can also be called again if reconnecting
|
||||||
|
if (request.url().isEmpty())
|
||||||
|
value = connection->d_func()->predictNextRequest().headerField("user-agent");
|
||||||
|
else
|
||||||
|
value = request.headerField("user-agent");
|
||||||
|
if (!value.isEmpty())
|
||||||
|
socket->setProperty("_q_user-agent", value);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (ssl) {
|
if (ssl) {
|
||||||
#ifndef QT_NO_OPENSSL
|
#ifndef QT_NO_OPENSSL
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
#include "qnetworkaccessbackend_p.h"
|
#include "qnetworkaccessbackend_p.h"
|
||||||
#include "qnetworkaccessmanager_p.h"
|
#include "qnetworkaccessmanager_p.h"
|
||||||
|
#include "qnetworkconfigmanager.h"
|
||||||
#include "qnetworkrequest.h"
|
#include "qnetworkrequest.h"
|
||||||
#include "qnetworkreply.h"
|
#include "qnetworkreply.h"
|
||||||
#include "qnetworkreply_p.h"
|
#include "qnetworkreply_p.h"
|
||||||
@ -343,8 +344,6 @@ void QNetworkAccessBackend::sslErrors(const QList<QSslError> &errors)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_BEARERMANAGEMENT
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Starts the backend. Returns true if the backend is started. Returns false if the backend
|
Starts the backend. Returns true if the backend is started. Returns false if the backend
|
||||||
could not be started due to an unopened or roaming session. The caller should recall this
|
could not be started due to an unopened or roaming session. The caller should recall this
|
||||||
@ -352,31 +351,62 @@ void QNetworkAccessBackend::sslErrors(const QList<QSslError> &errors)
|
|||||||
*/
|
*/
|
||||||
bool QNetworkAccessBackend::start()
|
bool QNetworkAccessBackend::start()
|
||||||
{
|
{
|
||||||
if (!manager->networkSession) {
|
#ifndef QT_NO_BEARERMANAGEMENT
|
||||||
open();
|
// For bearer, check if session start is required
|
||||||
return true;
|
if (manager->networkSession) {
|
||||||
}
|
// session required
|
||||||
|
if (manager->networkSession->isOpen() &&
|
||||||
|
manager->networkSession->state() == QNetworkSession::Connected) {
|
||||||
|
// Session is already open and ready to use.
|
||||||
|
// copy network session down to the backend
|
||||||
|
setProperty("_q_networksession", QVariant::fromValue(manager->networkSession));
|
||||||
|
} else {
|
||||||
|
// Session not ready, but can skip for loopback connections
|
||||||
|
|
||||||
// This is not ideal.
|
// This is not ideal.
|
||||||
const QString host = reply->url.host();
|
const QString host = reply->url.host();
|
||||||
if (host == QLatin1String("localhost") ||
|
|
||||||
QHostAddress(host) == QHostAddress::LocalHost ||
|
|
||||||
QHostAddress(host) == QHostAddress::LocalHostIPv6) {
|
|
||||||
// Don't need an open session for localhost access.
|
|
||||||
open();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (manager->networkSession->isOpen() &&
|
if (host == QLatin1String("localhost") ||
|
||||||
manager->networkSession->state() == QNetworkSession::Connected) {
|
QHostAddress(host) == QHostAddress::LocalHost ||
|
||||||
//copy network session down to the backend
|
QHostAddress(host) == QHostAddress::LocalHostIPv6) {
|
||||||
setProperty("_q_networksession", QVariant::fromValue(manager->networkSession));
|
// Don't need an open session for localhost access.
|
||||||
open();
|
} else {
|
||||||
return true;
|
// need to wait for session to be opened
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef QT_NO_NETWORKPROXY
|
||||||
|
#ifndef QT_NO_BEARERMANAGEMENT
|
||||||
|
// Get the proxy settings from the network session (in the case of service networks,
|
||||||
|
// the proxy settings change depending which AP was activated)
|
||||||
|
QNetworkSession *session = manager->networkSession.data();
|
||||||
|
QNetworkConfiguration config;
|
||||||
|
if (session) {
|
||||||
|
QNetworkConfigurationManager configManager;
|
||||||
|
// The active configuration tells us what IAP is in use
|
||||||
|
QVariant v = session->sessionProperty(QLatin1String("ActiveConfiguration"));
|
||||||
|
if (v.isValid())
|
||||||
|
config = configManager.configurationFromIdentifier(qvariant_cast<QString>(v));
|
||||||
|
// Fallback to using the configuration if no active configuration
|
||||||
|
if (!config.isValid())
|
||||||
|
config = session->configuration();
|
||||||
|
// or unspecified configuration if that is no good either
|
||||||
|
if (!config.isValid())
|
||||||
|
config = QNetworkConfiguration();
|
||||||
|
}
|
||||||
|
reply->proxyList = manager->queryProxy(QNetworkProxyQuery(config, url()));
|
||||||
|
#else // QT_NO_BEARERMANAGEMENT
|
||||||
|
// Without bearer management, the proxy depends only on the url
|
||||||
|
reply->proxyList = manager->queryProxy(QNetworkProxyQuery(url()));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// now start the request
|
||||||
|
open();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -1004,10 +1004,6 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
|
|||||||
// third step: find a backend
|
// third step: find a backend
|
||||||
priv->backend = d->findBackend(op, request);
|
priv->backend = d->findBackend(op, request);
|
||||||
|
|
||||||
#ifndef QT_NO_NETWORKPROXY
|
|
||||||
QList<QNetworkProxy> proxyList = d->queryProxy(QNetworkProxyQuery(request.url()));
|
|
||||||
priv->proxyList = proxyList;
|
|
||||||
#endif
|
|
||||||
if (priv->backend) {
|
if (priv->backend) {
|
||||||
priv->backend->setParent(reply);
|
priv->backend->setParent(reply);
|
||||||
priv->backend->reply = priv;
|
priv->backend->reply = priv;
|
||||||
|
@ -89,10 +89,10 @@ void QNetworkReplyImplPrivate::_q_startOperation()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!backend->start()) {
|
||||||
#ifndef QT_NO_BEARERMANAGEMENT
|
#ifndef QT_NO_BEARERMANAGEMENT
|
||||||
if (!backend->start()) { // ### we should call that method even if bearer is not used
|
|
||||||
// backend failed to start because the session state is not Connected.
|
// backend failed to start because the session state is not Connected.
|
||||||
// QNetworkAccessManager will call reply->backend->start() again for us when the session
|
// QNetworkAccessManager will call _q_startOperation again for us when the session
|
||||||
// state changes.
|
// state changes.
|
||||||
state = WaitingForSession;
|
state = WaitingForSession;
|
||||||
|
|
||||||
@ -108,11 +108,20 @@ void QNetworkReplyImplPrivate::_q_startOperation()
|
|||||||
session->open();
|
session->open();
|
||||||
} else {
|
} else {
|
||||||
qWarning("Backend is waiting for QNetworkSession to connect, but there is none!");
|
qWarning("Backend is waiting for QNetworkSession to connect, but there is none!");
|
||||||
|
state = Working;
|
||||||
|
error(QNetworkReplyImpl::UnknownNetworkError,
|
||||||
|
QCoreApplication::translate("QNetworkReply", "Network session error."));
|
||||||
|
finished();
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
qWarning("Backend start failed");
|
||||||
|
state = Working;
|
||||||
|
error(QNetworkReplyImpl::UnknownNetworkError,
|
||||||
|
QCoreApplication::translate("QNetworkReply", "backend start error."));
|
||||||
|
finished();
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (backend && backend->isSynchronous()) {
|
if (backend && backend->isSynchronous()) {
|
||||||
state = Finished;
|
state = Finished;
|
||||||
|
@ -385,8 +385,6 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations()
|
|||||||
this, SLOT(configurationRemoved(QNetworkConfigurationPrivatePointer)));
|
this, SLOT(configurationRemoved(QNetworkConfigurationPrivatePointer)));
|
||||||
connect(engine, SIGNAL(configurationChanged(QNetworkConfigurationPrivatePointer)),
|
connect(engine, SIGNAL(configurationChanged(QNetworkConfigurationPrivatePointer)),
|
||||||
this, SLOT(configurationChanged(QNetworkConfigurationPrivatePointer)));
|
this, SLOT(configurationChanged(QNetworkConfigurationPrivatePointer)));
|
||||||
|
|
||||||
QMetaObject::invokeMethod(engine, "initialize");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,8 +408,19 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations()
|
|||||||
startPolling();
|
startPolling();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstUpdate)
|
if (firstUpdate) {
|
||||||
firstUpdate = false;
|
firstUpdate = false;
|
||||||
|
QList<QBearerEngine*> enginesToInitialize = sessionEngines; //shallow copy the list in case it is modified when we unlock mutex
|
||||||
|
Qt::ConnectionType connectionType;
|
||||||
|
if (QCoreApplicationPrivate::mainThread() == QThread::currentThread())
|
||||||
|
connectionType = Qt::DirectConnection;
|
||||||
|
else
|
||||||
|
connectionType = Qt::BlockingQueuedConnection;
|
||||||
|
locker.unlock();
|
||||||
|
foreach (QBearerEngine* engine, enginesToInitialize) {
|
||||||
|
QMetaObject::invokeMethod(engine, "initialize", connectionType);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate()
|
void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate()
|
||||||
|
@ -228,6 +228,10 @@
|
|||||||
#include "qmutex.h"
|
#include "qmutex.h"
|
||||||
#include "qurl.h"
|
#include "qurl.h"
|
||||||
|
|
||||||
|
#ifndef QT_NO_BEARERMANAGEMENT
|
||||||
|
#include <QtNetwork/QNetworkConfiguration>
|
||||||
|
#endif
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QSocks5SocketEngineHandler;
|
class QSocks5SocketEngineHandler;
|
||||||
@ -716,6 +720,9 @@ public:
|
|||||||
QUrl remote;
|
QUrl remote;
|
||||||
int localPort;
|
int localPort;
|
||||||
QNetworkProxyQuery::QueryType type;
|
QNetworkProxyQuery::QueryType type;
|
||||||
|
#ifndef QT_NO_BEARERMANAGEMENT
|
||||||
|
QNetworkConfiguration config;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> void QSharedDataPointer<QNetworkProxyQueryPrivate>::detach()
|
template<> void QSharedDataPointer<QNetworkProxyQueryPrivate>::detach()
|
||||||
@ -777,6 +784,11 @@ template<> void QSharedDataPointer<QNetworkProxyQueryPrivate>::detach()
|
|||||||
like choosing an caching HTTP proxy for HTTP-based connections,
|
like choosing an caching HTTP proxy for HTTP-based connections,
|
||||||
but a more powerful SOCKSv5 proxy for all others.
|
but a more powerful SOCKSv5 proxy for all others.
|
||||||
|
|
||||||
|
The network configuration specifies which configuration to use,
|
||||||
|
when bearer management is used. For example on a mobile phone
|
||||||
|
the proxy settings are likely to be different for the cellular
|
||||||
|
network vs WLAN.
|
||||||
|
|
||||||
Some of the criteria may not make sense in all of the types of
|
Some of the criteria may not make sense in all of the types of
|
||||||
query. The following table lists the criteria that are most
|
query. The following table lists the criteria that are most
|
||||||
commonly used, according to the type of query.
|
commonly used, according to the type of query.
|
||||||
@ -902,6 +914,68 @@ QNetworkProxyQuery::QNetworkProxyQuery(quint16 bindPort, const QString &protocol
|
|||||||
d->type = queryType;
|
d->type = queryType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_BEARERMANAGEMENT
|
||||||
|
/*!
|
||||||
|
Constructs a QNetworkProxyQuery with the URL \a requestUrl and
|
||||||
|
sets the query type to \a queryType. The specified \a networkConfiguration
|
||||||
|
is used to resolve the proxy settings.
|
||||||
|
|
||||||
|
\sa protocolTag(), peerHostName(), peerPort(), networkConfiguration()
|
||||||
|
*/
|
||||||
|
QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration,
|
||||||
|
const QUrl &requestUrl, QueryType queryType)
|
||||||
|
{
|
||||||
|
d->config = networkConfiguration;
|
||||||
|
d->remote = requestUrl;
|
||||||
|
d->type = queryType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs a QNetworkProxyQuery of type \a queryType and sets the
|
||||||
|
protocol tag to be \a protocolTag. This constructor is suitable
|
||||||
|
for QNetworkProxyQuery::TcpSocket queries, because it sets the
|
||||||
|
peer hostname to \a hostname and the peer's port number to \a
|
||||||
|
port. The specified \a networkConfiguration
|
||||||
|
is used to resolve the proxy settings.
|
||||||
|
|
||||||
|
\sa networkConfiguration()
|
||||||
|
*/
|
||||||
|
QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration,
|
||||||
|
const QString &hostname, int port,
|
||||||
|
const QString &protocolTag,
|
||||||
|
QueryType queryType)
|
||||||
|
{
|
||||||
|
d->config = networkConfiguration;
|
||||||
|
d->remote.setScheme(protocolTag);
|
||||||
|
d->remote.setHost(hostname);
|
||||||
|
d->remote.setPort(port);
|
||||||
|
d->type = queryType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs a QNetworkProxyQuery of type \a queryType and sets the
|
||||||
|
protocol tag to be \a protocolTag. This constructor is suitable
|
||||||
|
for QNetworkProxyQuery::TcpSocket queries because it sets the
|
||||||
|
local port number to \a bindPort. The specified \a networkConfiguration
|
||||||
|
is used to resolve the proxy settings.
|
||||||
|
|
||||||
|
Note that \a bindPort is of type quint16 to indicate the exact
|
||||||
|
port number that is requested. The value of -1 (unknown) is not
|
||||||
|
allowed in this context.
|
||||||
|
|
||||||
|
\sa localPort(), networkConfiguration()
|
||||||
|
*/
|
||||||
|
QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration,
|
||||||
|
quint16 bindPort, const QString &protocolTag,
|
||||||
|
QueryType queryType)
|
||||||
|
{
|
||||||
|
d->config = networkConfiguration;
|
||||||
|
d->remote.setScheme(protocolTag);
|
||||||
|
d->localPort = bindPort;
|
||||||
|
d->type = queryType;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Constructs a QNetworkProxyQuery object that is a copy of \a other.
|
Constructs a QNetworkProxyQuery object that is a copy of \a other.
|
||||||
*/
|
*/
|
||||||
@ -1116,6 +1190,30 @@ void QNetworkProxyQuery::setUrl(const QUrl &url)
|
|||||||
d->remote = url;
|
d->remote = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_BEARERMANAGEMENT
|
||||||
|
QNetworkConfiguration QNetworkProxyQuery::networkConfiguration() const
|
||||||
|
{
|
||||||
|
return d ? d->config : QNetworkConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the network configuration component of this QNetworkProxyQuery
|
||||||
|
object to be \a networkConfiguration. The network configuration can
|
||||||
|
be used to return different proxy settings based on the network in
|
||||||
|
use, for example WLAN vs cellular networks on a mobile phone.
|
||||||
|
|
||||||
|
In the case of "user choice" or "service network" configurations,
|
||||||
|
you should first start the QNetworkSession and obtain the active
|
||||||
|
configuration from its properties.
|
||||||
|
|
||||||
|
\sa networkConfiguration
|
||||||
|
*/
|
||||||
|
void QNetworkProxyQuery::setNetworkConfiguration(const QNetworkConfiguration &networkConfiguration)
|
||||||
|
{
|
||||||
|
d->config = networkConfiguration;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class QNetworkProxyFactory
|
\class QNetworkProxyFactory
|
||||||
\brief The QNetworkProxyFactory class provides fine-grained proxy selection.
|
\brief The QNetworkProxyFactory class provides fine-grained proxy selection.
|
||||||
|
@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
QT_MODULE(Network)
|
QT_MODULE(Network)
|
||||||
|
|
||||||
class QUrl;
|
class QUrl;
|
||||||
|
class QNetworkConfiguration;
|
||||||
|
|
||||||
class QNetworkProxyQueryPrivate;
|
class QNetworkProxyQueryPrivate;
|
||||||
class Q_NETWORK_EXPORT QNetworkProxyQuery
|
class Q_NETWORK_EXPORT QNetworkProxyQuery
|
||||||
@ -73,6 +74,16 @@ public:
|
|||||||
QNetworkProxyQuery(quint16 bindPort, const QString &protocolTag = QString(),
|
QNetworkProxyQuery(quint16 bindPort, const QString &protocolTag = QString(),
|
||||||
QueryType queryType = TcpServer);
|
QueryType queryType = TcpServer);
|
||||||
QNetworkProxyQuery(const QNetworkProxyQuery &other);
|
QNetworkProxyQuery(const QNetworkProxyQuery &other);
|
||||||
|
#ifndef QT_NO_BEARERMANAGEMENT
|
||||||
|
QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration,
|
||||||
|
const QUrl &requestUrl, QueryType queryType = UrlRequest);
|
||||||
|
QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration,
|
||||||
|
const QString &hostname, int port, const QString &protocolTag = QString(),
|
||||||
|
QueryType queryType = TcpSocket);
|
||||||
|
QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration,
|
||||||
|
quint16 bindPort, const QString &protocolTag = QString(),
|
||||||
|
QueryType queryType = TcpServer);
|
||||||
|
#endif
|
||||||
~QNetworkProxyQuery();
|
~QNetworkProxyQuery();
|
||||||
QNetworkProxyQuery &operator=(const QNetworkProxyQuery &other);
|
QNetworkProxyQuery &operator=(const QNetworkProxyQuery &other);
|
||||||
bool operator==(const QNetworkProxyQuery &other) const;
|
bool operator==(const QNetworkProxyQuery &other) const;
|
||||||
@ -97,6 +108,11 @@ public:
|
|||||||
QUrl url() const;
|
QUrl url() const;
|
||||||
void setUrl(const QUrl &url);
|
void setUrl(const QUrl &url);
|
||||||
|
|
||||||
|
#ifndef QT_NO_BEARERMANAGEMENT
|
||||||
|
QNetworkConfiguration networkConfiguration() const;
|
||||||
|
void setNetworkConfiguration(const QNetworkConfiguration &networkConfiguration);
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSharedDataPointer<QNetworkProxyQueryPrivate> d;
|
QSharedDataPointer<QNetworkProxyQueryPrivate> d;
|
||||||
};
|
};
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
#include <commsdattypeinfov1_1.h> // CCDIAPRecord, CCDProxiesRecord
|
#include <commsdattypeinfov1_1.h> // CCDIAPRecord, CCDProxiesRecord
|
||||||
#include <commsdattypesv1_1.h> // KCDTIdIAPRecord, KCDTIdProxiesRecord
|
#include <commsdattypesv1_1.h> // KCDTIdIAPRecord, KCDTIdProxiesRecord
|
||||||
#include <QtNetwork/QNetworkConfigurationManager>
|
#include <QtNetwork/QNetworkConfigurationManager>
|
||||||
|
#include <QtNetwork/QNetworkConfiguration>
|
||||||
#include <QFlags>
|
#include <QFlags>
|
||||||
|
|
||||||
using namespace CommsDat;
|
using namespace CommsDat;
|
||||||
@ -88,7 +89,7 @@ class SymbianProxyQuery
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static QNetworkConfiguration findCurrentConfiguration(QNetworkConfigurationManager& configurationManager);
|
static QNetworkConfiguration findCurrentConfiguration(QNetworkConfigurationManager& configurationManager);
|
||||||
static SymbianIapId getIapId(QNetworkConfigurationManager& configurationManager);
|
static SymbianIapId getIapId(QNetworkConfigurationManager &configurationManager, const QNetworkProxyQuery &query);
|
||||||
static CCDIAPRecord *getIapRecordLC(TUint32 aIAPId, CMDBSession &aDb);
|
static CCDIAPRecord *getIapRecordLC(TUint32 aIAPId, CMDBSession &aDb);
|
||||||
static CMDBRecordSet<CCDProxiesRecord> *prepareQueryLC(TUint32 serviceId, TDesC& serviceType);
|
static CMDBRecordSet<CCDProxiesRecord> *prepareQueryLC(TUint32 serviceId, TDesC& serviceType);
|
||||||
static QList<QNetworkProxy> proxyQueryL(TUint32 aIAPId, const QNetworkProxyQuery &query);
|
static QList<QNetworkProxy> proxyQueryL(TUint32 aIAPId, const QNetworkProxyQuery &query);
|
||||||
@ -137,11 +138,15 @@ QNetworkConfiguration SymbianProxyQuery::findCurrentConfiguration(QNetworkConfig
|
|||||||
return currentConfig;
|
return currentConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbianIapId SymbianProxyQuery::getIapId(QNetworkConfigurationManager& configurationManager)
|
SymbianIapId SymbianProxyQuery::getIapId(QNetworkConfigurationManager& configurationManager, const QNetworkProxyQuery &query)
|
||||||
{
|
{
|
||||||
SymbianIapId iapId;
|
SymbianIapId iapId;
|
||||||
|
|
||||||
QNetworkConfiguration currentConfig = findCurrentConfiguration(configurationManager);
|
QNetworkConfiguration currentConfig = query.networkConfiguration();
|
||||||
|
if (!currentConfig.isValid()) {
|
||||||
|
//If config is not specified, then try to find out an active or default one
|
||||||
|
currentConfig = findCurrentConfiguration(configurationManager);
|
||||||
|
}
|
||||||
if (currentConfig.isValid()) {
|
if (currentConfig.isValid()) {
|
||||||
// Note: the following code assumes that the identifier is in format
|
// Note: the following code assumes that the identifier is in format
|
||||||
// I_xxxx where xxxx is the identifier of IAP. This is meant as a
|
// I_xxxx where xxxx is the identifier of IAP. This is meant as a
|
||||||
@ -249,7 +254,7 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro
|
|||||||
SymbianIapId iapId;
|
SymbianIapId iapId;
|
||||||
TInt error;
|
TInt error;
|
||||||
QNetworkConfigurationManager manager;
|
QNetworkConfigurationManager manager;
|
||||||
iapId = SymbianProxyQuery::getIapId(manager);
|
iapId = SymbianProxyQuery::getIapId(manager, query);
|
||||||
if (iapId.isValid()) {
|
if (iapId.isValid()) {
|
||||||
TRAP(error, proxies = SymbianProxyQuery::proxyQueryL(iapId.iapId(), query))
|
TRAP(error, proxies = SymbianProxyQuery::proxyQueryL(iapId.iapId(), query))
|
||||||
if (error != KErrNone) {
|
if (error != KErrNone) {
|
||||||
|
@ -556,6 +556,10 @@ bool QAbstractSocketPrivate::initSocketLayer(QAbstractSocket::NetworkLayerProtoc
|
|||||||
q->setErrorString(QAbstractSocket::tr("Operation on socket is not supported"));
|
q->setErrorString(QAbstractSocket::tr("Operation on socket is not supported"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#ifndef QT_NO_NETWORKPROXY
|
||||||
|
//copy user agent to socket engine (if it has been set)
|
||||||
|
socketEngine->setProperty("_q_user-agent", q->property("_q_user-agent"));
|
||||||
|
#endif
|
||||||
if (!socketEngine->initialize(q->socketType(), protocol)) {
|
if (!socketEngine->initialize(q->socketType(), protocol)) {
|
||||||
#if defined (QABSTRACTSOCKET_DEBUG)
|
#if defined (QABSTRACTSOCKET_DEBUG)
|
||||||
qDebug("QAbstractSocketPrivate::initSocketLayer(%s, %s) failed (%s)",
|
qDebug("QAbstractSocketPrivate::initSocketLayer(%s, %s) failed (%s)",
|
||||||
|
@ -501,7 +501,13 @@ void QHttpSocketEngine::slotSocketConnected()
|
|||||||
data += path;
|
data += path;
|
||||||
data += " HTTP/1.1\r\n";
|
data += " HTTP/1.1\r\n";
|
||||||
data += "Proxy-Connection: keep-alive\r\n"
|
data += "Proxy-Connection: keep-alive\r\n"
|
||||||
"User-Agent: Mozilla/5.0\r\n"
|
"User-Agent: ";
|
||||||
|
QVariant v = property("_q_user-agent");
|
||||||
|
if (v.isValid())
|
||||||
|
data += v.toByteArray();
|
||||||
|
else
|
||||||
|
data += "Mozilla/5.0";
|
||||||
|
data += "\r\n"
|
||||||
"Host: " + peerAddress + "\r\n";
|
"Host: " + peerAddress + "\r\n";
|
||||||
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(d->authenticator);
|
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(d->authenticator);
|
||||||
//qDebug() << "slotSocketConnected: priv=" << priv << (priv ? (int)priv->method : -1);
|
//qDebug() << "slotSocketConnected: priv=" << priv << (priv ? (int)priv->method : -1);
|
||||||
|
@ -1540,8 +1540,13 @@ qint64 QSocks5SocketEngine::write(const char *data, qint64 len)
|
|||||||
// ### Handle this error.
|
// ### Handle this error.
|
||||||
}
|
}
|
||||||
|
|
||||||
d->data->controlSocket->write(sealedBuf);
|
qint64 written = d->data->controlSocket->write(sealedBuf);
|
||||||
|
if (written <= 0) {
|
||||||
|
QSOCKS5_Q_DEBUG << "native write returned" << written;
|
||||||
|
return written;
|
||||||
|
}
|
||||||
d->data->controlSocket->waitForBytesWritten(0);
|
d->data->controlSocket->waitForBytesWritten(0);
|
||||||
|
//NB: returning len rather than written for the OK case, because the "sealing" may increase the length
|
||||||
return len;
|
return len;
|
||||||
#ifndef QT_NO_UDPSOCKET
|
#ifndef QT_NO_UDPSOCKET
|
||||||
} else if (d->mode == QSocks5SocketEnginePrivate::UdpAssociateMode) {
|
} else if (d->mode == QSocks5SocketEnginePrivate::UdpAssociateMode) {
|
||||||
|
@ -1736,6 +1736,8 @@ void QSslSocket::connectToHostImplementation(const QString &hostName, quint16 po
|
|||||||
}
|
}
|
||||||
#ifndef QT_NO_NETWORKPROXY
|
#ifndef QT_NO_NETWORKPROXY
|
||||||
d->plainSocket->setProxy(proxy());
|
d->plainSocket->setProxy(proxy());
|
||||||
|
//copy user agent down to the plain socket (if it has been set)
|
||||||
|
d->plainSocket->setProperty("_q_user-agent", property("_q_user-agent"));
|
||||||
#endif
|
#endif
|
||||||
QIODevice::open(openMode);
|
QIODevice::open(openMode);
|
||||||
d->plainSocket->connectToHost(hostName, port, openMode);
|
d->plainSocket->connectToHost(hostName, port, openMode);
|
||||||
|
@ -62,6 +62,7 @@ public slots:
|
|||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void usedInThread(); // this test must be first, or it will falsely pass
|
||||||
void allConfigurations();
|
void allConfigurations();
|
||||||
void defaultConfiguration();
|
void defaultConfiguration();
|
||||||
void configurationFromIdentifier();
|
void configurationFromIdentifier();
|
||||||
@ -329,6 +330,47 @@ void tst_QNetworkConfigurationManager::configurationFromIdentifier()
|
|||||||
QVERIFY(!invalid.isValid());
|
QVERIFY(!invalid.isValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class QNCMTestThread : public QThread
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
virtual void run()
|
||||||
|
{
|
||||||
|
QNetworkConfigurationManager manager;
|
||||||
|
preScanConfigs = manager.allConfigurations();
|
||||||
|
QSignalSpy spy(&manager, SIGNAL(updateCompleted()));
|
||||||
|
manager.updateConfigurations(); //initiate scans
|
||||||
|
QTRY_VERIFY(spy.count() == 1); //wait for scan to complete
|
||||||
|
configs = manager.allConfigurations();
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
QList<QNetworkConfiguration> configs;
|
||||||
|
QList<QNetworkConfiguration> preScanConfigs;
|
||||||
|
};
|
||||||
|
|
||||||
|
// regression test for QTBUG-18795
|
||||||
|
void tst_QNetworkConfigurationManager::usedInThread()
|
||||||
|
{
|
||||||
|
#if defined Q_OS_MAC && !defined (QT_NO_COREWLAN)
|
||||||
|
QSKIP("QTBUG-19070 Mac CoreWlan plugin is broken", SkipAll);
|
||||||
|
#else
|
||||||
|
QNCMTestThread thread;
|
||||||
|
connect(&thread, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
|
||||||
|
thread.start();
|
||||||
|
QTestEventLoop::instance().enterLoop(100); //QTRY_VERIFY could take ~90 seconds to time out in the thread
|
||||||
|
QVERIFY(thread.isFinished());
|
||||||
|
qDebug() << "prescan:" << thread.preScanConfigs.count();
|
||||||
|
qDebug() << "postscan:" << thread.configs.count();
|
||||||
|
|
||||||
|
QNetworkConfigurationManager manager;
|
||||||
|
QList<QNetworkConfiguration> preScanConfigs = manager.allConfigurations();
|
||||||
|
QSignalSpy spy(&manager, SIGNAL(updateCompleted()));
|
||||||
|
manager.updateConfigurations(); //initiate scans
|
||||||
|
QTRY_VERIFY(spy.count() == 1); //wait for scan to complete
|
||||||
|
QList<QNetworkConfiguration> configs = manager.allConfigurations();
|
||||||
|
QCOMPARE(thread.configs, configs);
|
||||||
|
QCOMPARE(thread.preScanConfigs, preScanConfigs);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QNetworkConfigurationManager)
|
QTEST_MAIN(tst_QNetworkConfigurationManager)
|
||||||
#include "tst_qnetworkconfigurationmanager.moc"
|
#include "tst_qnetworkconfigurationmanager.moc"
|
||||||
|
@ -7,5 +7,5 @@ QT = core network
|
|||||||
|
|
||||||
SOURCES += tst_qnetworkproxyfactory.cpp
|
SOURCES += tst_qnetworkproxyfactory.cpp
|
||||||
|
|
||||||
symbian: TARGET.CAPABILITY = NetworkServices
|
symbian: TARGET.CAPABILITY = NetworkServices ReadUserData
|
||||||
|
|
||||||
|
@ -41,20 +41,64 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <QtTest/QTest>
|
#include <QtTest/QTest>
|
||||||
|
#include <QtTest/QTestEventLoop>
|
||||||
|
|
||||||
#include <qcoreapplication.h>
|
#include <qcoreapplication.h>
|
||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
#include <qnetworkproxy.h>
|
#include <qnetworkproxy.h>
|
||||||
|
|
||||||
|
#include <QNetworkConfiguration>
|
||||||
|
#include <QNetworkConfigurationManager>
|
||||||
|
#include <QNetworkSession>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QNetworkConfiguration);
|
||||||
|
Q_DECLARE_METATYPE(QList<QNetworkProxy>);
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
class tst_QNetworkProxyFactory : public QObject {
|
class tst_QNetworkProxyFactory : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
tst_QNetworkProxyFactory();
|
||||||
|
|
||||||
|
class QDebugProxyFactory : public QNetworkProxyFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query = QNetworkProxyQuery())
|
||||||
|
{
|
||||||
|
returnedList = QNetworkProxyFactory::systemProxyForQuery(query);
|
||||||
|
requestCounter++;
|
||||||
|
return returnedList;
|
||||||
|
}
|
||||||
|
QList<QNetworkProxy> returnedList;
|
||||||
|
int requestCounter;
|
||||||
|
};
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void systemProxyForQueryCalledFromThread();
|
||||||
void systemProxyForQuery() const;
|
void systemProxyForQuery() const;
|
||||||
|
#ifndef QT_NO_BEARERMANAGEMENT
|
||||||
|
void fromConfigurations();
|
||||||
|
void inNetworkAccessManager_data();
|
||||||
|
void inNetworkAccessManager();
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString formatProxyName(const QNetworkProxy & proxy) const;
|
QString formatProxyName(const QNetworkProxy & proxy) const;
|
||||||
|
QDebugProxyFactory *factory;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
tst_QNetworkProxyFactory::tst_QNetworkProxyFactory()
|
||||||
|
{
|
||||||
|
factory = new QDebugProxyFactory;
|
||||||
|
QNetworkProxyFactory::setApplicationProxyFactory(factory);
|
||||||
|
}
|
||||||
|
|
||||||
QString tst_QNetworkProxyFactory::formatProxyName(const QNetworkProxy & proxy) const
|
QString tst_QNetworkProxyFactory::formatProxyName(const QNetworkProxy & proxy) const
|
||||||
{
|
{
|
||||||
QString proxyName;
|
QString proxyName;
|
||||||
@ -96,5 +140,136 @@ void tst_QNetworkProxyFactory::systemProxyForQuery() const
|
|||||||
QFAIL("One or more system proxy lookup failures occurred.");
|
QFAIL("One or more system proxy lookup failures occurred.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_BEARERMANAGEMENT
|
||||||
|
|
||||||
|
//Purpose of this test is just to check systemProxyForQuery doesn't hang or crash
|
||||||
|
//with any given configuration including no configuration.
|
||||||
|
//We can't test it returns the right proxies without implementing the native proxy code
|
||||||
|
//again here, which would be testing our implementation against itself.
|
||||||
|
//Therefore it's just testing that something valid is returned (at least a NoProxy entry)
|
||||||
|
void tst_QNetworkProxyFactory::fromConfigurations()
|
||||||
|
{
|
||||||
|
QNetworkConfigurationManager manager;
|
||||||
|
QList<QNetworkProxy> proxies;
|
||||||
|
QUrl url(QLatin1String("http://qt.nokia.com"));
|
||||||
|
//get from known configurations
|
||||||
|
foreach (QNetworkConfiguration config, manager.allConfigurations()) {
|
||||||
|
QNetworkProxyQuery query(config, url, QNetworkProxyQuery::UrlRequest);
|
||||||
|
proxies = QNetworkProxyFactory::systemProxyForQuery(query);
|
||||||
|
QVERIFY(!proxies.isEmpty());
|
||||||
|
foreach (QNetworkProxy proxy, proxies) {
|
||||||
|
qDebug() << config.name() << " - " << config.identifier() << " - " << formatProxyName(proxy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//get from default configuration
|
||||||
|
QNetworkProxyQuery defaultquery(url, QNetworkProxyQuery::UrlRequest);
|
||||||
|
proxies = QNetworkProxyFactory::systemProxyForQuery(defaultquery);
|
||||||
|
QVERIFY(!proxies.isEmpty());
|
||||||
|
foreach (QNetworkProxy proxy, proxies) {
|
||||||
|
qDebug() << "default - " << formatProxyName(proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
//get from active configuration
|
||||||
|
QNetworkSession session(manager.defaultConfiguration());
|
||||||
|
session.open();
|
||||||
|
QVERIFY(session.waitForOpened(30000));
|
||||||
|
proxies = QNetworkProxyFactory::systemProxyForQuery(defaultquery);
|
||||||
|
QVERIFY(!proxies.isEmpty());
|
||||||
|
foreach (QNetworkProxy proxy, proxies) {
|
||||||
|
qDebug() << "active - " << formatProxyName(proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
//get from known configurations while there is one active
|
||||||
|
foreach (QNetworkConfiguration config, manager.allConfigurations()) {
|
||||||
|
QNetworkProxyQuery query(config, url, QNetworkProxyQuery::UrlRequest);
|
||||||
|
proxies = QNetworkProxyFactory::systemProxyForQuery(query);
|
||||||
|
QVERIFY(!proxies.isEmpty());
|
||||||
|
foreach (QNetworkProxy proxy, proxies) {
|
||||||
|
qDebug() << config.name() << " - " << config.identifier() << " - " << formatProxyName(proxy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QNetworkProxyFactory::inNetworkAccessManager_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QNetworkConfiguration>("config");
|
||||||
|
QTest::addColumn<QList<QNetworkProxy> >("proxies");
|
||||||
|
QNetworkConfigurationManager manager;
|
||||||
|
//get from known configurations
|
||||||
|
foreach (QNetworkConfiguration config, manager.allConfigurations()) {
|
||||||
|
QNetworkProxyQuery query(config, QUrl(QString("http://qt.nokia.com")), QNetworkProxyQuery::UrlRequest);
|
||||||
|
QList<QNetworkProxy> proxies = QNetworkProxyFactory::systemProxyForQuery(query);
|
||||||
|
QTest::newRow(config.name().toUtf8()) << config << proxies;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Purpose of this test is to check that QNetworkAccessManager uses the proxy from the configuration it
|
||||||
|
//has been given. Needs two or more working configurations to be a good test.
|
||||||
|
void tst_QNetworkProxyFactory::inNetworkAccessManager()
|
||||||
|
{
|
||||||
|
QFETCH(QNetworkConfiguration, config);
|
||||||
|
QFETCH(QList<QNetworkProxy>, proxies);
|
||||||
|
|
||||||
|
int count = factory->requestCounter;
|
||||||
|
|
||||||
|
QNetworkAccessManager manager;
|
||||||
|
manager.setConfiguration(config);
|
||||||
|
|
||||||
|
//using an internet server, because cellular APs won't have a route to the test server.
|
||||||
|
QNetworkRequest req(QUrl(QString("http://qt.nokia.com")));
|
||||||
|
QNetworkReply *reply = manager.get(req);
|
||||||
|
connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
|
||||||
|
QTestEventLoop::instance().enterLoop(30);
|
||||||
|
delete reply;
|
||||||
|
|
||||||
|
if (count == factory->requestCounter) {
|
||||||
|
//RND phones are preconfigured with several test access points which won't work without a matching SIM
|
||||||
|
//If the network fails to start, QNAM won't ask the factory for proxies so we can't test.
|
||||||
|
QSKIP("network configuration didn't start", SkipSingle);
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "testing network configuration for" << config.name();
|
||||||
|
foreach (QNetworkProxy proxy, factory->returnedList) {
|
||||||
|
qDebug() << formatProxyName(proxy);
|
||||||
|
}
|
||||||
|
qDebug() << " <vs> ";
|
||||||
|
foreach (QNetworkProxy proxy, proxies) {
|
||||||
|
qDebug() << formatProxyName(proxy);
|
||||||
|
}
|
||||||
|
if (config.type() != QNetworkConfiguration::InternetAccessPoint)
|
||||||
|
QEXPECT_FAIL("","QNetworkProxyFactory::systemProxyForQuery doesn't work for service networks yet", Continue);
|
||||||
|
QCOMPARE(factory->returnedList, proxies);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //QT_NO_BEARERMANAGEMENT
|
||||||
|
|
||||||
|
|
||||||
|
class QSPFQThread : public QThread
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
virtual void run()
|
||||||
|
{
|
||||||
|
proxies = QNetworkProxyFactory::systemProxyForQuery(query);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
QNetworkProxyQuery query;
|
||||||
|
QList<QNetworkProxy> proxies;
|
||||||
|
};
|
||||||
|
|
||||||
|
//regression test for QTBUG-18799
|
||||||
|
void tst_QNetworkProxyFactory::systemProxyForQueryCalledFromThread()
|
||||||
|
{
|
||||||
|
QUrl url(QLatin1String("http://qt.nokia.com"));
|
||||||
|
QNetworkProxyQuery query(url);
|
||||||
|
QSPFQThread thread;
|
||||||
|
thread.query = query;
|
||||||
|
connect(&thread, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
|
||||||
|
thread.start();
|
||||||
|
QTestEventLoop::instance().enterLoop(5);
|
||||||
|
QVERIFY(thread.isFinished());
|
||||||
|
QCOMPARE(thread.proxies, QNetworkProxyFactory::systemProxyForQuery(query));
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QNetworkProxyFactory)
|
QTEST_MAIN(tst_QNetworkProxyFactory)
|
||||||
#include "tst_qnetworkproxyfactory.moc"
|
#include "tst_qnetworkproxyfactory.moc"
|
||||||
|
@ -4970,17 +4970,24 @@ void tst_QNetworkReply::httpProxyCommands()
|
|||||||
QNetworkProxy proxy(QNetworkProxy::HttpProxy, "127.0.0.1", proxyServer.serverPort());
|
QNetworkProxy proxy(QNetworkProxy::HttpProxy, "127.0.0.1", proxyServer.serverPort());
|
||||||
|
|
||||||
manager.setProxy(proxy);
|
manager.setProxy(proxy);
|
||||||
QNetworkReplyPtr reply = manager.get(QNetworkRequest(url));
|
QNetworkRequest request(url);
|
||||||
manager.setProxy(QNetworkProxy());
|
request.setRawHeader("User-Agent", "QNetworkReplyAutoTest/1.0");
|
||||||
|
QNetworkReplyPtr reply = manager.get(request);
|
||||||
|
//clearing the proxy here causes the test to fail.
|
||||||
|
//the proxy isn't used until after the bearer has been started
|
||||||
|
//which is correct in general, because system proxy isn't known until that time.
|
||||||
|
//removing this line is safe, as the proxy is also reset by the cleanup() function
|
||||||
|
//manager.setProxy(QNetworkProxy());
|
||||||
|
|
||||||
// wait for the finished signal
|
// wait for the finished signal
|
||||||
connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
|
connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
|
||||||
|
|
||||||
QTestEventLoop::instance().enterLoop(1);
|
QTestEventLoop::instance().enterLoop(15);
|
||||||
|
|
||||||
QVERIFY(!QTestEventLoop::instance().timeout());
|
QVERIFY(!QTestEventLoop::instance().timeout());
|
||||||
|
|
||||||
//qDebug() << reply->error() << reply->errorString();
|
//qDebug() << reply->error() << reply->errorString();
|
||||||
|
//qDebug() << proxyServer.receivedData;
|
||||||
|
|
||||||
// we don't really care if the request succeeded
|
// we don't really care if the request succeeded
|
||||||
// especially since it won't succeed in the HTTPS case
|
// especially since it won't succeed in the HTTPS case
|
||||||
@ -4988,6 +4995,12 @@ void tst_QNetworkReply::httpProxyCommands()
|
|||||||
|
|
||||||
QString receivedHeader = proxyServer.receivedData.left(expectedCommand.length());
|
QString receivedHeader = proxyServer.receivedData.left(expectedCommand.length());
|
||||||
QCOMPARE(receivedHeader, expectedCommand);
|
QCOMPARE(receivedHeader, expectedCommand);
|
||||||
|
|
||||||
|
//QTBUG-17223 - make sure the user agent from the request is sent to proxy server even for CONNECT
|
||||||
|
int uapos = proxyServer.receivedData.indexOf("User-Agent");
|
||||||
|
int uaend = proxyServer.receivedData.indexOf("\r\n", uapos);
|
||||||
|
QByteArray uaheader = proxyServer.receivedData.mid(uapos, uaend - uapos);
|
||||||
|
QCOMPARE(uaheader, QByteArray("User-Agent: QNetworkReplyAutoTest/1.0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProxyChangeHelper : public QObject {
|
class ProxyChangeHelper : public QObject {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user