Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qnetworkproxy.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
189#include "qnetworkproxy.h"
190
191#ifndef QT_NO_NETWORKPROXY
192
193#include "private/qnetworkrequest_p.h"
194#if QT_CONFIG(socks5)
195#include "private/qsocks5socketengine_p.h"
196#endif
197
198#if QT_CONFIG(http)
199#include "private/qhttpsocketengine_p.h"
200#endif
201
202#include "qauthenticator.h"
203#include "qdebug.h"
204#include "qmutex.h"
205#include "qstringlist.h"
206#include "qurl.h"
207
209
210using namespace Qt::StringLiterals;
211
213
216
218{
219public:
221 : applicationLevelProxy(nullptr)
222 , applicationLevelProxyFactory(nullptr)
223#if QT_CONFIG(socks5)
224 , socks5SocketEngineHandler(nullptr)
225#endif
226#if QT_CONFIG(http)
227 , httpSocketEngineHandler(nullptr)
228#endif
229#ifdef QT_USE_SYSTEM_PROXIES
230 , useSystemProxies(true)
231#else
232 , useSystemProxies(false)
233#endif
234 {
235#if QT_CONFIG(socks5)
236 socks5SocketEngineHandler = new QSocks5SocketEngineHandler();
237#endif
238#if QT_CONFIG(http)
239 httpSocketEngineHandler = new QHttpSocketEngineHandler();
240#endif
241 }
242
244 {
245 delete applicationLevelProxy;
246 delete applicationLevelProxyFactory;
247#if QT_CONFIG(socks5)
248 delete socks5SocketEngineHandler;
249#endif
250#if QT_CONFIG(http)
251 delete httpSocketEngineHandler;
252#endif
253 }
254
256 {
257 return useSystemProxies;
258 }
259
261 {
262 QMutexLocker lock(&mutex);
263 useSystemProxies = enable;
264
265 if (useSystemProxies) {
266 if (applicationLevelProxy)
267 *applicationLevelProxy = QNetworkProxy();
268 delete applicationLevelProxyFactory;
269 applicationLevelProxyFactory = nullptr;
270 }
271 }
272
274 {
275 QMutexLocker lock(&mutex);
276 if (!applicationLevelProxy)
277 applicationLevelProxy = new QNetworkProxy;
278 *applicationLevelProxy = proxy;
279 delete applicationLevelProxyFactory;
280 applicationLevelProxyFactory = nullptr;
281 useSystemProxies = false;
282 }
283
285 {
286 QMutexLocker lock(&mutex);
287 if (factory == applicationLevelProxyFactory)
288 return;
289 if (applicationLevelProxy)
290 *applicationLevelProxy = QNetworkProxy();
291 delete applicationLevelProxyFactory;
292 applicationLevelProxyFactory = factory;
293 useSystemProxies = false;
294 }
295
300
301 QList<QNetworkProxy> proxyForQuery(const QNetworkProxyQuery &query);
302
303private:
304 QRecursiveMutex mutex;
305 QNetworkProxy *applicationLevelProxy;
306 QNetworkProxyFactory *applicationLevelProxyFactory;
307#if QT_CONFIG(socks5)
308 QSocks5SocketEngineHandler *socks5SocketEngineHandler;
309#endif
310#if QT_CONFIG(http)
311 QHttpSocketEngineHandler *httpSocketEngineHandler;
312#endif
313 bool useSystemProxies;
314};
315
317{
318 QMutexLocker locker(&mutex);
319
320 QList<QNetworkProxy> result;
321
322 // don't look for proxies for a local connection
323 QHostAddress parsed;
324 QString hostname = query.url().host();
325 if (hostname == "localhost"_L1 || hostname.startsWith("localhost."_L1)
326 || (parsed.setAddress(hostname) && (parsed.isLoopback()))) {
328 return result;
329 }
330
331 if (!applicationLevelProxyFactory) {
332 if (applicationLevelProxy
333 && applicationLevelProxy->type() != QNetworkProxy::DefaultProxy) {
334 result << *applicationLevelProxy;
335 } else if (useSystemProxies) {
337
338 // Make sure NoProxy is in the list, so that QTcpServer can work:
339 // it searches for the first proxy that can has the ListeningCapability capability
340 // if none have (as is the case with HTTP proxies), it fails to bind.
341 // NoProxy allows it to fallback to the 'no proxy' case and bind.
343 } else {
345 }
346 return result;
347 }
348
349 // we have a factory
350 result = applicationLevelProxyFactory->queryProxy(query);
351 if (result.isEmpty()) {
352 qWarning("QNetworkProxyFactory: factory %p has returned an empty result set",
353 applicationLevelProxyFactory);
355 }
356 return result;
357}
358
359Q_GLOBAL_STATIC(QGlobalNetworkProxy, globalNetworkProxy)
360
361namespace {
362 template<bool> struct StaticAssertTest;
363 template<> struct StaticAssertTest<true> { enum { Value = 1 }; };
364}
365
366static inline void qt_noop_with_arg(int) {}
367#define q_static_assert(expr) qt_noop_with_arg(sizeof(StaticAssertTest< expr >::Value))
368
370{
373 static const int defaults[] =
374 {
375 /* [QNetworkProxy::DefaultProxy] = */
381 /* [QNetworkProxy::Socks5Proxy] = */
386 // it's weird to talk about the proxy capabilities of a "not proxy"...
387 /* [QNetworkProxy::NoProxy] = */
393 /* [QNetworkProxy::HttpProxy] = */
397 /* [QNetworkProxy::HttpCachingProxy] = */
400 /* [QNetworkProxy::FtpCachingProxy] = */
403 };
404
405 if (int(type) < 0 || int(type) > int(QNetworkProxy::FtpCachingProxy))
407 return QNetworkProxy::Capabilities(defaults[int(type)]);
408}
409
411{
412public:
416 QNetworkProxy::Capabilities capabilities;
421
423 const QString &h = QString(), quint16 p = 0,
424 const QString &u = QString(), const QString &pw = QString())
425 : hostName(h),
426 user(u),
427 password(pw),
429 port(p),
430 type(t),
432 { }
433
434 inline bool operator==(const QNetworkProxyPrivate &other) const
435 {
436 return type == other.type &&
437 port == other.port &&
438 hostName == other.hostName &&
439 user == other.user &&
440 password == other.password &&
441 capabilities == other.capabilities;
442 }
443};
444
446{
447 if (d && d->ref.loadRelaxed() == 1)
448 return;
451 x->ref.ref();
452 if (d && !d->ref.deref())
453 delete d;
454 d = x;
455}
456
466 : d(nullptr)
467{
468 // make sure we have QGlobalNetworkProxy singleton created, otherwise
469 // you don't have any socket engine handler created when directly setting
470 // a proxy to a socket
471 globalNetworkProxy();
472}
473
483 const QString &user, const QString &password)
484 : d(new QNetworkProxyPrivate(type, hostName, port, user, password))
485{
486 // make sure we have QGlobalNetworkProxy singleton created, otherwise
487 // you don't have any socket engine handler created when directly setting
488 // a proxy to a socket
489 globalNetworkProxy();
490}
491
499
504{
505 // QSharedDataPointer takes care of deleting for us
506}
507
515{
516 return d == other.d || (d && other.d && *d == *other.d);
517}
518
533{
534 d = other.d;
535 return *this;
536}
537
561
568{
569 return d ? d->type : DefaultProxy;
570}
571
579void QNetworkProxy::setCapabilities(Capabilities capabilities)
580{
582 d->capabilitiesSet = true;
583}
584
592QNetworkProxy::Capabilities QNetworkProxy::capabilities() const
593{
595}
596
610{
612}
613
631
638{
639 d->user = user;
640}
641
648{
649 return d ? d->user : QString();
650}
651
658{
659 d->password = password;
660}
661
668{
669 return d ? d->password : QString();
670}
671
678{
679 d->hostName = hostName;
680}
681
688{
689 return d ? d->hostName : QString();
690}
691
698{
699 d->port = port;
700}
701
708{
709 return d ? d->port : 0;
710}
711
728{
729 if (globalNetworkProxy()) {
730 // don't accept setting the proxy to DefaultProxy
731 if (networkProxy.type() == DefaultProxy)
732 globalNetworkProxy()->setApplicationProxy(QNetworkProxy::NoProxy);
733 else
734 globalNetworkProxy()->setApplicationProxy(networkProxy);
735 }
736}
737
748{
749 if (globalNetworkProxy())
750 return globalNetworkProxy()->applicationProxy();
751 return QNetworkProxy();
752}
753
765{
766 if (d->type != HttpProxy && d->type != HttpCachingProxy)
767 return {};
768 return d->headers.headers();
769}
770
786{
787 if (d->type == HttpProxy || d->type == HttpCachingProxy)
788 d->headers.setHeaders(std::move(newHeaders));
789}
790
796{
797 if (d->type == HttpProxy || d->type == HttpCachingProxy)
798 d->headers.setHeaders(newHeaders);
799}
800
815
832
841bool QNetworkProxy::hasRawHeader(const QByteArray &headerName) const
842{
843 if (d->type != HttpProxy && d->type != HttpCachingProxy)
844 return false;
845 return d->headers.headers().contains(headerName);
846}
847
861{
862 if (d->type != HttpProxy && d->type != HttpCachingProxy)
863 return QByteArray();
864 return d->headers.rawHeader(headerName);
865}
866
877QList<QByteArray> QNetworkProxy::rawHeaderList() const
878{
879 if (d->type != HttpProxy && d->type != HttpCachingProxy)
880 return QList<QByteArray>();
881 return d->headers.rawHeadersKeys();
882}
883
908{
909 if (d->type == HttpProxy || d->type == HttpCachingProxy)
910 d->headers.setRawHeader(headerName, headerValue);
911}
912
914{
915public:
917 : localPort(-1), type(QNetworkProxyQuery::TcpSocket)
918 { }
919
921 {
922 return type == other.type &&
923 localPort == other.localPort &&
924 remote == other.remote;
925 }
926
930};
931
933{
934 if (d && d->ref.loadRelaxed() == 1)
935 return;
938 x->ref.ref();
939 if (d && !d->ref.deref())
940 delete d;
941 d = x;
942}
943
1086
1094{
1095 d->remote = requestUrl;
1096 d->type = queryType;
1097}
1098
1107 const QString &protocolTag,
1108 QueryType queryType)
1109{
1110 d->remote.setScheme(protocolTag);
1111 d->remote.setHost(hostname);
1112 d->remote.setPort(port);
1113 d->type = queryType;
1114}
1115
1129 QueryType queryType)
1130{
1131 d->remote.setScheme(protocolTag);
1132 d->localPort = bindPort;
1133 d->type = queryType;
1134}
1135
1143
1148{
1149 // QSharedDataPointer automatically deletes
1150}
1151
1156{
1157 d = other.d;
1158 return *this;
1159}
1160
1174{
1175 return d == other.d || (d && other.d && *d == *other.d);
1176}
1177
1192
1200
1212{
1213 return d ? d->remote.port() : -1;
1214}
1215
1232
1244{
1245 return d ? d->remote.host() : QString();
1246}
1247
1261{
1262 d->remote.setHost(hostname);
1263}
1264
1272{
1273 return d ? d->localPort : -1;
1274}
1275
1295{
1296 d->localPort = port;
1297}
1298
1310{
1311 return d ? d->remote.scheme() : QString();
1312}
1313
1329{
1331}
1332
1340{
1341 return d ? d->remote : QUrl();
1342}
1343
1354{
1355 d->remote = url;
1356}
1357
1407
1414
1421{
1422 if (globalNetworkProxy())
1423 return globalNetworkProxy()->usesSystemConfiguration();
1424 return false;
1425}
1426
1440{
1441 if (globalNetworkProxy())
1442 globalNetworkProxy()->setUseSystemConfiguration(enable);
1443}
1444
1464{
1465 if (globalNetworkProxy())
1466 globalNetworkProxy()->setApplicationProxyFactory(factory);
1467}
1468
1547{
1548 if (!globalNetworkProxy())
1549 return QList<QNetworkProxy>() << QNetworkProxy(QNetworkProxy::NoProxy);
1550 return globalNetworkProxy()->proxyForQuery(query);
1551}
1552
1553#ifndef QT_NO_DEBUG_STREAM
1555{
1556 QDebugStateSaver saver(debug);
1557 debug.resetFormat().nospace();
1559 switch (type) {
1561 debug << "NoProxy ";
1562 break;
1564 debug << "DefaultProxy ";
1565 break;
1567 debug << "Socks5Proxy ";
1568 break;
1570 debug << "HttpProxy ";
1571 break;
1573 debug << "HttpCachingProxy ";
1574 break;
1576 debug << "FtpCachingProxy ";
1577 break;
1578 default:
1579 debug << "Unknown proxy " << int(type);
1580 break;
1581 }
1582 debug << '"' << proxy.hostName() << ':' << proxy.port() << "\" ";
1583 QNetworkProxy::Capabilities caps = proxy.capabilities();
1584 QStringList scaps;
1586 scaps << QStringLiteral("Tunnel");
1588 scaps << QStringLiteral("Listen");
1590 scaps << QStringLiteral("UDP");
1592 scaps << QStringLiteral("Caching");
1594 scaps << QStringLiteral("NameLookup");
1596 scaps << QStringLiteral("SctpTunnel");
1598 scaps << QStringLiteral("SctpListen");
1599 debug << '[' << scaps.join(u' ') << ']';
1600 return debug;
1601}
1602
1604{
1605 QDebugStateSaver saver(debug);
1606 debug.resetFormat().nospace()
1607 << "ProxyQuery("
1608 << "type: " << proxyQuery.queryType()
1609 << ", protocol: " << proxyQuery.protocolTag()
1610 << ", peerPort: " << proxyQuery.peerPort()
1611 << ", peerHostName: " << proxyQuery.peerHostName()
1612 << ", localPort: " << proxyQuery.localPort()
1613 << ", url: " << proxyQuery.url()
1614 << ')';
1615 return debug;
1616}
1617#endif
1618
1620
1621#include "moc_qnetworkproxy.cpp"
1622
1623#endif // QT_NO_NETWORKPROXY
bool ref() noexcept
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
\inmodule QtCore
bool usesSystemConfiguration() const
QList< QNetworkProxy > proxyForQuery(const QNetworkProxyQuery &query)
void setUseSystemConfiguration(bool enable)
void setApplicationProxyFactory(QNetworkProxyFactory *factory)
void setApplicationProxy(const QNetworkProxy &proxy)
QNetworkProxy applicationProxy()
T value(const Key &key) const noexcept
Definition qhash.h:1054
The QHostAddress class provides an IP address.
bool isLoopback() const
void setAddress(quint32 ip4Addr)
Set the IPv4 address specified by ip4Addr.
Q_NETWORK_EXPORT bool contains(QAnyStringView name) const
Returns whether the headers contain header with name.
const T & constFirst() const noexcept
Definition qlist.h:647
\inmodule QtCore
Definition qmutex.h:313
QByteArray rawHeader(QAnyStringView headerName) const
void setCookedHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
QList< QByteArray > rawHeadersKeys() const
QHttpHeaders headers() const
void setHeaders(const QHttpHeaders &newHeaders)
void setRawHeader(const QByteArray &key, const QByteArray &value)
CookedHeadersMap cookedHeaders
The QNetworkProxyFactory class provides fine-grained proxy selection.
static bool usesSystemConfiguration()
virtual QList< QNetworkProxy > queryProxy(const QNetworkProxyQuery &query=QNetworkProxyQuery())=0
This function takes the query request, query, examines the details of the type of socket or request a...
static void setUseSystemConfiguration(bool enable)
static QList< QNetworkProxy > systemProxyForQuery(const QNetworkProxyQuery &query=QNetworkProxyQuery())
This function takes the query request, query, examines the details of the type of socket or request a...
static void setApplicationProxyFactory(QNetworkProxyFactory *factory)
Sets the application-wide proxy factory to be factory.
static QList< QNetworkProxy > proxyForQuery(const QNetworkProxyQuery &query)
This function takes the query request, query, examines the details of the type of socket or request a...
QNetworkProxyFactory()
Creates a QNetworkProxyFactory object.
virtual ~QNetworkProxyFactory()
Destroys the QNetworkProxyFactory object.
QNetworkProxyPrivate(QNetworkProxy::ProxyType t=QNetworkProxy::DefaultProxy, const QString &h=QString(), quint16 p=0, const QString &u=QString(), const QString &pw=QString())
bool operator==(const QNetworkProxyPrivate &other) const
QNetworkProxy::ProxyType type
QNetworkProxy::Capabilities capabilities
QNetworkHeadersPrivate headers
QNetworkProxyQuery::QueryType type
bool operator==(const QNetworkProxyQueryPrivate &other) const
The QNetworkProxyQuery class is used to query the proxy settings for a socket.
void setPeerPort(int port)
Sets the requested port number for the outgoing connection to be port.
QueryType
Describes the type of one QNetworkProxyQuery query.
int peerPort() const
Returns the port number for the outgoing request or -1 if the port number is not known.
int localPort() const
Returns the port number of the socket that will accept incoming packets from remote servers or -1 if ...
~QNetworkProxyQuery()
Destroys this QNetworkProxyQuery object.
void setUrl(const QUrl &url)
Sets the URL component of this QNetworkProxyQuery object to be url.
QString peerHostName() const
Returns the host name or IP address being of the outgoing connection being requested,...
QueryType queryType() const
Returns the query type.
void setPeerHostName(const QString &hostname)
Sets the hostname of the outgoing connection being requested to hostname.
void setQueryType(QueryType type)
Sets the query type of this object to be type.
QNetworkProxyQuery & operator=(QNetworkProxyQuery &&other) noexcept
QNetworkProxyQuery()
Constructs a default QNetworkProxyQuery object.
QString protocolTag() const
Returns the protocol tag for this QNetworkProxyQuery object, or an empty QString in case the protocol...
void setLocalPort(int port)
Sets the port number that the socket wishes to use locally to accept incoming packets from remote ser...
bool operator==(const QNetworkProxyQuery &other) const
Returns true if this QNetworkProxyQuery object contains the same data as other.
QUrl url() const
Returns the URL component of this QNetworkProxyQuery object in case of a query of type QNetworkProxyQ...
void setProtocolTag(const QString &protocolTag)
Sets the protocol tag for this QNetworkProxyQuery object to be protocolTag.
The QNetworkProxy class provides a network layer proxy.
QVariant header(QNetworkRequest::KnownHeaders header) const
static QNetworkProxy applicationProxy()
Returns the application level network proxying.
ProxyType
This enum describes the types of network proxying provided in Qt.
bool isCachingProxy() const
QString user() const
Returns the user name used for authentication.
QNetworkProxy()
Constructs a QNetworkProxy with DefaultProxy type.
void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
void setHostName(const QString &hostName)
Sets the host name of the proxy host to be hostName.
void setRawHeader(const QByteArray &headerName, const QByteArray &value)
void setCapabilities(Capabilities capab)
void setUser(const QString &userName)
Sets the user name for proxy authentication to be user.
QNetworkProxy & operator=(QNetworkProxy &&other) noexcept
bool operator==(const QNetworkProxy &other) const
Capabilities capabilities() const
~QNetworkProxy()
Destroys the QNetworkProxy object.
QByteArray rawHeader(const QByteArray &headerName) const
bool isTransparentProxy() const
QNetworkProxy::ProxyType type() const
Returns the proxy type for this instance.
QList< QByteArray > rawHeaderList() const
void setHeaders(const QHttpHeaders &newHeaders)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QHttpHeaders headers() const
static void setApplicationProxy(const QNetworkProxy &proxy)
Sets the application level network proxying to be networkProxy.
void setType(QNetworkProxy::ProxyType type)
Sets the proxy type for this instance to be type.
bool hasRawHeader(const QByteArray &headerName) const
QString password() const
Returns the password used for authentication.
QString hostName() const
Returns the host name of the proxy host.
void setPassword(const QString &password)
Sets the password for proxy authentication to be password.
void setPort(quint16 port)
Sets the port of the proxy host to be port.
quint16 port() const
Returns the port of the proxy host.
KnownHeaders
List of known header types that QNetworkRequest parses.
\inmodule QtCore
Definition qmutex.h:309
void detach()
If the shared data object's reference count is greater than 1, this function creates a deep copy of t...
Definition qshareddata.h:40
\inmodule QtCore
Definition qshareddata.h:19
QAtomicInt ref
Definition qshareddata.h:21
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition qstring.cpp:5455
\inmodule QtCore
Definition qurl.h:94
QString host(ComponentFormattingOptions=FullyDecoded) const
Returns the host of the URL if it is defined; otherwise an empty string is returned.
Definition qurl.cpp:2340
QString scheme() const
Returns the scheme of the URL.
Definition qurl.cpp:1991
void setScheme(const QString &scheme)
Sets the scheme of the URL to scheme.
Definition qurl.cpp:1967
void setHost(const QString &host, ParsingMode mode=DecodedMode)
Sets the host of the URL to host.
Definition qurl.cpp:2289
int port(int defaultPort=-1) const
Definition qurl.cpp:2383
void setPort(int port)
Sets the port of the URL to port.
Definition qurl.cpp:2358
\inmodule QtCore
Definition qvariant.h:65
Combined button and popup list for selecting options.
static QString header(const QString &name)
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
EGLOutputPortEXT port
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:166
#define QT_IMPL_METATYPE_EXTERN(TYPE)
Definition qmetatype.h:1390
static void qt_noop_with_arg(int)
static QNetworkProxy::Capabilities defaultCapabilitiesForType(QNetworkProxy::ProxyType type)
QDebug operator<<(QDebug debug, const QNetworkProxy &proxy)
#define q_static_assert(expr)
static QByteArray headerValue(QNetworkRequest::KnownHeaders header, const QVariant &value)
GLint GLint GLint GLint GLint x
[0]
GLenum type
GLboolean enable
GLfloat GLfloat GLfloat GLfloat h
GLenum query
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
#define QStringLiteral(str)
#define QT_CONFIG(feature)
unsigned short quint16
Definition qtypes.h:48
if(qFloatDistance(a, b)<(1<< 7))
[0]
QFile defaults(defaultsPath)
QUrl url("example.com")
[constructor-url-reference]
QObject::connect nullptr
QReadWriteLock lock
[0]
QSharedPointer< T > other(t)
[5]
QItemEditorFactory * factory
QNetworkProxy proxy
[0]