summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@accenture.com>2011-05-04 16:27:36 (GMT)
committerShane Kearns <shane.kearns@accenture.com>2011-05-05 13:01:24 (GMT)
commitcffec6c4fc1aed32ec9b3d9dd1f97105005385dc (patch)
tree5ccc8214e5674963e073084196141d65072886c5
parente8fc93973a41f193665baa5fdc26cba951bd692f (diff)
downloadQt-cffec6c4fc1aed32ec9b3d9dd1f97105005385dc.zip
Qt-cffec6c4fc1aed32ec9b3d9dd1f97105005385dc.tar.gz
Qt-cffec6c4fc1aed32ec9b3d9dd1f97105005385dc.tar.bz2
Send User-Agent from the network request in http proxy CONNECT command
Some proxies can discriminate based on the User-Agent when sent a CONNECT command for establishing a HTTPS connection. With this change, if the User-Agent header is set in the QNetworkRequest then it will be passed to the http socket engine for use in the connect command sent to the proxy. As before, "Mozilla/5.0" will be used by default when no user agent has been set. Task-number: QTBUG-17223 Reviewed-by: Markus Goetz
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp6
-rw-r--r--src/network/socket/qabstractsocket.cpp4
-rw-r--r--src/network/socket/qhttpsocketengine.cpp8
-rw-r--r--src/network/ssl/qsslsocket.cpp2
-rw-r--r--tests/auto/qnetworkreply/tst_qnetworkreply.cpp10
5 files changed, 28 insertions, 2 deletions
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 700b455..bf2fa8f 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -557,6 +557,12 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
connectHost = connection->d_func()->networkProxy.hostName();
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 = request.headerField("user-agent");
+ if (!value.isEmpty())
+ socket->setProperty("_q_user-agent", value);
+ }
#endif
if (connection->d_func()->encrypt) {
#ifndef QT_NO_OPENSSL
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index f927ae2..0dc08d9 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -549,6 +549,10 @@ bool QAbstractSocketPrivate::initSocketLayer(QAbstractSocket::NetworkLayerProtoc
q->setErrorString(QAbstractSocket::tr("Operation on socket is not supported"));
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 defined (QABSTRACTSOCKET_DEBUG)
qDebug("QAbstractSocketPrivate::initSocketLayer(%s, %s) failed (%s)",
diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp
index a338d97..cebff34 100644
--- a/src/network/socket/qhttpsocketengine.cpp
+++ b/src/network/socket/qhttpsocketengine.cpp
@@ -467,7 +467,13 @@ void QHttpSocketEngine::slotSocketConnected()
data += path;
data += " HTTP/1.1\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";
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(d->authenticator);
//qDebug() << "slotSocketConnected: priv=" << priv << (priv ? (int)priv->method : -1);
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 4252123..cf95adf 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1698,6 +1698,8 @@ void QSslSocket::connectToHostImplementation(const QString &hostName, quint16 po
}
#ifndef QT_NO_NETWORKPROXY
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
QIODevice::open(openMode);
d->plainSocket->connectToHost(hostName, port, openMode);
diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
index 81278b6..27c5713 100644
--- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
@@ -4537,7 +4537,9 @@ void tst_QNetworkReply::httpProxyCommands()
QNetworkProxy proxy(QNetworkProxy::HttpProxy, "127.0.0.1", proxyServer.serverPort());
manager.setProxy(proxy);
- QNetworkReplyPtr reply = manager.get(QNetworkRequest(url));
+ QNetworkRequest request(url);
+ request.setRawHeader("User-Agent", "QNetworkReplyAutoTest/1.0");
+ QNetworkReplyPtr reply = manager.get(request);
manager.setProxy(QNetworkProxy());
// wait for the finished signal
@@ -4555,6 +4557,12 @@ void tst_QNetworkReply::httpProxyCommands()
QString receivedHeader = proxyServer.receivedData.left(expectedCommand.length());
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 {