Qt 6.x
The Qt SDK
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
297 {
299 }
300
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
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
496 : d(other.d)
497{
498}
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
556{
557 d->type = type;
558 if (!d->capabilitiesSet)
560}
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
628{
630}
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
763{
764 if (d->type != HttpProxy && d->type != HttpCachingProxy)
765 return QVariant();
767}
768
781{
782 if (d->type == HttpProxy || d->type == HttpCachingProxy)
784}
785
795{
796 if (d->type != HttpProxy && d->type != HttpCachingProxy)
797 return false;
799}
800
814{
815 if (d->type != HttpProxy && d->type != HttpCachingProxy)
816 return QByteArray();
819 if (it != d->headers.rawHeaders.constEnd())
820 return it->second;
821 return QByteArray();
822}
823
835{
836 if (d->type != HttpProxy && d->type != HttpCachingProxy)
837 return QList<QByteArray>();
838 return d->headers.rawHeadersKeys();
839}
840
865{
866 if (d->type == HttpProxy || d->type == HttpCachingProxy)
868}
869
871{
872public:
874 : localPort(-1), type(QNetworkProxyQuery::TcpSocket)
875 { }
876
878 {
879 return type == other.type &&
880 localPort == other.localPort &&
881 remote == other.remote;
882 }
883
887};
888
890{
891 if (d && d->ref.loadRelaxed() == 1)
892 return;
895 x->ref.ref();
896 if (d && !d->ref.deref())
897 delete d;
898 d = x;
899}
900
1041{
1042}
1043
1051{
1052 d->remote = requestUrl;
1053 d->type = queryType;
1054}
1055
1064 const QString &protocolTag,
1065 QueryType queryType)
1066{
1068 d->remote.setHost(hostname);
1069 d->remote.setPort(port);
1070 d->type = queryType;
1071}
1072
1086 QueryType queryType)
1087{
1089 d->localPort = bindPort;
1090 d->type = queryType;
1091}
1092
1097 : d(other.d)
1098{
1099}
1100
1105{
1106 // QSharedDataPointer automatically deletes
1107}
1108
1113{
1114 d = other.d;
1115 return *this;
1116}
1117
1131{
1132 return d == other.d || (d && other.d && *d == *other.d);
1133}
1134
1146{
1147 return d ? d->type : TcpSocket;
1148}
1149
1154{
1155 d->type = type;
1156}
1157
1169{
1170 return d ? d->remote.port() : -1;
1171}
1172
1186{
1187 d->remote.setPort(port);
1188}
1189
1201{
1202 return d ? d->remote.host() : QString();
1203}
1204
1218{
1219 d->remote.setHost(hostname);
1220}
1221
1229{
1230 return d ? d->localPort : -1;
1231}
1232
1252{
1253 d->localPort = port;
1254}
1255
1267{
1268 return d ? d->remote.scheme() : QString();
1269}
1270
1286{
1288}
1289
1297{
1298 return d ? d->remote : QUrl();
1299}
1300
1311{
1312 d->remote = url;
1313}
1314
1362{
1363}
1364
1369{
1370}
1371
1378{
1379 if (globalNetworkProxy())
1380 return globalNetworkProxy()->usesSystemConfiguration();
1381 return false;
1382}
1383
1397{
1398 if (globalNetworkProxy())
1399 globalNetworkProxy()->setUseSystemConfiguration(enable);
1400}
1401
1421{
1422 if (globalNetworkProxy())
1423 globalNetworkProxy()->setApplicationProxyFactory(factory);
1424}
1425
1504{
1505 if (!globalNetworkProxy())
1507 return globalNetworkProxy()->proxyForQuery(query);
1508}
1509
1510#ifndef QT_NO_DEBUG_STREAM
1512{
1513 QDebugStateSaver saver(debug);
1514 debug.resetFormat().nospace();
1516 switch (type) {
1518 debug << "NoProxy ";
1519 break;
1521 debug << "DefaultProxy ";
1522 break;
1524 debug << "Socks5Proxy ";
1525 break;
1527 debug << "HttpProxy ";
1528 break;
1530 debug << "HttpCachingProxy ";
1531 break;
1533 debug << "FtpCachingProxy ";
1534 break;
1535 default:
1536 debug << "Unknown proxy " << int(type);
1537 break;
1538 }
1539 debug << '"' << proxy.hostName() << ':' << proxy.port() << "\" ";
1540 QNetworkProxy::Capabilities caps = proxy.capabilities();
1541 QStringList scaps;
1543 scaps << QStringLiteral("Tunnel");
1545 scaps << QStringLiteral("Listen");
1547 scaps << QStringLiteral("UDP");
1549 scaps << QStringLiteral("Caching");
1551 scaps << QStringLiteral("NameLookup");
1553 scaps << QStringLiteral("SctpTunnel");
1555 scaps << QStringLiteral("SctpListen");
1556 debug << '[' << scaps.join(u' ') << ']';
1557 return debug;
1558}
1559
1561{
1562 QDebugStateSaver saver(debug);
1563 debug.resetFormat().nospace()
1564 << "ProxyQuery("
1565 << "type: " << proxyQuery.queryType()
1566 << ", protocol: " << proxyQuery.protocolTag()
1567 << ", peerPort: " << proxyQuery.peerPort()
1568 << ", peerHostName: " << proxyQuery.peerHostName()
1569 << ", localPort: " << proxyQuery.localPort()
1570 << ", url: " << proxyQuery.url()
1571 << ')';
1572 return debug;
1573}
1574#endif
1575
1577
1578#include "moc_qnetworkproxy.cpp"
1579
1580#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:1044
The QHostAddress class provides an IP address.
bool isLoopback() const
void setAddress(quint32 ip4Addr)
Set the IPv4 address specified by ip4Addr.
Definition qlist.h:74
const T & constFirst() const noexcept
Definition qlist.h:630
const_iterator constEnd() const noexcept
Definition qlist.h:616
const_iterator ConstIterator
Definition qlist.h:251
\inmodule QtCore
Definition qmutex.h:317
void setCookedHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
QList< QByteArray > rawHeadersKeys() const
void setRawHeader(const QByteArray &key, const QByteArray &value)
RawHeadersList::ConstIterator findRawHeader(const QByteArray &key) const
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
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:313
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:127
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:5299
\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:2337
QString scheme() const
Returns the scheme of the URL.
Definition qurl.cpp:1983
void setScheme(const QString &scheme)
Sets the scheme of the URL to scheme.
Definition qurl.cpp:1959
void setHost(const QString &host, ParsingMode mode=DecodedMode)
Sets the host of the URL to host.
Definition qurl.cpp:2286
int port(int defaultPort=-1) const
Definition qurl.cpp:2380
void setPort(int port)
Sets the port of the URL to port.
Definition qurl.cpp:2355
\inmodule QtCore
Definition qvariant.h:64
QSet< QString >::iterator it
Combined button and popup list for selecting options.
static QString header(const QString &name)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
EGLOutputPortEXT port
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:162
#define QT_IMPL_METATYPE_EXTERN(TYPE)
Definition qmetatype.h:1369
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)
static QByteArray headerName(QNetworkRequest::KnownHeaders header)
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:43
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]