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
5/*!
6 \class QNetworkProxy
7
8 \since 4.1
9
10 \brief The QNetworkProxy class provides a network layer proxy.
11
12 \reentrant
13 \ingroup network
14 \ingroup shared
15 \inmodule QtNetwork
16
17 QNetworkProxy provides the method for configuring network layer
18 proxy support to the Qt network classes. The currently supported
19 classes are QAbstractSocket, QTcpSocket, QUdpSocket, QTcpServer
20 and QNetworkAccessManager. The proxy support is designed to
21 be as transparent as possible. This means that existing
22 network-enabled applications that you have written should
23 automatically support network proxy using the following code.
24
25 \snippet code/src_network_kernel_qnetworkproxy.cpp 0
26
27 An alternative to setting an application wide proxy is to specify
28 the proxy for individual sockets using QAbstractSocket::setProxy()
29 and QTcpServer::setProxy(). In this way, it is possible to disable
30 the use of a proxy for specific sockets using the following code:
31
32 \snippet code/src_network_kernel_qnetworkproxy.cpp 1
33
34 Network proxy is not used if the address used in \l
35 {QAbstractSocket::connectToHost()}{connectToHost()}, \l
36 {QUdpSocket::bind()}{bind()} or \l
37 {QTcpServer::listen()}{listen()} is equivalent to
38 QHostAddress::LocalHost or QHostAddress::LocalHostIPv6.
39
40 Each type of proxy support has certain restrictions associated with it.
41 You should read the \l{ProxyType} documentation carefully before
42 selecting a proxy type to use.
43
44 \note Changes made to currently connected sockets do not take effect.
45 If you need to change a connected socket, you should reconnect it.
46
47 \section1 SOCKS5
48
49 The SOCKS5 support since Qt 4 is based on
50 \l{http://www.rfc-editor.org/rfc/rfc1928.txt}{RFC 1928} and
51 \l{http://www.rfc-editor.org/rfc/rfc1929.txt}{RFC 1929}.
52 The supported authentication methods are no authentication and
53 username/password authentication. Both IPv4 and IPv6 are
54 supported. Domain names are resolved through the SOCKS5 server if
55 the QNetworkProxy::HostNameLookupCapability is enabled, otherwise
56 they are resolved locally and the IP address is sent to the
57 server. There are several things to remember when using SOCKS5
58 with QUdpSocket and QTcpServer:
59
60 With QUdpSocket, a call to \l {QUdpSocket::bind()}{bind()} may fail
61 with a timeout error. If a port number other than 0 is passed to
62 \l {QUdpSocket::bind()}{bind()}, it is not guaranteed that it is the
63 specified port that will be used.
64 Use \l{QUdpSocket::localPort()}{localPort()} and
65 \l{QUdpSocket::localAddress()}{localAddress()} to get the actual
66 address and port number in use. Because proxied UDP goes through
67 two UDP connections, it is more likely that packets will be dropped.
68
69 With QTcpServer a call to \l{QTcpServer::listen()}{listen()} may
70 fail with a timeout error. If a port number other than 0 is passed
71 to \l{QTcpServer::listen()}{listen()}, then it is not guaranteed
72 that it is the specified port that will be used.
73 Use \l{QTcpServer::serverPort()}{serverPort()} and
74 \l{QTcpServer::serverAddress()}{serverAddress()} to get the actual
75 address and port used to listen for connections. SOCKS5 only supports
76 one accepted connection per call to \l{QTcpServer::listen()}{listen()},
77 and each call is likely to result in a different
78 \l{QTcpServer::serverPort()}{serverPort()} being used.
79
80 \sa QAbstractSocket, QTcpServer
81*/
82
83/*!
84 \enum QNetworkProxy::ProxyType
85
86 This enum describes the types of network proxying provided in Qt.
87
88 There are two types of proxies that Qt understands:
89 transparent proxies and caching proxies. The first group consists
90 of proxies that can handle any arbitrary data transfer, while the
91 second can only handle specific requests. The caching proxies only
92 make sense for the specific classes where they can be used.
93
94 \value NoProxy No proxying is used
95 \value DefaultProxy Proxy is determined based on the application proxy set using setApplicationProxy()
96 \value Socks5Proxy \l Socks5 proxying is used
97 \value HttpProxy HTTP transparent proxying is used
98 \value HttpCachingProxy Proxying for HTTP requests only
99 \value FtpCachingProxy Proxying for FTP requests only
100
101 The table below lists different proxy types and their
102 capabilities. Since each proxy type has different capabilities, it
103 is important to understand them before choosing a proxy type.
104
105 \table
106 \header
107 \li Proxy type
108 \li Description
109 \li Default capabilities
110
111 \row
112 \li SOCKS 5
113 \li Generic proxy for any kind of connection. Supports TCP,
114 UDP, binding to a port (incoming connections) and
115 authentication.
116 \li TunnelingCapability, ListeningCapability,
117 UdpTunnelingCapability, HostNameLookupCapability
118
119 \row
120 \li HTTP
121 \li Implemented using the "CONNECT" command, supports only
122 outgoing TCP connections; supports authentication.
123 \li TunnelingCapability, CachingCapability, HostNameLookupCapability
124
125 \row
126 \li Caching-only HTTP
127 \li Implemented using normal HTTP commands, it is useful only
128 in the context of HTTP requests (see QNetworkAccessManager)
129 \li CachingCapability, HostNameLookupCapability
130
131 \row
132 \li Caching FTP
133 \li Implemented using an FTP proxy, it is useful only in the
134 context of FTP requests (see QNetworkAccessManager)
135 \li CachingCapability, HostNameLookupCapability
136
137 \endtable
138
139 Also note that you shouldn't set the application default proxy
140 (setApplicationProxy()) to a proxy that doesn't have the
141 TunnelingCapability capability. If you do, QTcpSocket will not
142 know how to open connections.
143
144 \sa setType(), type(), capabilities(), setCapabilities()
145*/
146
147/*!
148 \enum QNetworkProxy::Capability
149 \since 4.5
150
151 These flags indicate the capabilities that a given proxy server
152 supports.
153
154 QNetworkProxy sets different capabilities by default when the
155 object is created (see QNetworkProxy::ProxyType for a list of the
156 defaults). However, it is possible to change the capabilities
157 after the object has been created with setCapabilities().
158
159 The capabilities that QNetworkProxy supports are:
160
161 \value TunnelingCapability Ability to open transparent, tunneled
162 TCP connections to a remote host. The proxy server relays the
163 transmission verbatim from one side to the other and does no
164 caching.
165
166 \value ListeningCapability Ability to create a listening socket
167 and wait for an incoming TCP connection from a remote host.
168
169 \value UdpTunnelingCapability Ability to relay UDP datagrams via
170 the proxy server to and from a remote host.
171
172 \value CachingCapability Ability to cache the contents of the
173 transfer. This capability is specific to each protocol and proxy
174 type. For example, HTTP proxies can cache the contents of web data
175 transferred with "GET" commands.
176
177 \value HostNameLookupCapability Ability to connect to perform the
178 lookup on a remote host name and connect to it, as opposed to
179 requiring the application to perform the name lookup and request
180 connection to IP addresses only.
181
182 \value SctpTunnelingCapability Ability to open transparent, tunneled
183 SCTP connections to a remote host.
184
185 \value SctpListeningCapability Ability to create a listening socket
186 and wait for an incoming SCTP connection from a remote host.
187*/
188
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
208QT_BEGIN_NAMESPACE
209
210using namespace Qt::StringLiterals;
211
212QT_IMPL_METATYPE_EXTERN(QNetworkProxy)
213
214class QSocks5SocketEngineHandler;
215class QHttpSocketEngineHandler;
216
217class QGlobalNetworkProxy
218{
219public:
220 QGlobalNetworkProxy()
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
243 ~QGlobalNetworkProxy()
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
255 bool usesSystemConfiguration() const
256 {
257 return useSystemProxies;
258 }
259
260 void setUseSystemConfiguration(bool enable)
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
273 void setApplicationProxy(const QNetworkProxy &proxy)
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
284 void setApplicationProxyFactory(QNetworkProxyFactory *factory)
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
296 QNetworkProxy applicationProxy()
297 {
298 return proxyForQuery(query: QNetworkProxyQuery()).constFirst();
299 }
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
316QList<QNetworkProxy> QGlobalNetworkProxy::proxyForQuery(const QNetworkProxyQuery &query)
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(s: "localhost."_L1)
326 || (parsed.setAddress(hostname) && (parsed.isLoopback()))) {
327 result << QNetworkProxy(QNetworkProxy::NoProxy);
328 return result;
329 }
330
331 if (!applicationLevelProxyFactory) {
332 if (applicationLevelProxy
333 && applicationLevelProxy->type() != QNetworkProxy::DefaultProxy) {
334 result << *applicationLevelProxy;
335 } else if (useSystemProxies) {
336 result = QNetworkProxyFactory::systemProxyForQuery(query);
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.
342 result << QNetworkProxy(QNetworkProxy::NoProxy);
343 } else {
344 result << QNetworkProxy(QNetworkProxy::NoProxy);
345 }
346 return result;
347 }
348
349 // we have a factory
350 result = applicationLevelProxyFactory->queryProxy(query);
351 if (result.isEmpty()) {
352 qWarning(msg: "QNetworkProxyFactory: factory %p has returned an empty result set",
353 applicationLevelProxyFactory);
354 result << QNetworkProxy(QNetworkProxy::NoProxy);
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
369static QNetworkProxy::Capabilities defaultCapabilitiesForType(QNetworkProxy::ProxyType type)
370{
371 q_static_assert(int(QNetworkProxy::DefaultProxy) == 0);
372 q_static_assert(int(QNetworkProxy::FtpCachingProxy) == 5);
373 static const int defaults[] =
374 {
375 /* [QNetworkProxy::DefaultProxy] = */
376 (int(QNetworkProxy::ListeningCapability) |
377 int(QNetworkProxy::TunnelingCapability) |
378 int(QNetworkProxy::UdpTunnelingCapability) |
379 int(QNetworkProxy::SctpTunnelingCapability) |
380 int(QNetworkProxy::SctpListeningCapability)),
381 /* [QNetworkProxy::Socks5Proxy] = */
382 (int(QNetworkProxy::TunnelingCapability) |
383 int(QNetworkProxy::ListeningCapability) |
384 int(QNetworkProxy::UdpTunnelingCapability) |
385 int(QNetworkProxy::HostNameLookupCapability)),
386 // it's weird to talk about the proxy capabilities of a "not proxy"...
387 /* [QNetworkProxy::NoProxy] = */
388 (int(QNetworkProxy::ListeningCapability) |
389 int(QNetworkProxy::TunnelingCapability) |
390 int(QNetworkProxy::UdpTunnelingCapability) |
391 int(QNetworkProxy::SctpTunnelingCapability) |
392 int(QNetworkProxy::SctpListeningCapability)),
393 /* [QNetworkProxy::HttpProxy] = */
394 (int(QNetworkProxy::TunnelingCapability) |
395 int(QNetworkProxy::CachingCapability) |
396 int(QNetworkProxy::HostNameLookupCapability)),
397 /* [QNetworkProxy::HttpCachingProxy] = */
398 (int(QNetworkProxy::CachingCapability) |
399 int(QNetworkProxy::HostNameLookupCapability)),
400 /* [QNetworkProxy::FtpCachingProxy] = */
401 (int(QNetworkProxy::CachingCapability) |
402 int(QNetworkProxy::HostNameLookupCapability)),
403 };
404
405 if (int(type) < 0 || int(type) > int(QNetworkProxy::FtpCachingProxy))
406 type = QNetworkProxy::DefaultProxy;
407 return QNetworkProxy::Capabilities(defaults[int(type)]);
408}
409
410class QNetworkProxyPrivate: public QSharedData
411{
412public:
413 QString hostName;
414 QString user;
415 QString password;
416 QNetworkProxy::Capabilities capabilities;
417 quint16 port;
418 QNetworkProxy::ProxyType type;
419 bool capabilitiesSet;
420 QNetworkHeadersPrivate headers;
421
422 inline QNetworkProxyPrivate(QNetworkProxy::ProxyType t = QNetworkProxy::DefaultProxy,
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),
428 capabilities(defaultCapabilitiesForType(type: t)),
429 port(p),
430 type(t),
431 capabilitiesSet(false)
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
445template<> void QSharedDataPointer<QNetworkProxyPrivate>::detach()
446{
447 if (d && d->ref.loadRelaxed() == 1)
448 return;
449 QNetworkProxyPrivate *x = (d ? new QNetworkProxyPrivate(*d)
450 : new QNetworkProxyPrivate);
451 x->ref.ref();
452 if (d && !d->ref.deref())
453 delete d;
454 d = x;
455}
456
457/*!
458 Constructs a QNetworkProxy with DefaultProxy type.
459
460 The proxy type is determined by applicationProxy(), which defaults to
461 NoProxy or a system-wide proxy if one is configured.
462
463 \sa setType(), setApplicationProxy()
464*/
465QNetworkProxy::QNetworkProxy()
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
474/*!
475 Constructs a QNetworkProxy with \a type, \a hostName, \a port,
476 \a user and \a password.
477
478 The default capabilities for proxy type \a type are set automatically.
479
480 \sa capabilities()
481*/
482QNetworkProxy::QNetworkProxy(ProxyType type, const QString &hostName, quint16 port,
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
492/*!
493 Constructs a copy of \a other.
494*/
495QNetworkProxy::QNetworkProxy(const QNetworkProxy &other)
496 : d(other.d)
497{
498}
499
500/*!
501 Destroys the QNetworkProxy object.
502*/
503QNetworkProxy::~QNetworkProxy()
504{
505 // QSharedDataPointer takes care of deleting for us
506}
507
508/*!
509 \since 4.4
510
511 Compares the value of this network proxy to \a other and returns \c true
512 if they are equal (same proxy type, server as well as username and password)
513*/
514bool QNetworkProxy::operator==(const QNetworkProxy &other) const
515{
516 return d == other.d || (d && other.d && *d == *other.d);
517}
518
519/*!
520 \fn bool QNetworkProxy::operator!=(const QNetworkProxy &other) const
521 \since 4.4
522
523 Compares the value of this network proxy to \a other and returns \c true
524 if they differ.
525\*/
526
527/*!
528 \since 4.2
529
530 Assigns the value of the network proxy \a other to this network proxy.
531*/
532QNetworkProxy &QNetworkProxy::operator=(const QNetworkProxy &other)
533{
534 d = other.d;
535 return *this;
536}
537
538/*!
539 \fn void QNetworkProxy::swap(QNetworkProxy &other)
540 \since 5.0
541
542 Swaps this network proxy instance with \a other. This function is
543 very fast and never fails.
544*/
545
546/*!
547 Sets the proxy type for this instance to be \a type.
548
549 Note that changing the type of a proxy does not change
550 the set of capabilities this QNetworkProxy object holds if any
551 capabilities have been set with setCapabilities().
552
553 \sa type(), setCapabilities()
554*/
555void QNetworkProxy::setType(QNetworkProxy::ProxyType type)
556{
557 d->type = type;
558 if (!d->capabilitiesSet)
559 d->capabilities = defaultCapabilitiesForType(type);
560}
561
562/*!
563 Returns the proxy type for this instance.
564
565 \sa setType()
566*/
567QNetworkProxy::ProxyType QNetworkProxy::type() const
568{
569 return d ? d->type : DefaultProxy;
570}
571
572/*!
573 \since 4.5
574
575 Sets the capabilities of this proxy to \a capabilities.
576
577 \sa setType(), capabilities()
578*/
579void QNetworkProxy::setCapabilities(Capabilities capabilities)
580{
581 d->capabilities = capabilities;
582 d->capabilitiesSet = true;
583}
584
585/*!
586 \since 4.5
587
588 Returns the capabilities of this proxy server.
589
590 \sa setCapabilities(), type()
591*/
592QNetworkProxy::Capabilities QNetworkProxy::capabilities() const
593{
594 return d ? d->capabilities : defaultCapabilitiesForType(type: DefaultProxy);
595}
596
597/*!
598 \since 4.4
599
600 Returns \c true if this proxy supports the
601 QNetworkProxy::CachingCapability capability.
602
603 In Qt 4.4, the capability was tied to the proxy type, but since Qt
604 4.5 it is possible to remove the capability of caching from a
605 proxy by calling setCapabilities().
606
607 \sa capabilities(), type(), isTransparentProxy()
608*/
609bool QNetworkProxy::isCachingProxy() const
610{
611 return capabilities() & CachingCapability;
612}
613
614/*!
615 \since 4.4
616
617 Returns \c true if this proxy supports transparent tunneling of TCP
618 connections. This matches the QNetworkProxy::TunnelingCapability
619 capability.
620
621 In Qt 4.4, the capability was tied to the proxy type, but since Qt
622 4.5 it is possible to remove the capability of caching from a
623 proxy by calling setCapabilities().
624
625 \sa capabilities(), type(), isCachingProxy()
626*/
627bool QNetworkProxy::isTransparentProxy() const
628{
629 return capabilities() & TunnelingCapability;
630}
631
632/*!
633 Sets the user name for proxy authentication to be \a user.
634
635 \sa user(), setPassword(), password()
636*/
637void QNetworkProxy::setUser(const QString &user)
638{
639 d->user = user;
640}
641
642/*!
643 Returns the user name used for authentication.
644
645 \sa setUser(), setPassword(), password()
646*/
647QString QNetworkProxy::user() const
648{
649 return d ? d->user : QString();
650}
651
652/*!
653 Sets the password for proxy authentication to be \a password.
654
655 \sa user(), setUser(), password()
656*/
657void QNetworkProxy::setPassword(const QString &password)
658{
659 d->password = password;
660}
661
662/*!
663 Returns the password used for authentication.
664
665 \sa user(), setPassword(), setUser()
666*/
667QString QNetworkProxy::password() const
668{
669 return d ? d->password : QString();
670}
671
672/*!
673 Sets the host name of the proxy host to be \a hostName.
674
675 \sa hostName(), setPort(), port()
676*/
677void QNetworkProxy::setHostName(const QString &hostName)
678{
679 d->hostName = hostName;
680}
681
682/*!
683 Returns the host name of the proxy host.
684
685 \sa setHostName(), setPort(), port()
686*/
687QString QNetworkProxy::hostName() const
688{
689 return d ? d->hostName : QString();
690}
691
692/*!
693 Sets the port of the proxy host to be \a port.
694
695 \sa hostName(), setHostName(), port()
696*/
697void QNetworkProxy::setPort(quint16 port)
698{
699 d->port = port;
700}
701
702/*!
703 Returns the port of the proxy host.
704
705 \sa setHostName(), setPort(), hostName()
706*/
707quint16 QNetworkProxy::port() const
708{
709 return d ? d->port : 0;
710}
711
712/*!
713 Sets the application level network proxying to be \a networkProxy.
714
715 If a QAbstractSocket or QTcpSocket has the
716 QNetworkProxy::DefaultProxy type, then the QNetworkProxy set with
717 this function is used. If you want more flexibility in determining
718 which proxy is used, use the QNetworkProxyFactory class.
719
720 Setting a default proxy value with this function will override the
721 application proxy factory set with
722 QNetworkProxyFactory::setApplicationProxyFactory, and disable the
723 use of a system proxy.
724
725 \sa QNetworkProxyFactory, applicationProxy(), QAbstractSocket::setProxy(), QTcpServer::setProxy()
726*/
727void QNetworkProxy::setApplicationProxy(const QNetworkProxy &networkProxy)
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
738/*!
739 Returns the application level network proxying.
740
741 If a QAbstractSocket or QTcpSocket has the
742 QNetworkProxy::DefaultProxy type, then the QNetworkProxy returned
743 by this function is used.
744
745 \sa QNetworkProxyFactory, setApplicationProxy(), QAbstractSocket::proxy(), QTcpServer::proxy()
746*/
747QNetworkProxy QNetworkProxy::applicationProxy()
748{
749 if (globalNetworkProxy())
750 return globalNetworkProxy()->applicationProxy();
751 return QNetworkProxy();
752}
753
754/*!
755 \since 6.8
756
757 Returns headers that are set in this network request.
758
759 If the proxy is not of type HttpProxy or HttpCachingProxy,
760 default constructed QHttpHeaders is returned.
761
762 \sa setHeaders()
763*/
764QHttpHeaders QNetworkProxy::headers() const
765{
766 if (d->type != HttpProxy && d->type != HttpCachingProxy)
767 return {};
768 return d->headers.headers();
769}
770
771/*!
772 \since 6.8
773
774 Sets \a newHeaders as headers in this network request, overriding
775 any previously set headers.
776
777 If some headers correspond to the known headers, the values will
778 be parsed and the corresponding parsed form will also be set.
779
780 If the proxy is not of type HttpProxy or HttpCachingProxy this has no
781 effect.
782
783 \sa headers(), QNetworkRequest::KnownHeaders
784*/
785void QNetworkProxy::setHeaders(QHttpHeaders &&newHeaders)
786{
787 if (d->type == HttpProxy || d->type == HttpCachingProxy)
788 d->headers.setHeaders(std::move(newHeaders));
789}
790
791/*!
792 \overload
793 \since 6.8
794*/
795void QNetworkProxy::setHeaders(const QHttpHeaders &newHeaders)
796{
797 if (d->type == HttpProxy || d->type == HttpCachingProxy)
798 d->headers.setHeaders(newHeaders);
799}
800
801/*!
802 \since 5.0
803 Returns the value of the known network header \a header if it is
804 in use for this proxy. If it is not present, returns QVariant()
805 (i.e., an invalid variant).
806
807 \sa QNetworkRequest::KnownHeaders, rawHeader(), setHeader()
808*/
809QVariant QNetworkProxy::header(QNetworkRequest::KnownHeaders header) const
810{
811 if (d->type != HttpProxy && d->type != HttpCachingProxy)
812 return QVariant();
813 return d->headers.cookedHeaders.value(key: header);
814}
815
816/*!
817 \since 5.0
818 Sets the value of the known header \a header to be \a value,
819 overriding any previously set headers. This operation also sets
820 the equivalent raw HTTP header.
821
822 If the proxy is not of type HttpProxy or HttpCachingProxy this has no
823 effect.
824
825 \sa QNetworkRequest::KnownHeaders, setRawHeader(), header()
826*/
827void QNetworkProxy::setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
828{
829 if (d->type == HttpProxy || d->type == HttpCachingProxy)
830 d->headers.setCookedHeader(header, value);
831}
832
833/*!
834 \since 5.0
835 Returns \c true if the raw header \a headerName is in use for this
836 proxy. Returns \c false if the proxy is not of type HttpProxy or
837 HttpCachingProxy.
838
839 \sa rawHeader(), setRawHeader()
840*/
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(name: headerName);
846}
847
848/*!
849 \since 5.0
850 Returns the raw form of header \a headerName. If no such header is
851 present or the proxy is not of type HttpProxy or HttpCachingProxy,
852 an empty QByteArray is returned, which may be indistinguishable
853 from a header that is present but has no content (use hasRawHeader()
854 to find out if the header exists or not).
855
856 Raw headers can be set with setRawHeader() or with setHeader().
857
858 \sa header(), setRawHeader()
859*/
860QByteArray QNetworkProxy::rawHeader(const QByteArray &headerName) const
861{
862 if (d->type != HttpProxy && d->type != HttpCachingProxy)
863 return QByteArray();
864 return d->headers.rawHeader(headerName);
865}
866
867/*!
868 \since 5.0
869 Returns a list of all raw headers that are set in this network
870 proxy. The list is in the order that the headers were set.
871
872 If the proxy is not of type HttpProxy or HttpCachingProxy an empty
873 QList is returned.
874
875 \sa hasRawHeader(), rawHeader()
876*/
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
884/*!
885 \since 5.0
886 Sets the header \a headerName to be of value \a headerValue. If \a
887 headerName corresponds to a known header (see
888 QNetworkRequest::KnownHeaders), the raw format will be parsed and
889 the corresponding "cooked" header will be set as well.
890
891 For example:
892 \snippet code/src_network_access_qnetworkrequest.cpp 0
893
894 will also set the known header LastModifiedHeader to be the
895 QDateTime object of the parsed date.
896
897 \note Setting the same header twice overrides the previous
898 setting. To accomplish the behaviour of multiple HTTP headers of
899 the same name, you should concatenate the two values, separating
900 them with a comma (",") and set one single raw header.
901
902 If the proxy is not of type HttpProxy or HttpCachingProxy this has no
903 effect.
904
905 \sa QNetworkRequest::KnownHeaders, setHeader(), hasRawHeader(), rawHeader()
906*/
907void QNetworkProxy::setRawHeader(const QByteArray &headerName, const QByteArray &headerValue)
908{
909 if (d->type == HttpProxy || d->type == HttpCachingProxy)
910 d->headers.setRawHeader(key: headerName, value: headerValue);
911}
912
913class QNetworkProxyQueryPrivate: public QSharedData
914{
915public:
916 inline QNetworkProxyQueryPrivate()
917 : localPort(-1), type(QNetworkProxyQuery::TcpSocket)
918 { }
919
920 bool operator==(const QNetworkProxyQueryPrivate &other) const
921 {
922 return type == other.type &&
923 localPort == other.localPort &&
924 remote == other.remote;
925 }
926
927 QUrl remote;
928 int localPort;
929 QNetworkProxyQuery::QueryType type;
930};
931
932template<> void QSharedDataPointer<QNetworkProxyQueryPrivate>::detach()
933{
934 if (d && d->ref.loadRelaxed() == 1)
935 return;
936 QNetworkProxyQueryPrivate *x = (d ? new QNetworkProxyQueryPrivate(*d)
937 : new QNetworkProxyQueryPrivate);
938 x->ref.ref();
939 if (d && !d->ref.deref())
940 delete d;
941 d = x;
942}
943
944/*!
945 \class QNetworkProxyQuery
946 \since 4.5
947 \ingroup shared
948 \inmodule QtNetwork
949 \brief The QNetworkProxyQuery class is used to query the proxy
950 settings for a socket.
951
952 QNetworkProxyQuery holds the details of a socket being created or
953 request being made. It is used by QNetworkProxy and
954 QNetworkProxyFactory to allow applications to have a more
955 fine-grained control over which proxy servers are used, depending
956 on the details of the query. This allows an application to apply
957 different settings, according to the protocol or destination
958 hostname, for instance.
959
960 QNetworkProxyQuery supports the following criteria for selecting
961 the proxy:
962
963 \list
964 \li the type of query
965 \li the local port number to use
966 \li the destination host name
967 \li the destination port number
968 \li the protocol name, such as "http" or "ftp"
969 \li the URL being requested
970 \endlist
971
972 The destination host name is the host in the connection in the
973 case of outgoing connection sockets. It is the \c hostName
974 parameter passed to QTcpSocket::connectToHost() or the host
975 component of a URL requested with QNetworkRequest.
976
977 The destination port number is the requested port to connect to in
978 the case of outgoing sockets, while the local port number is the
979 port the socket wishes to use locally before attempting the
980 external connection. In most cases, the local port number is used
981 by listening sockets only (QTcpSocket) or by datagram sockets
982 (QUdpSocket).
983
984 The protocol name is an arbitrary string that indicates the type
985 of connection being attempted. For example, it can match the
986 scheme of a URL, like "http", "https" and "ftp". In most cases,
987 the proxy selection will not change depending on the protocol, but
988 this information is provided in case a better choice can be made,
989 like choosing an caching HTTP proxy for HTTP-based connections,
990 but a more powerful SOCKSv5 proxy for all others.
991
992 Some of the criteria may not make sense in all of the types of
993 query. The following table lists the criteria that are most
994 commonly used, according to the type of query.
995
996 \table
997 \header
998 \li Query type
999 \li Description
1000
1001 \row
1002 \li TcpSocket
1003 \li Normal sockets requesting a connection to a remote server,
1004 like QTcpSocket. The peer hostname and peer port match the
1005 values passed to QTcpSocket::connectToHost(). The local port
1006 is usually -1, indicating the socket has no preference in
1007 which port should be used. The URL component is not used.
1008
1009 \row
1010 \li UdpSocket
1011 \li Datagram-based sockets, which can both send and
1012 receive. The local port, remote host or remote port fields
1013 can all be used or be left unused, depending on the
1014 characteristics of the socket. The URL component is not used.
1015
1016 \row
1017 \li SctpSocket
1018 \li Message-oriented sockets requesting a connection to a remote
1019 server. The peer hostname and peer port match the values passed
1020 to QSctpSocket::connectToHost(). The local port is usually -1,
1021 indicating the socket has no preference in which port should be
1022 used. The URL component is not used.
1023
1024 \row
1025 \li TcpServer
1026 \li Passive server sockets that listen on a port and await
1027 incoming connections from the network. Normally, only the
1028 local port is used, but the remote address could be used in
1029 specific circumstances, for example to indicate which remote
1030 host a connection is expected from. The URL component is not used.
1031
1032 \row
1033 \li UrlRequest
1034 \li A more high-level request, such as those coming from
1035 QNetworkAccessManager. These requests will inevitably use an
1036 outgoing TCP socket, but the this query type is provided to
1037 indicate that more detailed information is present in the URL
1038 component. For ease of implementation, the URL's host and
1039 port are set as the destination address.
1040
1041 \row
1042 \li SctpServer
1043 \li Passive server sockets that listen on an SCTP port and await
1044 incoming connections from the network. Normally, only the
1045 local port is used, but the remote address could be used in
1046 specific circumstances, for example to indicate which remote
1047 host a connection is expected from. The URL component is not used.
1048 \endtable
1049
1050 It should be noted that any of the criteria may be missing or
1051 unknown (an empty QString for the hostname or protocol name, -1
1052 for the port numbers). If that happens, the functions executing
1053 the query should make their best guess or apply some
1054 implementation-defined default values.
1055
1056 \sa QNetworkProxy, QNetworkProxyFactory, QNetworkAccessManager,
1057 QAbstractSocket::setProxy()
1058*/
1059
1060/*!
1061 \enum QNetworkProxyQuery::QueryType
1062
1063 Describes the type of one QNetworkProxyQuery query.
1064
1065 \value TcpSocket a normal, outgoing TCP socket
1066 \value UdpSocket a datagram-based UDP socket, which could send
1067 to multiple destinations
1068 \value SctpSocket a message-oriented, outgoing SCTP socket
1069 \value TcpServer a TCP server that listens for incoming
1070 connections from the network
1071 \value UrlRequest a more complex request which involves loading
1072 of a URL
1073 \value SctpServer an SCTP server that listens for incoming
1074 connections from the network
1075
1076 \sa queryType(), setQueryType()
1077*/
1078
1079/*!
1080 Constructs a default QNetworkProxyQuery object. By default, the
1081 query type will be QNetworkProxyQuery::TcpSocket.
1082*/
1083QNetworkProxyQuery::QNetworkProxyQuery()
1084{
1085}
1086
1087/*!
1088 Constructs a QNetworkProxyQuery with the URL \a requestUrl and
1089 sets the query type to \a queryType.
1090
1091 \sa protocolTag(), peerHostName(), peerPort()
1092*/
1093QNetworkProxyQuery::QNetworkProxyQuery(const QUrl &requestUrl, QueryType queryType)
1094{
1095 d->remote = requestUrl;
1096 d->type = queryType;
1097}
1098
1099/*!
1100 Constructs a QNetworkProxyQuery of type \a queryType and sets the
1101 protocol tag to be \a protocolTag. This constructor is suitable
1102 for QNetworkProxyQuery::TcpSocket queries, because it sets the
1103 peer hostname to \a hostname and the peer's port number to \a
1104 port.
1105*/
1106QNetworkProxyQuery::QNetworkProxyQuery(const QString &hostname, int port,
1107 const QString &protocolTag,
1108 QueryType queryType)
1109{
1110 d->remote.setScheme(protocolTag);
1111 d->remote.setHost(host: hostname);
1112 d->remote.setPort(port);
1113 d->type = queryType;
1114}
1115
1116/*!
1117 Constructs a QNetworkProxyQuery of type \a queryType and sets the
1118 protocol tag to be \a protocolTag. This constructor is suitable
1119 for QNetworkProxyQuery::TcpSocket queries because it sets the
1120 local port number to \a bindPort.
1121
1122 Note that \a bindPort is of type quint16 to indicate the exact
1123 port number that is requested. The value of -1 (unknown) is not
1124 allowed in this context.
1125
1126 \sa localPort()
1127*/
1128QNetworkProxyQuery::QNetworkProxyQuery(quint16 bindPort, const QString &protocolTag,
1129 QueryType queryType)
1130{
1131 d->remote.setScheme(protocolTag);
1132 d->localPort = bindPort;
1133 d->type = queryType;
1134}
1135
1136/*!
1137 Constructs a QNetworkProxyQuery object that is a copy of \a other.
1138*/
1139QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkProxyQuery &other)
1140 : d(other.d)
1141{
1142}
1143
1144/*!
1145 Destroys this QNetworkProxyQuery object.
1146*/
1147QNetworkProxyQuery::~QNetworkProxyQuery()
1148{
1149 // QSharedDataPointer automatically deletes
1150}
1151
1152/*!
1153 Copies the contents of \a other.
1154*/
1155QNetworkProxyQuery &QNetworkProxyQuery::operator=(const QNetworkProxyQuery &other)
1156{
1157 d = other.d;
1158 return *this;
1159}
1160
1161/*!
1162 \fn void QNetworkProxyQuery::swap(QNetworkProxyQuery &other)
1163 \since 5.0
1164
1165 Swaps this network proxy query instance with \a other. This
1166 function is very fast and never fails.
1167*/
1168
1169/*!
1170 Returns \c true if this QNetworkProxyQuery object contains the same
1171 data as \a other.
1172*/
1173bool QNetworkProxyQuery::operator==(const QNetworkProxyQuery &other) const
1174{
1175 return d == other.d || (d && other.d && *d == *other.d);
1176}
1177
1178/*!
1179 \fn bool QNetworkProxyQuery::operator!=(const QNetworkProxyQuery &other) const
1180
1181 Returns \c true if this QNetworkProxyQuery object does not contain
1182 the same data as \a other.
1183*/
1184
1185/*!
1186 Returns the query type.
1187*/
1188QNetworkProxyQuery::QueryType QNetworkProxyQuery::queryType() const
1189{
1190 return d ? d->type : TcpSocket;
1191}
1192
1193/*!
1194 Sets the query type of this object to be \a type.
1195*/
1196void QNetworkProxyQuery::setQueryType(QueryType type)
1197{
1198 d->type = type;
1199}
1200
1201/*!
1202 Returns the port number for the outgoing request or -1 if the port
1203 number is not known.
1204
1205 If the query type is QNetworkProxyQuery::UrlRequest, this function
1206 returns the port number of the URL being requested. In general,
1207 frameworks will fill in the port number from their default values.
1208
1209 \sa peerHostName(), localPort(), setPeerPort()
1210*/
1211int QNetworkProxyQuery::peerPort() const
1212{
1213 return d ? d->remote.port() : -1;
1214}
1215
1216/*!
1217 Sets the requested port number for the outgoing connection to be
1218 \a port. Valid values are 1 to 65535, or -1 to indicate that the
1219 remote port number is unknown.
1220
1221 The peer port number can also be used to indicate the expected
1222 port number of an incoming connection in the case of
1223 QNetworkProxyQuery::UdpSocket or QNetworkProxyQuery::TcpServer
1224 query types.
1225
1226 \sa peerPort(), setPeerHostName(), setLocalPort()
1227*/
1228void QNetworkProxyQuery::setPeerPort(int port)
1229{
1230 d->remote.setPort(port);
1231}
1232
1233/*!
1234 Returns the host name or IP address being of the outgoing
1235 connection being requested, or an empty string if the remote
1236 hostname is not known.
1237
1238 If the query type is QNetworkProxyQuery::UrlRequest, this function
1239 returns the host component of the URL being requested.
1240
1241 \sa peerPort(), localPort(), setPeerHostName()
1242*/
1243QString QNetworkProxyQuery::peerHostName() const
1244{
1245 return d ? d->remote.host() : QString();
1246}
1247
1248/*!
1249 Sets the hostname of the outgoing connection being requested to \a
1250 hostname. An empty hostname can be used to indicate that the
1251 remote host is unknown.
1252
1253 The peer host name can also be used to indicate the expected
1254 source address of an incoming connection in the case of
1255 QNetworkProxyQuery::UdpSocket or QNetworkProxyQuery::TcpServer
1256 query types.
1257
1258 \sa peerHostName(), setPeerPort(), setLocalPort()
1259*/
1260void QNetworkProxyQuery::setPeerHostName(const QString &hostname)
1261{
1262 d->remote.setHost(host: hostname);
1263}
1264
1265/*!
1266 Returns the port number of the socket that will accept incoming
1267 packets from remote servers or -1 if the port is not known.
1268
1269 \sa peerPort(), peerHostName(), setLocalPort()
1270*/
1271int QNetworkProxyQuery::localPort() const
1272{
1273 return d ? d->localPort : -1;
1274}
1275
1276/*!
1277 Sets the port number that the socket wishes to use locally to
1278 accept incoming packets from remote servers to \a port. The local
1279 port is most often used with the QNetworkProxyQuery::TcpServer
1280 and QNetworkProxyQuery::UdpSocket query types.
1281
1282 Valid values are 0 to 65535 (with 0 indicating that any port
1283 number will be acceptable) or -1, which means the local port
1284 number is unknown or not applicable.
1285
1286 In some circumstances, for special protocols, it's the local port
1287 number can also be used with a query of type
1288 QNetworkProxyQuery::TcpSocket. When that happens, the socket is
1289 indicating it wishes to use the port number \a port when
1290 connecting to a remote host.
1291
1292 \sa localPort(), setPeerPort(), setPeerHostName()
1293*/
1294void QNetworkProxyQuery::setLocalPort(int port)
1295{
1296 d->localPort = port;
1297}
1298
1299/*!
1300 Returns the protocol tag for this QNetworkProxyQuery object, or an
1301 empty QString in case the protocol tag is unknown.
1302
1303 In the case of queries of type QNetworkProxyQuery::UrlRequest,
1304 this function returns the value of the scheme component of the
1305 URL.
1306
1307 \sa setProtocolTag(), url()
1308*/
1309QString QNetworkProxyQuery::protocolTag() const
1310{
1311 return d ? d->remote.scheme() : QString();
1312}
1313
1314/*!
1315 Sets the protocol tag for this QNetworkProxyQuery object to be \a
1316 protocolTag.
1317
1318 The protocol tag is an arbitrary string that indicates which
1319 protocol is being talked over the socket, such as "http", "xmpp",
1320 "telnet", etc. The protocol tag is used by the backend to
1321 return a request that is more specific to the protocol in
1322 question: for example, a HTTP connection could be use a caching
1323 HTTP proxy server, while all other connections use a more powerful
1324 SOCKSv5 proxy server.
1325
1326 \sa protocolTag()
1327*/
1328void QNetworkProxyQuery::setProtocolTag(const QString &protocolTag)
1329{
1330 d->remote.setScheme(protocolTag);
1331}
1332
1333/*!
1334 Returns the URL component of this QNetworkProxyQuery object in
1335 case of a query of type QNetworkProxyQuery::UrlRequest.
1336
1337 \sa setUrl()
1338*/
1339QUrl QNetworkProxyQuery::url() const
1340{
1341 return d ? d->remote : QUrl();
1342}
1343
1344/*!
1345 Sets the URL component of this QNetworkProxyQuery object to be \a
1346 url. Setting the URL will also set the protocol tag, the remote
1347 host name and port number. This is done so as to facilitate the
1348 implementation of the code that determines the proxy server to be
1349 used.
1350
1351 \sa url(), peerHostName(), peerPort()
1352*/
1353void QNetworkProxyQuery::setUrl(const QUrl &url)
1354{
1355 d->remote = url;
1356}
1357
1358/*!
1359 \class QNetworkProxyFactory
1360 \brief The QNetworkProxyFactory class provides fine-grained proxy selection.
1361 \since 4.5
1362
1363 \ingroup network
1364 \inmodule QtNetwork
1365
1366 QNetworkProxyFactory is an extension to QNetworkProxy, allowing
1367 applications to have a more fine-grained control over which proxy
1368 servers are used, depending on the socket requesting the
1369 proxy. This allows an application to apply different settings,
1370 according to the protocol or destination hostname, for instance.
1371
1372 QNetworkProxyFactory can be set globally for an application, in
1373 which case it will override any global proxies set with
1374 QNetworkProxy::setApplicationProxy(). If set globally, any sockets
1375 created with Qt will query the factory to determine the proxy to
1376 be used.
1377
1378 A factory can also be set in certain frameworks that support
1379 multiple connections, such as QNetworkAccessManager. When set on
1380 such object, the factory will be queried for sockets created by
1381 that framework only.
1382
1383 \section1 System Proxies
1384
1385 You can configure a factory to use the system proxy's settings.
1386 Call the setUseSystemConfiguration() function with true to enable
1387 this behavior, or false to disable it.
1388
1389 Similarly, you can use a factory to make queries directly to the
1390 system proxy by calling its systemProxyForQuery() function.
1391
1392 \warning Depending on the configuration of the user's system, the
1393 use of system proxy features on certain platforms may be subject
1394 to limitations. The systemProxyForQuery() documentation contains a
1395 list of these limitations for those platforms that are affected.
1396*/
1397
1398/*!
1399 Creates a QNetworkProxyFactory object.
1400
1401 Since QNetworkProxyFactory is an abstract class, you cannot create
1402 objects of type QNetworkProxyFactory directly.
1403*/
1404QNetworkProxyFactory::QNetworkProxyFactory()
1405{
1406}
1407
1408/*!
1409 Destroys the QNetworkProxyFactory object.
1410*/
1411QNetworkProxyFactory::~QNetworkProxyFactory()
1412{
1413}
1414
1415/*!
1416 \since 5.8
1417
1418 Returns whether the use of platform-specific proxy settings are enabled.
1419*/
1420bool QNetworkProxyFactory::usesSystemConfiguration()
1421{
1422 if (globalNetworkProxy())
1423 return globalNetworkProxy()->usesSystemConfiguration();
1424 return false;
1425}
1426
1427/*!
1428 \since 4.6
1429
1430 Enables the use of the platform-specific proxy settings, and only those.
1431 See systemProxyForQuery() for more information.
1432
1433 Calling this function with \a enable set to \c true resets any proxy
1434 or QNetworkProxyFactory that is already set.
1435
1436 \note See the systemProxyForQuery() documentation for a list of
1437 limitations related to the use of system proxies.
1438*/
1439void QNetworkProxyFactory::setUseSystemConfiguration(bool enable)
1440{
1441 if (globalNetworkProxy())
1442 globalNetworkProxy()->setUseSystemConfiguration(enable);
1443}
1444
1445/*!
1446 Sets the application-wide proxy factory to be \a factory. This
1447 function will take ownership of that object and will delete it
1448 when necessary.
1449
1450 The application-wide proxy is used as a last-resort when all other
1451 proxy selection requests returned QNetworkProxy::DefaultProxy. For
1452 example, QTcpSocket objects can have a proxy set with
1453 QTcpSocket::setProxy, but if none is set, the proxy factory class
1454 set with this function will be queried.
1455
1456 If you set a proxy factory with this function, any application
1457 level proxies set with QNetworkProxy::setApplicationProxy will be
1458 overridden, and usesSystemConfiguration() will return \c{false}.
1459
1460 \sa QNetworkProxy::setApplicationProxy(),
1461 QAbstractSocket::proxy(), QAbstractSocket::setProxy()
1462*/
1463void QNetworkProxyFactory::setApplicationProxyFactory(QNetworkProxyFactory *factory)
1464{
1465 if (globalNetworkProxy())
1466 globalNetworkProxy()->setApplicationProxyFactory(factory);
1467}
1468
1469/*!
1470 \fn QList<QNetworkProxy> QNetworkProxyFactory::queryProxy(const QNetworkProxyQuery &query)
1471
1472 This function takes the query request, \a query,
1473 examines the details of the type of socket or request and returns
1474 a list of QNetworkProxy objects that indicate the proxy servers to
1475 be used, in order of preference.
1476
1477 When reimplementing this class, take care to return at least one
1478 element.
1479
1480 If you cannot determine a better proxy alternative, use
1481 QNetworkProxy::DefaultProxy, which tells the code querying for a
1482 proxy to use a higher alternative. For example, if this factory is
1483 set to a QNetworkAccessManager object, DefaultProxy will tell it
1484 to query the application-level proxy settings.
1485
1486 If this factory is set as the application proxy factory,
1487 DefaultProxy and NoProxy will have the same meaning.
1488*/
1489
1490/*!
1491 \fn QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &query)
1492
1493 This function takes the query request, \a query,
1494 examines the details of the type of socket or request and returns
1495 a list of QNetworkProxy objects that indicate the proxy servers to
1496 be used, in order of preference.
1497
1498 This function can be used to determine the platform-specific proxy
1499 settings. This function will use the libraries provided by the
1500 operating system to determine the proxy for a given connection, if
1501 such libraries exist. If they don't, this function will just return a
1502 QNetworkProxy of type QNetworkProxy::NoProxy.
1503
1504 On Windows, this function will use the WinHTTP DLL functions. Despite
1505 its name, Microsoft suggests using it for all applications that
1506 require network connections, not just HTTP. This will respect the
1507 proxy settings set on the registry with the proxycfg.exe tool. If
1508 those settings are not found, this function will attempt to obtain
1509 Internet Explorer's settings and use them.
1510
1511 On \macos, this function will obtain the proxy settings using the
1512 CFNetwork framework from Apple. It will apply the FTP,
1513 HTTP and HTTPS proxy configurations for queries that contain the
1514 protocol tag "ftp", "http" and "https", respectively. If the SOCKS
1515 proxy is enabled in that configuration, this function will use the
1516 SOCKS server for all queries. If SOCKS isn't enabled, it will use
1517 the HTTPS proxy for all TcpSocket and UrlRequest queries.
1518
1519 On systems configured with libproxy support, this function will
1520 rely on libproxy to obtain the proxy settings. Depending on
1521 libproxy configurations, this can in turn delegate to desktop
1522 settings, environment variables, etc.
1523
1524 On other systems, this function will pick up proxy settings from
1525 the "http_proxy" environment variable. This variable must be a URL
1526 using one of the following schemes: "http", "socks5" or "socks5h".
1527
1528 \section1 Limitations
1529
1530 These are the limitations for the current version of this
1531 function. Future versions of Qt may lift some of the limitations
1532 listed here.
1533
1534 \list
1535 \li On Windows platforms, this function may take several seconds to
1536 execute depending on the configuration of the user's system.
1537 \endlist
1538*/
1539
1540/*!
1541 This function takes the query request, \a query,
1542 examines the details of the type of socket or request and returns
1543 a list of QNetworkProxy objects that indicate the proxy servers to
1544 be used, in order of preference.
1545*/
1546QList<QNetworkProxy> QNetworkProxyFactory::proxyForQuery(const QNetworkProxyQuery &query)
1547{
1548 if (!globalNetworkProxy())
1549 return QList<QNetworkProxy>() << QNetworkProxy(QNetworkProxy::NoProxy);
1550 return globalNetworkProxy()->proxyForQuery(query);
1551}
1552
1553#ifndef QT_NO_DEBUG_STREAM
1554QDebug operator<<(QDebug debug, const QNetworkProxy &proxy)
1555{
1556 QDebugStateSaver saver(debug);
1557 debug.resetFormat().nospace();
1558 QNetworkProxy::ProxyType type = proxy.type();
1559 switch (type) {
1560 case QNetworkProxy::NoProxy:
1561 debug << "NoProxy ";
1562 break;
1563 case QNetworkProxy::DefaultProxy:
1564 debug << "DefaultProxy ";
1565 break;
1566 case QNetworkProxy::Socks5Proxy:
1567 debug << "Socks5Proxy ";
1568 break;
1569 case QNetworkProxy::HttpProxy:
1570 debug << "HttpProxy ";
1571 break;
1572 case QNetworkProxy::HttpCachingProxy:
1573 debug << "HttpCachingProxy ";
1574 break;
1575 case QNetworkProxy::FtpCachingProxy:
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;
1585 if (caps & QNetworkProxy::TunnelingCapability)
1586 scaps << QStringLiteral("Tunnel");
1587 if (caps & QNetworkProxy::ListeningCapability)
1588 scaps << QStringLiteral("Listen");
1589 if (caps & QNetworkProxy::UdpTunnelingCapability)
1590 scaps << QStringLiteral("UDP");
1591 if (caps & QNetworkProxy::CachingCapability)
1592 scaps << QStringLiteral("Caching");
1593 if (caps & QNetworkProxy::HostNameLookupCapability)
1594 scaps << QStringLiteral("NameLookup");
1595 if (caps & QNetworkProxy::SctpTunnelingCapability)
1596 scaps << QStringLiteral("SctpTunnel");
1597 if (caps & QNetworkProxy::SctpListeningCapability)
1598 scaps << QStringLiteral("SctpListen");
1599 debug << '[' << scaps.join(sep: u' ') << ']';
1600 return debug;
1601}
1602
1603QDebug operator<<(QDebug debug, const QNetworkProxyQuery &proxyQuery)
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
1619QT_END_NAMESPACE
1620
1621#include "moc_qnetworkproxy.cpp"
1622
1623#endif // QT_NO_NETWORKPROXY
1624

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtbase/src/network/kernel/qnetworkproxy.cpp