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