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 5.0
756 Returns the value of the known network header \a header if it is
757 in use for this proxy. If it is not present, returns QVariant()
758 (i.e., an invalid variant).
759
760 \sa QNetworkRequest::KnownHeaders, rawHeader(), setHeader()
761*/
762QVariant QNetworkProxy::header(QNetworkRequest::KnownHeaders header) const
763{
764 if (d->type != HttpProxy && d->type != HttpCachingProxy)
765 return QVariant();
766 return d->headers.cookedHeaders.value(key: header);
767}
768
769/*!
770 \since 5.0
771 Sets the value of the known header \a header to be \a value,
772 overriding any previously set headers. This operation also sets
773 the equivalent raw HTTP header.
774
775 If the proxy is not of type HttpProxy or HttpCachingProxy this has no
776 effect.
777
778 \sa QNetworkRequest::KnownHeaders, setRawHeader(), header()
779*/
780void QNetworkProxy::setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
781{
782 if (d->type == HttpProxy || d->type == HttpCachingProxy)
783 d->headers.setCookedHeader(header, value);
784}
785
786/*!
787 \since 5.0
788 Returns \c true if the raw header \a headerName is in use for this
789 proxy. Returns \c false if the proxy is not of type HttpProxy or
790 HttpCachingProxy.
791
792 \sa rawHeader(), setRawHeader()
793*/
794bool QNetworkProxy::hasRawHeader(const QByteArray &headerName) const
795{
796 if (d->type != HttpProxy && d->type != HttpCachingProxy)
797 return false;
798 return d->headers.findRawHeader(key: headerName) != d->headers.rawHeaders.constEnd();
799}
800
801/*!
802 \since 5.0
803 Returns the raw form of header \a headerName. If no such header is
804 present or the proxy is not of type HttpProxy or HttpCachingProxy,
805 an empty QByteArray is returned, which may be indistinguishable
806 from a header that is present but has no content (use hasRawHeader()
807 to find out if the header exists or not).
808
809 Raw headers can be set with setRawHeader() or with setHeader().
810
811 \sa header(), setRawHeader()
812*/
813QByteArray QNetworkProxy::rawHeader(const QByteArray &headerName) const
814{
815 if (d->type != HttpProxy && d->type != HttpCachingProxy)
816 return QByteArray();
817 QNetworkHeadersPrivate::RawHeadersList::ConstIterator it =
818 d->headers.findRawHeader(key: headerName);
819 if (it != d->headers.rawHeaders.constEnd())
820 return it->second;
821 return QByteArray();
822}
823
824/*!
825 \since 5.0
826 Returns a list of all raw headers that are set in this network
827 proxy. The list is in the order that the headers were set.
828
829 If the proxy is not of type HttpProxy or HttpCachingProxy an empty
830 QList is returned.
831
832 \sa hasRawHeader(), rawHeader()
833*/
834QList<QByteArray> QNetworkProxy::rawHeaderList() const
835{
836 if (d->type != HttpProxy && d->type != HttpCachingProxy)
837 return QList<QByteArray>();
838 return d->headers.rawHeadersKeys();
839}
840
841/*!
842 \since 5.0
843 Sets the header \a headerName to be of value \a headerValue. If \a
844 headerName corresponds to a known header (see
845 QNetworkRequest::KnownHeaders), the raw format will be parsed and
846 the corresponding "cooked" header will be set as well.
847
848 For example:
849 \snippet code/src_network_access_qnetworkrequest.cpp 0
850
851 will also set the known header LastModifiedHeader to be the
852 QDateTime object of the parsed date.
853
854 \note Setting the same header twice overrides the previous
855 setting. To accomplish the behaviour of multiple HTTP headers of
856 the same name, you should concatenate the two values, separating
857 them with a comma (",") and set one single raw header.
858
859 If the proxy is not of type HttpProxy or HttpCachingProxy this has no
860 effect.
861
862 \sa QNetworkRequest::KnownHeaders, setHeader(), hasRawHeader(), rawHeader()
863*/
864void QNetworkProxy::setRawHeader(const QByteArray &headerName, const QByteArray &headerValue)
865{
866 if (d->type == HttpProxy || d->type == HttpCachingProxy)
867 d->headers.setRawHeader(key: headerName, value: headerValue);
868}
869
870class QNetworkProxyQueryPrivate: public QSharedData
871{
872public:
873 inline QNetworkProxyQueryPrivate()
874 : localPort(-1), type(QNetworkProxyQuery::TcpSocket)
875 { }
876
877 bool operator==(const QNetworkProxyQueryPrivate &other) const
878 {
879 return type == other.type &&
880 localPort == other.localPort &&
881 remote == other.remote;
882 }
883
884 QUrl remote;
885 int localPort;
886 QNetworkProxyQuery::QueryType type;
887};
888
889template<> void QSharedDataPointer<QNetworkProxyQueryPrivate>::detach()
890{
891 if (d && d->ref.loadRelaxed() == 1)
892 return;
893 QNetworkProxyQueryPrivate *x = (d ? new QNetworkProxyQueryPrivate(*d)
894 : new QNetworkProxyQueryPrivate);
895 x->ref.ref();
896 if (d && !d->ref.deref())
897 delete d;
898 d = x;
899}
900
901/*!
902 \class QNetworkProxyQuery
903 \since 4.5
904 \ingroup shared
905 \inmodule QtNetwork
906 \brief The QNetworkProxyQuery class is used to query the proxy
907 settings for a socket.
908
909 QNetworkProxyQuery holds the details of a socket being created or
910 request being made. It is used by QNetworkProxy and
911 QNetworkProxyFactory to allow applications to have a more
912 fine-grained control over which proxy servers are used, depending
913 on the details of the query. This allows an application to apply
914 different settings, according to the protocol or destination
915 hostname, for instance.
916
917 QNetworkProxyQuery supports the following criteria for selecting
918 the proxy:
919
920 \list
921 \li the type of query
922 \li the local port number to use
923 \li the destination host name
924 \li the destination port number
925 \li the protocol name, such as "http" or "ftp"
926 \li the URL being requested
927 \endlist
928
929 The destination host name is the host in the connection in the
930 case of outgoing connection sockets. It is the \c hostName
931 parameter passed to QTcpSocket::connectToHost() or the host
932 component of a URL requested with QNetworkRequest.
933
934 The destination port number is the requested port to connect to in
935 the case of outgoing sockets, while the local port number is the
936 port the socket wishes to use locally before attempting the
937 external connection. In most cases, the local port number is used
938 by listening sockets only (QTcpSocket) or by datagram sockets
939 (QUdpSocket).
940
941 The protocol name is an arbitrary string that indicates the type
942 of connection being attempted. For example, it can match the
943 scheme of a URL, like "http", "https" and "ftp". In most cases,
944 the proxy selection will not change depending on the protocol, but
945 this information is provided in case a better choice can be made,
946 like choosing an caching HTTP proxy for HTTP-based connections,
947 but a more powerful SOCKSv5 proxy for all others.
948
949 Some of the criteria may not make sense in all of the types of
950 query. The following table lists the criteria that are most
951 commonly used, according to the type of query.
952
953 \table
954 \header
955 \li Query type
956 \li Description
957
958 \row
959 \li TcpSocket
960 \li Normal sockets requesting a connection to a remote server,
961 like QTcpSocket. The peer hostname and peer port match the
962 values passed to QTcpSocket::connectToHost(). The local port
963 is usually -1, indicating the socket has no preference in
964 which port should be used. The URL component is not used.
965
966 \row
967 \li UdpSocket
968 \li Datagram-based sockets, which can both send and
969 receive. The local port, remote host or remote port fields
970 can all be used or be left unused, depending on the
971 characteristics of the socket. The URL component is not used.
972
973 \row
974 \li SctpSocket
975 \li Message-oriented sockets requesting a connection to a remote
976 server. The peer hostname and peer port match the values passed
977 to QSctpSocket::connectToHost(). The local port is usually -1,
978 indicating the socket has no preference in which port should be
979 used. The URL component is not used.
980
981 \row
982 \li TcpServer
983 \li Passive server sockets that listen on a port and await
984 incoming connections from the network. Normally, only the
985 local port is used, but the remote address could be used in
986 specific circumstances, for example to indicate which remote
987 host a connection is expected from. The URL component is not used.
988
989 \row
990 \li UrlRequest
991 \li A more high-level request, such as those coming from
992 QNetworkAccessManager. These requests will inevitably use an
993 outgoing TCP socket, but the this query type is provided to
994 indicate that more detailed information is present in the URL
995 component. For ease of implementation, the URL's host and
996 port are set as the destination address.
997
998 \row
999 \li SctpServer
1000 \li Passive server sockets that listen on an SCTP port and await
1001 incoming connections from the network. Normally, only the
1002 local port is used, but the remote address could be used in
1003 specific circumstances, for example to indicate which remote
1004 host a connection is expected from. The URL component is not used.
1005 \endtable
1006
1007 It should be noted that any of the criteria may be missing or
1008 unknown (an empty QString for the hostname or protocol name, -1
1009 for the port numbers). If that happens, the functions executing
1010 the query should make their best guess or apply some
1011 implementation-defined default values.
1012
1013 \sa QNetworkProxy, QNetworkProxyFactory, QNetworkAccessManager,
1014 QAbstractSocket::setProxy()
1015*/
1016
1017/*!
1018 \enum QNetworkProxyQuery::QueryType
1019
1020 Describes the type of one QNetworkProxyQuery query.
1021
1022 \value TcpSocket a normal, outgoing TCP socket
1023 \value UdpSocket a datagram-based UDP socket, which could send
1024 to multiple destinations
1025 \value SctpSocket a message-oriented, outgoing SCTP socket
1026 \value TcpServer a TCP server that listens for incoming
1027 connections from the network
1028 \value UrlRequest a more complex request which involves loading
1029 of a URL
1030 \value SctpServer an SCTP server that listens for incoming
1031 connections from the network
1032
1033 \sa queryType(), setQueryType()
1034*/
1035
1036/*!
1037 Constructs a default QNetworkProxyQuery object. By default, the
1038 query type will be QNetworkProxyQuery::TcpSocket.
1039*/
1040QNetworkProxyQuery::QNetworkProxyQuery()
1041{
1042}
1043
1044/*!
1045 Constructs a QNetworkProxyQuery with the URL \a requestUrl and
1046 sets the query type to \a queryType.
1047
1048 \sa protocolTag(), peerHostName(), peerPort()
1049*/
1050QNetworkProxyQuery::QNetworkProxyQuery(const QUrl &requestUrl, QueryType queryType)
1051{
1052 d->remote = requestUrl;
1053 d->type = queryType;
1054}
1055
1056/*!
1057 Constructs a QNetworkProxyQuery of type \a queryType and sets the
1058 protocol tag to be \a protocolTag. This constructor is suitable
1059 for QNetworkProxyQuery::TcpSocket queries, because it sets the
1060 peer hostname to \a hostname and the peer's port number to \a
1061 port.
1062*/
1063QNetworkProxyQuery::QNetworkProxyQuery(const QString &hostname, int port,
1064 const QString &protocolTag,
1065 QueryType queryType)
1066{
1067 d->remote.setScheme(protocolTag);
1068 d->remote.setHost(host: hostname);
1069 d->remote.setPort(port);
1070 d->type = queryType;
1071}
1072
1073/*!
1074 Constructs a QNetworkProxyQuery of type \a queryType and sets the
1075 protocol tag to be \a protocolTag. This constructor is suitable
1076 for QNetworkProxyQuery::TcpSocket queries because it sets the
1077 local port number to \a bindPort.
1078
1079 Note that \a bindPort is of type quint16 to indicate the exact
1080 port number that is requested. The value of -1 (unknown) is not
1081 allowed in this context.
1082
1083 \sa localPort()
1084*/
1085QNetworkProxyQuery::QNetworkProxyQuery(quint16 bindPort, const QString &protocolTag,
1086 QueryType queryType)
1087{
1088 d->remote.setScheme(protocolTag);
1089 d->localPort = bindPort;
1090 d->type = queryType;
1091}
1092
1093/*!
1094 Constructs a QNetworkProxyQuery object that is a copy of \a other.
1095*/
1096QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkProxyQuery &other)
1097 : d(other.d)
1098{
1099}
1100
1101/*!
1102 Destroys this QNetworkProxyQuery object.
1103*/
1104QNetworkProxyQuery::~QNetworkProxyQuery()
1105{
1106 // QSharedDataPointer automatically deletes
1107}
1108
1109/*!
1110 Copies the contents of \a other.
1111*/
1112QNetworkProxyQuery &QNetworkProxyQuery::operator=(const QNetworkProxyQuery &other)
1113{
1114 d = other.d;
1115 return *this;
1116}
1117
1118/*!
1119 \fn void QNetworkProxyQuery::swap(QNetworkProxyQuery &other)
1120 \since 5.0
1121
1122 Swaps this network proxy query instance with \a other. This
1123 function is very fast and never fails.
1124*/
1125
1126/*!
1127 Returns \c true if this QNetworkProxyQuery object contains the same
1128 data as \a other.
1129*/
1130bool QNetworkProxyQuery::operator==(const QNetworkProxyQuery &other) const
1131{
1132 return d == other.d || (d && other.d && *d == *other.d);
1133}
1134
1135/*!
1136 \fn bool QNetworkProxyQuery::operator!=(const QNetworkProxyQuery &other) const
1137
1138 Returns \c true if this QNetworkProxyQuery object does not contain
1139 the same data as \a other.
1140*/
1141
1142/*!
1143 Returns the query type.
1144*/
1145QNetworkProxyQuery::QueryType QNetworkProxyQuery::queryType() const
1146{
1147 return d ? d->type : TcpSocket;
1148}
1149
1150/*!
1151 Sets the query type of this object to be \a type.
1152*/
1153void QNetworkProxyQuery::setQueryType(QueryType type)
1154{
1155 d->type = type;
1156}
1157
1158/*!
1159 Returns the port number for the outgoing request or -1 if the port
1160 number is not known.
1161
1162 If the query type is QNetworkProxyQuery::UrlRequest, this function
1163 returns the port number of the URL being requested. In general,
1164 frameworks will fill in the port number from their default values.
1165
1166 \sa peerHostName(), localPort(), setPeerPort()
1167*/
1168int QNetworkProxyQuery::peerPort() const
1169{
1170 return d ? d->remote.port() : -1;
1171}
1172
1173/*!
1174 Sets the requested port number for the outgoing connection to be
1175 \a port. Valid values are 1 to 65535, or -1 to indicate that the
1176 remote port number is unknown.
1177
1178 The peer port number can also be used to indicate the expected
1179 port number of an incoming connection in the case of
1180 QNetworkProxyQuery::UdpSocket or QNetworkProxyQuery::TcpServer
1181 query types.
1182
1183 \sa peerPort(), setPeerHostName(), setLocalPort()
1184*/
1185void QNetworkProxyQuery::setPeerPort(int port)
1186{
1187 d->remote.setPort(port);
1188}
1189
1190/*!
1191 Returns the host name or IP address being of the outgoing
1192 connection being requested, or an empty string if the remote
1193 hostname is not known.
1194
1195 If the query type is QNetworkProxyQuery::UrlRequest, this function
1196 returns the host component of the URL being requested.
1197
1198 \sa peerPort(), localPort(), setPeerHostName()
1199*/
1200QString QNetworkProxyQuery::peerHostName() const
1201{
1202 return d ? d->remote.host() : QString();
1203}
1204
1205/*!
1206 Sets the hostname of the outgoing connection being requested to \a
1207 hostname. An empty hostname can be used to indicate that the
1208 remote host is unknown.
1209
1210 The peer host name can also be used to indicate the expected
1211 source address of an incoming connection in the case of
1212 QNetworkProxyQuery::UdpSocket or QNetworkProxyQuery::TcpServer
1213 query types.
1214
1215 \sa peerHostName(), setPeerPort(), setLocalPort()
1216*/
1217void QNetworkProxyQuery::setPeerHostName(const QString &hostname)
1218{
1219 d->remote.setHost(host: hostname);
1220}
1221
1222/*!
1223 Returns the port number of the socket that will accept incoming
1224 packets from remote servers or -1 if the port is not known.
1225
1226 \sa peerPort(), peerHostName(), setLocalPort()
1227*/
1228int QNetworkProxyQuery::localPort() const
1229{
1230 return d ? d->localPort : -1;
1231}
1232
1233/*!
1234 Sets the port number that the socket wishes to use locally to
1235 accept incoming packets from remote servers to \a port. The local
1236 port is most often used with the QNetworkProxyQuery::TcpServer
1237 and QNetworkProxyQuery::UdpSocket query types.
1238
1239 Valid values are 0 to 65535 (with 0 indicating that any port
1240 number will be acceptable) or -1, which means the local port
1241 number is unknown or not applicable.
1242
1243 In some circumstances, for special protocols, it's the local port
1244 number can also be used with a query of type
1245 QNetworkProxyQuery::TcpSocket. When that happens, the socket is
1246 indicating it wishes to use the port number \a port when
1247 connecting to a remote host.
1248
1249 \sa localPort(), setPeerPort(), setPeerHostName()
1250*/
1251void QNetworkProxyQuery::setLocalPort(int port)
1252{
1253 d->localPort = port;
1254}
1255
1256/*!
1257 Returns the protocol tag for this QNetworkProxyQuery object, or an
1258 empty QString in case the protocol tag is unknown.
1259
1260 In the case of queries of type QNetworkProxyQuery::UrlRequest,
1261 this function returns the value of the scheme component of the
1262 URL.
1263
1264 \sa setProtocolTag(), url()
1265*/
1266QString QNetworkProxyQuery::protocolTag() const
1267{
1268 return d ? d->remote.scheme() : QString();
1269}
1270
1271/*!
1272 Sets the protocol tag for this QNetworkProxyQuery object to be \a
1273 protocolTag.
1274
1275 The protocol tag is an arbitrary string that indicates which
1276 protocol is being talked over the socket, such as "http", "xmpp",
1277 "telnet", etc. The protocol tag is used by the backend to
1278 return a request that is more specific to the protocol in
1279 question: for example, a HTTP connection could be use a caching
1280 HTTP proxy server, while all other connections use a more powerful
1281 SOCKSv5 proxy server.
1282
1283 \sa protocolTag()
1284*/
1285void QNetworkProxyQuery::setProtocolTag(const QString &protocolTag)
1286{
1287 d->remote.setScheme(protocolTag);
1288}
1289
1290/*!
1291 Returns the URL component of this QNetworkProxyQuery object in
1292 case of a query of type QNetworkProxyQuery::UrlRequest.
1293
1294 \sa setUrl()
1295*/
1296QUrl QNetworkProxyQuery::url() const
1297{
1298 return d ? d->remote : QUrl();
1299}
1300
1301/*!
1302 Sets the URL component of this QNetworkProxyQuery object to be \a
1303 url. Setting the URL will also set the protocol tag, the remote
1304 host name and port number. This is done so as to facilitate the
1305 implementation of the code that determines the proxy server to be
1306 used.
1307
1308 \sa url(), peerHostName(), peerPort()
1309*/
1310void QNetworkProxyQuery::setUrl(const QUrl &url)
1311{
1312 d->remote = url;
1313}
1314
1315/*!
1316 \class QNetworkProxyFactory
1317 \brief The QNetworkProxyFactory class provides fine-grained proxy selection.
1318 \since 4.5
1319
1320 \ingroup network
1321 \inmodule QtNetwork
1322
1323 QNetworkProxyFactory is an extension to QNetworkProxy, allowing
1324 applications to have a more fine-grained control over which proxy
1325 servers are used, depending on the socket requesting the
1326 proxy. This allows an application to apply different settings,
1327 according to the protocol or destination hostname, for instance.
1328
1329 QNetworkProxyFactory can be set globally for an application, in
1330 which case it will override any global proxies set with
1331 QNetworkProxy::setApplicationProxy(). If set globally, any sockets
1332 created with Qt will query the factory to determine the proxy to
1333 be used.
1334
1335 A factory can also be set in certain frameworks that support
1336 multiple connections, such as QNetworkAccessManager. When set on
1337 such object, the factory will be queried for sockets created by
1338 that framework only.
1339
1340 \section1 System Proxies
1341
1342 You can configure a factory to use the system proxy's settings.
1343 Call the setUseSystemConfiguration() function with true to enable
1344 this behavior, or false to disable it.
1345
1346 Similarly, you can use a factory to make queries directly to the
1347 system proxy by calling its systemProxyForQuery() function.
1348
1349 \warning Depending on the configuration of the user's system, the
1350 use of system proxy features on certain platforms may be subject
1351 to limitations. The systemProxyForQuery() documentation contains a
1352 list of these limitations for those platforms that are affected.
1353*/
1354
1355/*!
1356 Creates a QNetworkProxyFactory object.
1357
1358 Since QNetworkProxyFactory is an abstract class, you cannot create
1359 objects of type QNetworkProxyFactory directly.
1360*/
1361QNetworkProxyFactory::QNetworkProxyFactory()
1362{
1363}
1364
1365/*!
1366 Destroys the QNetworkProxyFactory object.
1367*/
1368QNetworkProxyFactory::~QNetworkProxyFactory()
1369{
1370}
1371
1372/*!
1373 \since 5.8
1374
1375 Returns whether the use of platform-specific proxy settings are enabled.
1376*/
1377bool QNetworkProxyFactory::usesSystemConfiguration()
1378{
1379 if (globalNetworkProxy())
1380 return globalNetworkProxy()->usesSystemConfiguration();
1381 return false;
1382}
1383
1384/*!
1385 \since 4.6
1386
1387 Enables the use of the platform-specific proxy settings, and only those.
1388 See systemProxyForQuery() for more information.
1389
1390 Calling this function with \a enable set to \c true resets any proxy
1391 or QNetworkProxyFactory that is already set.
1392
1393 \note See the systemProxyForQuery() documentation for a list of
1394 limitations related to the use of system proxies.
1395*/
1396void QNetworkProxyFactory::setUseSystemConfiguration(bool enable)
1397{
1398 if (globalNetworkProxy())
1399 globalNetworkProxy()->setUseSystemConfiguration(enable);
1400}
1401
1402/*!
1403 Sets the application-wide proxy factory to be \a factory. This
1404 function will take ownership of that object and will delete it
1405 when necessary.
1406
1407 The application-wide proxy is used as a last-resort when all other
1408 proxy selection requests returned QNetworkProxy::DefaultProxy. For
1409 example, QTcpSocket objects can have a proxy set with
1410 QTcpSocket::setProxy, but if none is set, the proxy factory class
1411 set with this function will be queried.
1412
1413 If you set a proxy factory with this function, any application
1414 level proxies set with QNetworkProxy::setApplicationProxy will be
1415 overridden, and usesSystemConfiguration() will return \c{false}.
1416
1417 \sa QNetworkProxy::setApplicationProxy(),
1418 QAbstractSocket::proxy(), QAbstractSocket::setProxy()
1419*/
1420void QNetworkProxyFactory::setApplicationProxyFactory(QNetworkProxyFactory *factory)
1421{
1422 if (globalNetworkProxy())
1423 globalNetworkProxy()->setApplicationProxyFactory(factory);
1424}
1425
1426/*!
1427 \fn QList<QNetworkProxy> QNetworkProxyFactory::queryProxy(const QNetworkProxyQuery &query)
1428
1429 This function takes the query request, \a query,
1430 examines the details of the type of socket or request and returns
1431 a list of QNetworkProxy objects that indicate the proxy servers to
1432 be used, in order of preference.
1433
1434 When reimplementing this class, take care to return at least one
1435 element.
1436
1437 If you cannot determine a better proxy alternative, use
1438 QNetworkProxy::DefaultProxy, which tells the code querying for a
1439 proxy to use a higher alternative. For example, if this factory is
1440 set to a QNetworkAccessManager object, DefaultProxy will tell it
1441 to query the application-level proxy settings.
1442
1443 If this factory is set as the application proxy factory,
1444 DefaultProxy and NoProxy will have the same meaning.
1445*/
1446
1447/*!
1448 \fn QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &query)
1449
1450 This function takes the query request, \a query,
1451 examines the details of the type of socket or request and returns
1452 a list of QNetworkProxy objects that indicate the proxy servers to
1453 be used, in order of preference.
1454
1455 This function can be used to determine the platform-specific proxy
1456 settings. This function will use the libraries provided by the
1457 operating system to determine the proxy for a given connection, if
1458 such libraries exist. If they don't, this function will just return a
1459 QNetworkProxy of type QNetworkProxy::NoProxy.
1460
1461 On Windows, this function will use the WinHTTP DLL functions. Despite
1462 its name, Microsoft suggests using it for all applications that
1463 require network connections, not just HTTP. This will respect the
1464 proxy settings set on the registry with the proxycfg.exe tool. If
1465 those settings are not found, this function will attempt to obtain
1466 Internet Explorer's settings and use them.
1467
1468 On \macos, this function will obtain the proxy settings using the
1469 CFNetwork framework from Apple. It will apply the FTP,
1470 HTTP and HTTPS proxy configurations for queries that contain the
1471 protocol tag "ftp", "http" and "https", respectively. If the SOCKS
1472 proxy is enabled in that configuration, this function will use the
1473 SOCKS server for all queries. If SOCKS isn't enabled, it will use
1474 the HTTPS proxy for all TcpSocket and UrlRequest queries.
1475
1476 On systems configured with libproxy support, this function will
1477 rely on libproxy to obtain the proxy settings. Depending on
1478 libproxy configurations, this can in turn delegate to desktop
1479 settings, environment variables, etc.
1480
1481 On other systems, this function will pick up proxy settings from
1482 the "http_proxy" environment variable. This variable must be a URL
1483 using one of the following schemes: "http", "socks5" or "socks5h".
1484
1485 \section1 Limitations
1486
1487 These are the limitations for the current version of this
1488 function. Future versions of Qt may lift some of the limitations
1489 listed here.
1490
1491 \list
1492 \li On Windows platforms, this function may take several seconds to
1493 execute depending on the configuration of the user's system.
1494 \endlist
1495*/
1496
1497/*!
1498 This function takes the query request, \a query,
1499 examines the details of the type of socket or request and returns
1500 a list of QNetworkProxy objects that indicate the proxy servers to
1501 be used, in order of preference.
1502*/
1503QList<QNetworkProxy> QNetworkProxyFactory::proxyForQuery(const QNetworkProxyQuery &query)
1504{
1505 if (!globalNetworkProxy())
1506 return QList<QNetworkProxy>() << QNetworkProxy(QNetworkProxy::NoProxy);
1507 return globalNetworkProxy()->proxyForQuery(query);
1508}
1509
1510#ifndef QT_NO_DEBUG_STREAM
1511QDebug operator<<(QDebug debug, const QNetworkProxy &proxy)
1512{
1513 QDebugStateSaver saver(debug);
1514 debug.resetFormat().nospace();
1515 QNetworkProxy::ProxyType type = proxy.type();
1516 switch (type) {
1517 case QNetworkProxy::NoProxy:
1518 debug << "NoProxy ";
1519 break;
1520 case QNetworkProxy::DefaultProxy:
1521 debug << "DefaultProxy ";
1522 break;
1523 case QNetworkProxy::Socks5Proxy:
1524 debug << "Socks5Proxy ";
1525 break;
1526 case QNetworkProxy::HttpProxy:
1527 debug << "HttpProxy ";
1528 break;
1529 case QNetworkProxy::HttpCachingProxy:
1530 debug << "HttpCachingProxy ";
1531 break;
1532 case QNetworkProxy::FtpCachingProxy:
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;
1542 if (caps & QNetworkProxy::TunnelingCapability)
1543 scaps << QStringLiteral("Tunnel");
1544 if (caps & QNetworkProxy::ListeningCapability)
1545 scaps << QStringLiteral("Listen");
1546 if (caps & QNetworkProxy::UdpTunnelingCapability)
1547 scaps << QStringLiteral("UDP");
1548 if (caps & QNetworkProxy::CachingCapability)
1549 scaps << QStringLiteral("Caching");
1550 if (caps & QNetworkProxy::HostNameLookupCapability)
1551 scaps << QStringLiteral("NameLookup");
1552 if (caps & QNetworkProxy::SctpTunnelingCapability)
1553 scaps << QStringLiteral("SctpTunnel");
1554 if (caps & QNetworkProxy::SctpListeningCapability)
1555 scaps << QStringLiteral("SctpListen");
1556 debug << '[' << scaps.join(sep: u' ') << ']';
1557 return debug;
1558}
1559
1560QDebug operator<<(QDebug debug, const QNetworkProxyQuery &proxyQuery)
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
1576QT_END_NAMESPACE
1577
1578#include "moc_qnetworkproxy.cpp"
1579
1580#endif // QT_NO_NETWORKPROXY
1581

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