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 capabilities
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
244#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section
245#include <QtNetwork/QNetworkConfiguration>
246#endif
247
248QT_BEGIN_NAMESPACE
249
250class QSocks5SocketEngineHandler;
251class QHttpSocketEngineHandler;
252
253class QGlobalNetworkProxy
254{
255public:
256 QGlobalNetworkProxy()
257 : applicationLevelProxy(nullptr)
258 , applicationLevelProxyFactory(nullptr)
259#if QT_CONFIG(socks5)
260 , socks5SocketEngineHandler(nullptr)
261#endif
262#if QT_CONFIG(http)
263 , httpSocketEngineHandler(nullptr)
264#endif
265#ifdef QT_USE_SYSTEM_PROXIES
266 , useSystemProxies(true)
267#else
268 , useSystemProxies(false)
269#endif
270 {
271#if QT_CONFIG(socks5)
272 socks5SocketEngineHandler = new QSocks5SocketEngineHandler();
273#endif
274#if QT_CONFIG(http)
275 httpSocketEngineHandler = new QHttpSocketEngineHandler();
276#endif
277 }
278
279 ~QGlobalNetworkProxy()
280 {
281 delete applicationLevelProxy;
282 delete applicationLevelProxyFactory;
283#if QT_CONFIG(socks5)
284 delete socks5SocketEngineHandler;
285#endif
286#if QT_CONFIG(http)
287 delete httpSocketEngineHandler;
288#endif
289 }
290
291 bool usesSystemConfiguration() const
292 {
293 return useSystemProxies;
294 }
295
296 void setUseSystemConfiguration(bool enable)
297 {
298 QMutexLocker lock(&mutex);
299 useSystemProxies = enable;
300
301 if (useSystemProxies) {
302 if (applicationLevelProxy)
303 *applicationLevelProxy = QNetworkProxy();
304 delete applicationLevelProxyFactory;
305 applicationLevelProxyFactory = nullptr;
306 }
307 }
308
309 void setApplicationProxy(const QNetworkProxy &proxy)
310 {
311 QMutexLocker lock(&mutex);
312 if (!applicationLevelProxy)
313 applicationLevelProxy = new QNetworkProxy;
314 *applicationLevelProxy = proxy;
315 delete applicationLevelProxyFactory;
316 applicationLevelProxyFactory = nullptr;
317 useSystemProxies = false;
318 }
319
320 void setApplicationProxyFactory(QNetworkProxyFactory *factory)
321 {
322 QMutexLocker lock(&mutex);
323 if (factory == applicationLevelProxyFactory)
324 return;
325 if (applicationLevelProxy)
326 *applicationLevelProxy = QNetworkProxy();
327 delete applicationLevelProxyFactory;
328 applicationLevelProxyFactory = factory;
329 useSystemProxies = false;
330 }
331
332 QNetworkProxy applicationProxy()
333 {
334 return proxyForQuery(query: QNetworkProxyQuery()).constFirst();
335 }
336
337 QList<QNetworkProxy> proxyForQuery(const QNetworkProxyQuery &query);
338
339private:
340 QRecursiveMutex mutex;
341 QNetworkProxy *applicationLevelProxy;
342 QNetworkProxyFactory *applicationLevelProxyFactory;
343#if QT_CONFIG(socks5)
344 QSocks5SocketEngineHandler *socks5SocketEngineHandler;
345#endif
346#if QT_CONFIG(http)
347 QHttpSocketEngineHandler *httpSocketEngineHandler;
348#endif
349 bool useSystemProxies;
350};
351
352QList<QNetworkProxy> QGlobalNetworkProxy::proxyForQuery(const QNetworkProxyQuery &query)
353{
354 QMutexLocker locker(&mutex);
355
356 QList<QNetworkProxy> result;
357
358 // don't look for proxies for a local connection
359 QHostAddress parsed;
360 QString hostname = query.url().host();
361 if (hostname == QLatin1String("localhost")
362 || hostname.startsWith(s: QLatin1String("localhost."))
363 || (parsed.setAddress(hostname)
364 && (parsed.isLoopback()))) {
365 result << QNetworkProxy(QNetworkProxy::NoProxy);
366 return result;
367 }
368
369 if (!applicationLevelProxyFactory) {
370 if (applicationLevelProxy
371 && applicationLevelProxy->type() != QNetworkProxy::DefaultProxy) {
372 result << *applicationLevelProxy;
373 } else if (useSystemProxies) {
374 result = QNetworkProxyFactory::systemProxyForQuery(query);
375
376 // Make sure NoProxy is in the list, so that QTcpServer can work:
377 // it searches for the first proxy that can has the ListeningCapability capability
378 // if none have (as is the case with HTTP proxies), it fails to bind.
379 // NoProxy allows it to fallback to the 'no proxy' case and bind.
380 result << QNetworkProxy(QNetworkProxy::NoProxy);
381 } else {
382 result << QNetworkProxy(QNetworkProxy::NoProxy);
383 }
384 return result;
385 }
386
387 // we have a factory
388 result = applicationLevelProxyFactory->queryProxy(query);
389 if (result.isEmpty()) {
390 qWarning(msg: "QNetworkProxyFactory: factory %p has returned an empty result set",
391 applicationLevelProxyFactory);
392 result << QNetworkProxy(QNetworkProxy::NoProxy);
393 }
394 return result;
395}
396
397Q_GLOBAL_STATIC(QGlobalNetworkProxy, globalNetworkProxy)
398
399namespace {
400 template<bool> struct StaticAssertTest;
401 template<> struct StaticAssertTest<true> { enum { Value = 1 }; };
402}
403
404static inline void qt_noop_with_arg(int) {}
405#define q_static_assert(expr) qt_noop_with_arg(sizeof(StaticAssertTest< expr >::Value))
406
407static QNetworkProxy::Capabilities defaultCapabilitiesForType(QNetworkProxy::ProxyType type)
408{
409 q_static_assert(int(QNetworkProxy::DefaultProxy) == 0);
410 q_static_assert(int(QNetworkProxy::FtpCachingProxy) == 5);
411 static const int defaults[] =
412 {
413 /* [QNetworkProxy::DefaultProxy] = */
414 (int(QNetworkProxy::ListeningCapability) |
415 int(QNetworkProxy::TunnelingCapability) |
416 int(QNetworkProxy::UdpTunnelingCapability) |
417 int(QNetworkProxy::SctpTunnelingCapability) |
418 int(QNetworkProxy::SctpListeningCapability)),
419 /* [QNetworkProxy::Socks5Proxy] = */
420 (int(QNetworkProxy::TunnelingCapability) |
421 int(QNetworkProxy::ListeningCapability) |
422 int(QNetworkProxy::UdpTunnelingCapability) |
423 int(QNetworkProxy::HostNameLookupCapability)),
424 // it's weird to talk about the proxy capabilities of a "not proxy"...
425 /* [QNetworkProxy::NoProxy] = */
426 (int(QNetworkProxy::ListeningCapability) |
427 int(QNetworkProxy::TunnelingCapability) |
428 int(QNetworkProxy::UdpTunnelingCapability) |
429 int(QNetworkProxy::SctpTunnelingCapability) |
430 int(QNetworkProxy::SctpListeningCapability)),
431 /* [QNetworkProxy::HttpProxy] = */
432 (int(QNetworkProxy::TunnelingCapability) |
433 int(QNetworkProxy::CachingCapability) |
434 int(QNetworkProxy::HostNameLookupCapability)),
435 /* [QNetworkProxy::HttpCachingProxy] = */
436 (int(QNetworkProxy::CachingCapability) |
437 int(QNetworkProxy::HostNameLookupCapability)),
438 /* [QNetworkProxy::FtpCachingProxy] = */
439 (int(QNetworkProxy::CachingCapability) |
440 int(QNetworkProxy::HostNameLookupCapability)),
441 };
442
443 if (int(type) < 0 || int(type) > int(QNetworkProxy::FtpCachingProxy))
444 type = QNetworkProxy::DefaultProxy;
445 return QNetworkProxy::Capabilities(defaults[int(type)]);
446}
447
448class QNetworkProxyPrivate: public QSharedData
449{
450public:
451 QString hostName;
452 QString user;
453 QString password;
454 QNetworkProxy::Capabilities capabilities;
455 quint16 port;
456 QNetworkProxy::ProxyType type;
457 bool capabilitiesSet;
458 QNetworkHeadersPrivate headers;
459
460 inline QNetworkProxyPrivate(QNetworkProxy::ProxyType t = QNetworkProxy::DefaultProxy,
461 const QString &h = QString(), quint16 p = 0,
462 const QString &u = QString(), const QString &pw = QString())
463 : hostName(h),
464 user(u),
465 password(pw),
466 capabilities(defaultCapabilitiesForType(type: t)),
467 port(p),
468 type(t),
469 capabilitiesSet(false)
470 { }
471
472 inline bool operator==(const QNetworkProxyPrivate &other) const
473 {
474 return type == other.type &&
475 port == other.port &&
476 hostName == other.hostName &&
477 user == other.user &&
478 password == other.password &&
479 capabilities == other.capabilities;
480 }
481};
482
483template<> void QSharedDataPointer<QNetworkProxyPrivate>::detach()
484{
485 if (d && d->ref.loadRelaxed() == 1)
486 return;
487 QNetworkProxyPrivate *x = (d ? new QNetworkProxyPrivate(*d)
488 : new QNetworkProxyPrivate);
489 x->ref.ref();
490 if (d && !d->ref.deref())
491 delete d;
492 d = x;
493}
494
495/*!
496 Constructs a QNetworkProxy with DefaultProxy type.
497
498 The proxy type is determined by applicationProxy(), which defaults to
499 NoProxy or a system-wide proxy if one is configured.
500
501 \sa setType(), setApplicationProxy()
502*/
503QNetworkProxy::QNetworkProxy()
504 : d(nullptr)
505{
506 // make sure we have QGlobalNetworkProxy singleton created, otherwise
507 // you don't have any socket engine handler created when directly setting
508 // a proxy to a socket
509 globalNetworkProxy();
510}
511
512/*!
513 Constructs a QNetworkProxy with \a type, \a hostName, \a port,
514 \a user and \a password.
515
516 The default capabilities for proxy type \a type are set automatically.
517
518 \sa capabilities()
519*/
520QNetworkProxy::QNetworkProxy(ProxyType type, const QString &hostName, quint16 port,
521 const QString &user, const QString &password)
522 : d(new QNetworkProxyPrivate(type, hostName, port, user, password))
523{
524 // make sure we have QGlobalNetworkProxy singleton created, otherwise
525 // you don't have any socket engine handler created when directly setting
526 // a proxy to a socket
527 globalNetworkProxy();
528}
529
530/*!
531 Constructs a copy of \a other.
532*/
533QNetworkProxy::QNetworkProxy(const QNetworkProxy &other)
534 : d(other.d)
535{
536}
537
538/*!
539 Destroys the QNetworkProxy object.
540*/
541QNetworkProxy::~QNetworkProxy()
542{
543 // QSharedDataPointer takes care of deleting for us
544}
545
546/*!
547 \since 4.4
548
549 Compares the value of this network proxy to \a other and returns \c true
550 if they are equal (same proxy type, server as well as username and password)
551*/
552bool QNetworkProxy::operator==(const QNetworkProxy &other) const
553{
554 return d == other.d || (d && other.d && *d == *other.d);
555}
556
557/*!
558 \fn bool QNetworkProxy::operator!=(const QNetworkProxy &other) const
559 \since 4.4
560
561 Compares the value of this network proxy to \a other and returns \c true
562 if they differ.
563\*/
564
565/*!
566 \since 4.2
567
568 Assigns the value of the network proxy \a other to this network proxy.
569*/
570QNetworkProxy &QNetworkProxy::operator=(const QNetworkProxy &other)
571{
572 d = other.d;
573 return *this;
574}
575
576/*!
577 \fn void QNetworkProxy::swap(QNetworkProxy &other)
578 \since 5.0
579
580 Swaps this network proxy instance with \a other. This function is
581 very fast and never fails.
582*/
583
584/*!
585 Sets the proxy type for this instance to be \a type.
586
587 Note that changing the type of a proxy does not change
588 the set of capabilities this QNetworkProxy object holds if any
589 capabilities have been set with setCapabilities().
590
591 \sa type(), setCapabilities()
592*/
593void QNetworkProxy::setType(QNetworkProxy::ProxyType type)
594{
595 d->type = type;
596 if (!d->capabilitiesSet)
597 d->capabilities = defaultCapabilitiesForType(type);
598}
599
600/*!
601 Returns the proxy type for this instance.
602
603 \sa setType()
604*/
605QNetworkProxy::ProxyType QNetworkProxy::type() const
606{
607 return d ? d->type : DefaultProxy;
608}
609
610/*!
611 \since 4.5
612
613 Sets the capabilities of this proxy to \a capabilities.
614
615 \sa setType(), capabilities()
616*/
617void QNetworkProxy::setCapabilities(Capabilities capabilities)
618{
619 d->capabilities = capabilities;
620 d->capabilitiesSet = true;
621}
622
623/*!
624 \since 4.5
625
626 Returns the capabilities of this proxy server.
627
628 \sa setCapabilities(), type()
629*/
630QNetworkProxy::Capabilities QNetworkProxy::capabilities() const
631{
632 return d ? d->capabilities : defaultCapabilitiesForType(type: DefaultProxy);
633}
634
635/*!
636 \since 4.4
637
638 Returns \c true if this proxy supports the
639 QNetworkProxy::CachingCapability capability.
640
641 In Qt 4.4, the capability was tied to the proxy type, but since Qt
642 4.5 it is possible to remove the capability of caching from a
643 proxy by calling setCapabilities().
644
645 \sa capabilities(), type(), isTransparentProxy()
646*/
647bool QNetworkProxy::isCachingProxy() const
648{
649 return capabilities() & CachingCapability;
650}
651
652/*!
653 \since 4.4
654
655 Returns \c true if this proxy supports transparent tunneling of TCP
656 connections. This matches the QNetworkProxy::TunnelingCapability
657 capability.
658
659 In Qt 4.4, the capability was tied to the proxy type, but since Qt
660 4.5 it is possible to remove the capability of caching from a
661 proxy by calling setCapabilities().
662
663 \sa capabilities(), type(), isCachingProxy()
664*/
665bool QNetworkProxy::isTransparentProxy() const
666{
667 return capabilities() & TunnelingCapability;
668}
669
670/*!
671 Sets the user name for proxy authentication to be \a user.
672
673 \sa user(), setPassword(), password()
674*/
675void QNetworkProxy::setUser(const QString &user)
676{
677 d->user = user;
678}
679
680/*!
681 Returns the user name used for authentication.
682
683 \sa setUser(), setPassword(), password()
684*/
685QString QNetworkProxy::user() const
686{
687 return d ? d->user : QString();
688}
689
690/*!
691 Sets the password for proxy authentication to be \a password.
692
693 \sa user(), setUser(), password()
694*/
695void QNetworkProxy::setPassword(const QString &password)
696{
697 d->password = password;
698}
699
700/*!
701 Returns the password used for authentication.
702
703 \sa user(), setPassword(), setUser()
704*/
705QString QNetworkProxy::password() const
706{
707 return d ? d->password : QString();
708}
709
710/*!
711 Sets the host name of the proxy host to be \a hostName.
712
713 \sa hostName(), setPort(), port()
714*/
715void QNetworkProxy::setHostName(const QString &hostName)
716{
717 d->hostName = hostName;
718}
719
720/*!
721 Returns the host name of the proxy host.
722
723 \sa setHostName(), setPort(), port()
724*/
725QString QNetworkProxy::hostName() const
726{
727 return d ? d->hostName : QString();
728}
729
730/*!
731 Sets the port of the proxy host to be \a port.
732
733 \sa hostName(), setHostName(), port()
734*/
735void QNetworkProxy::setPort(quint16 port)
736{
737 d->port = port;
738}
739
740/*!
741 Returns the port of the proxy host.
742
743 \sa setHostName(), setPort(), hostName()
744*/
745quint16 QNetworkProxy::port() const
746{
747 return d ? d->port : 0;
748}
749
750/*!
751 Sets the application level network proxying to be \a networkProxy.
752
753 If a QAbstractSocket or QTcpSocket has the
754 QNetworkProxy::DefaultProxy type, then the QNetworkProxy set with
755 this function is used. If you want more flexibility in determining
756 which proxy is used, use the QNetworkProxyFactory class.
757
758 Setting a default proxy value with this function will override the
759 application proxy factory set with
760 QNetworkProxyFactory::setApplicationProxyFactory, and disable the
761 use of a system proxy.
762
763 \sa QNetworkProxyFactory, applicationProxy(), QAbstractSocket::setProxy(), QTcpServer::setProxy()
764*/
765void QNetworkProxy::setApplicationProxy(const QNetworkProxy &networkProxy)
766{
767 if (globalNetworkProxy()) {
768 // don't accept setting the proxy to DefaultProxy
769 if (networkProxy.type() == DefaultProxy)
770 globalNetworkProxy()->setApplicationProxy(QNetworkProxy::NoProxy);
771 else
772 globalNetworkProxy()->setApplicationProxy(networkProxy);
773 }
774}
775
776/*!
777 Returns the application level network proxying.
778
779 If a QAbstractSocket or QTcpSocket has the
780 QNetworkProxy::DefaultProxy type, then the QNetworkProxy returned
781 by this function is used.
782
783 \sa QNetworkProxyFactory, setApplicationProxy(), QAbstractSocket::proxy(), QTcpServer::proxy()
784*/
785QNetworkProxy QNetworkProxy::applicationProxy()
786{
787 if (globalNetworkProxy())
788 return globalNetworkProxy()->applicationProxy();
789 return QNetworkProxy();
790}
791
792/*!
793 \since 5.0
794 Returns the value of the known network header \a header if it is
795 in use for this proxy. If it is not present, returns QVariant()
796 (i.e., an invalid variant).
797
798 \sa QNetworkRequest::KnownHeaders, rawHeader(), setHeader()
799*/
800QVariant QNetworkProxy::header(QNetworkRequest::KnownHeaders header) const
801{
802 if (d->type != HttpProxy && d->type != HttpCachingProxy)
803 return QVariant();
804 return d->headers.cookedHeaders.value(akey: header);
805}
806
807/*!
808 \since 5.0
809 Sets the value of the known header \a header to be \a value,
810 overriding any previously set headers. This operation also sets
811 the equivalent raw HTTP header.
812
813 If the proxy is not of type HttpProxy or HttpCachingProxy this has no
814 effect.
815
816 \sa QNetworkRequest::KnownHeaders, setRawHeader(), header()
817*/
818void QNetworkProxy::setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
819{
820 if (d->type == HttpProxy || d->type == HttpCachingProxy)
821 d->headers.setCookedHeader(header, value);
822}
823
824/*!
825 \since 5.0
826 Returns \c true if the raw header \a headerName is in use for this
827 proxy. Returns \c false if the proxy is not of type HttpProxy or
828 HttpCachingProxy.
829
830 \sa rawHeader(), setRawHeader()
831*/
832bool QNetworkProxy::hasRawHeader(const QByteArray &headerName) const
833{
834 if (d->type != HttpProxy && d->type != HttpCachingProxy)
835 return false;
836 return d->headers.findRawHeader(key: headerName) != d->headers.rawHeaders.constEnd();
837}
838
839/*!
840 \since 5.0
841 Returns the raw form of header \a headerName. If no such header is
842 present or the proxy is not of type HttpProxy or HttpCachingProxy,
843 an empty QByteArray is returned, which may be indistinguishable
844 from a header that is present but has no content (use hasRawHeader()
845 to find out if the header exists or not).
846
847 Raw headers can be set with setRawHeader() or with setHeader().
848
849 \sa header(), setRawHeader()
850*/
851QByteArray QNetworkProxy::rawHeader(const QByteArray &headerName) const
852{
853 if (d->type != HttpProxy && d->type != HttpCachingProxy)
854 return QByteArray();
855 QNetworkHeadersPrivate::RawHeadersList::ConstIterator it =
856 d->headers.findRawHeader(key: headerName);
857 if (it != d->headers.rawHeaders.constEnd())
858 return it->second;
859 return QByteArray();
860}
861
862/*!
863 \since 5.0
864 Returns a list of all raw headers that are set in this network
865 proxy. The list is in the order that the headers were set.
866
867 If the proxy is not of type HttpProxy or HttpCachingProxy an empty
868 QList is returned.
869
870 \sa hasRawHeader(), rawHeader()
871*/
872QList<QByteArray> QNetworkProxy::rawHeaderList() const
873{
874 if (d->type != HttpProxy && d->type != HttpCachingProxy)
875 return QList<QByteArray>();
876 return d->headers.rawHeadersKeys();
877}
878
879/*!
880 \since 5.0
881 Sets the header \a headerName to be of value \a headerValue. If \a
882 headerName corresponds to a known header (see
883 QNetworkRequest::KnownHeaders), the raw format will be parsed and
884 the corresponding "cooked" header will be set as well.
885
886 For example:
887 \snippet code/src_network_access_qnetworkrequest.cpp 0
888
889 will also set the known header LastModifiedHeader to be the
890 QDateTime object of the parsed date.
891
892 \note Setting the same header twice overrides the previous
893 setting. To accomplish the behaviour of multiple HTTP headers of
894 the same name, you should concatenate the two values, separating
895 them with a comma (",") and set one single raw header.
896
897 If the proxy is not of type HttpProxy or HttpCachingProxy this has no
898 effect.
899
900 \sa QNetworkRequest::KnownHeaders, setHeader(), hasRawHeader(), rawHeader()
901*/
902void QNetworkProxy::setRawHeader(const QByteArray &headerName, const QByteArray &headerValue)
903{
904 if (d->type == HttpProxy || d->type == HttpCachingProxy)
905 d->headers.setRawHeader(key: headerName, value: headerValue);
906}
907
908class QNetworkProxyQueryPrivate: public QSharedData
909{
910public:
911 inline QNetworkProxyQueryPrivate()
912 : localPort(-1), type(QNetworkProxyQuery::TcpSocket)
913 { }
914
915 bool operator==(const QNetworkProxyQueryPrivate &other) const
916 {
917 return type == other.type &&
918 localPort == other.localPort &&
919 remote == other.remote;
920 }
921
922 QUrl remote;
923 int localPort;
924 QNetworkProxyQuery::QueryType type;
925};
926
927template<> void QSharedDataPointer<QNetworkProxyQueryPrivate>::detach()
928{
929 if (d && d->ref.loadRelaxed() == 1)
930 return;
931 QNetworkProxyQueryPrivate *x = (d ? new QNetworkProxyQueryPrivate(*d)
932 : new QNetworkProxyQueryPrivate);
933 x->ref.ref();
934 if (d && !d->ref.deref())
935 delete d;
936 d = x;
937}
938
939/*!
940 \class QNetworkProxyQuery
941 \since 4.5
942 \ingroup shared
943 \inmodule QtNetwork
944 \brief The QNetworkProxyQuery class is used to query the proxy
945 settings for a socket.
946
947 QNetworkProxyQuery holds the details of a socket being created or
948 request being made. It is used by QNetworkProxy and
949 QNetworkProxyFactory to allow applications to have a more
950 fine-grained control over which proxy servers are used, depending
951 on the details of the query. This allows an application to apply
952 different settings, according to the protocol or destination
953 hostname, for instance.
954
955 QNetworkProxyQuery supports the following criteria for selecting
956 the proxy:
957
958 \list
959 \li the type of query
960 \li the local port number to use
961 \li the destination host name
962 \li the destination port number
963 \li the protocol name, such as "http" or "ftp"
964 \li the URL being requested
965 \endlist
966
967 The destination host name is the host in the connection in the
968 case of outgoing connection sockets. It is the \c hostName
969 parameter passed to QTcpSocket::connectToHost() or the host
970 component of a URL requested with QNetworkRequest.
971
972 The destination port number is the requested port to connect to in
973 the case of outgoing sockets, while the local port number is the
974 port the socket wishes to use locally before attempting the
975 external connection. In most cases, the local port number is used
976 by listening sockets only (QTcpSocket) or by datagram sockets
977 (QUdpSocket).
978
979 The protocol name is an arbitrary string that indicates the type
980 of connection being attempted. For example, it can match the
981 scheme of a URL, like "http", "https" and "ftp". In most cases,
982 the proxy selection will not change depending on the protocol, but
983 this information is provided in case a better choice can be made,
984 like choosing an caching HTTP proxy for HTTP-based connections,
985 but a more powerful SOCKSv5 proxy for all others.
986
987 Some of the criteria may not make sense in all of the types of
988 query. The following table lists the criteria that are most
989 commonly used, according to the type of query.
990
991 \table
992 \header
993 \li Query type
994 \li Description
995
996 \row
997 \li TcpSocket
998 \li Normal sockets requesting a connection to a remote server,
999 like QTcpSocket. The peer hostname and peer port match the
1000 values passed to QTcpSocket::connectToHost(). The local port
1001 is usually -1, indicating the socket has no preference in
1002 which port should be used. The URL component is not used.
1003
1004 \row
1005 \li UdpSocket
1006 \li Datagram-based sockets, which can both send and
1007 receive. The local port, remote host or remote port fields
1008 can all be used or be left unused, depending on the
1009 characteristics of the socket. The URL component is not used.
1010
1011 \row
1012 \li SctpSocket
1013 \li Message-oriented sockets requesting a connection to a remote
1014 server. The peer hostname and peer port match the values passed
1015 to QSctpSocket::connectToHost(). The local port is usually -1,
1016 indicating the socket has no preference in which port should be
1017 used. The URL component is not used.
1018
1019 \row
1020 \li TcpServer
1021 \li Passive server sockets that listen on a port and await
1022 incoming connections from the network. Normally, only the
1023 local port is used, but the remote address could be used in
1024 specific circumstances, for example to indicate which remote
1025 host a connection is expected from. The URL component is not used.
1026
1027 \row
1028 \li UrlRequest
1029 \li A more high-level request, such as those coming from
1030 QNetworkAccessManager. These requests will inevitably use an
1031 outgoing TCP socket, but the this query type is provided to
1032 indicate that more detailed information is present in the URL
1033 component. For ease of implementation, the URL's host and
1034 port are set as the destination address.
1035
1036 \row
1037 \li SctpServer
1038 \li Passive server sockets that listen on an SCTP port and await
1039 incoming connections from the network. Normally, only the
1040 local port is used, but the remote address could be used in
1041 specific circumstances, for example to indicate which remote
1042 host a connection is expected from. The URL component is not used.
1043 \endtable
1044
1045 It should be noted that any of the criteria may be missing or
1046 unknown (an empty QString for the hostname or protocol name, -1
1047 for the port numbers). If that happens, the functions executing
1048 the query should make their best guess or apply some
1049 implementation-defined default values.
1050
1051 \sa QNetworkProxy, QNetworkProxyFactory, QNetworkAccessManager,
1052 QAbstractSocket::setProxy()
1053*/
1054
1055/*!
1056 \enum QNetworkProxyQuery::QueryType
1057
1058 Describes the type of one QNetworkProxyQuery query.
1059
1060 \value TcpSocket a normal, outgoing TCP socket
1061 \value UdpSocket a datagram-based UDP socket, which could send
1062 to multiple destinations
1063 \value SctpSocket a message-oriented, outgoing SCTP socket
1064 \value TcpServer a TCP server that listens for incoming
1065 connections from the network
1066 \value UrlRequest a more complex request which involves loading
1067 of a URL
1068 \value SctpServer an SCTP server that listens for incoming
1069 connections from the network
1070
1071 \sa queryType(), setQueryType()
1072*/
1073
1074/*!
1075 Constructs a default QNetworkProxyQuery object. By default, the
1076 query type will be QNetworkProxyQuery::TcpSocket.
1077*/
1078QNetworkProxyQuery::QNetworkProxyQuery()
1079{
1080}
1081
1082/*!
1083 Constructs a QNetworkProxyQuery with the URL \a requestUrl and
1084 sets the query type to \a queryType.
1085
1086 \sa protocolTag(), peerHostName(), peerPort()
1087*/
1088QNetworkProxyQuery::QNetworkProxyQuery(const QUrl &requestUrl, QueryType queryType)
1089{
1090 d->remote = requestUrl;
1091 d->type = queryType;
1092}
1093
1094/*!
1095 Constructs a QNetworkProxyQuery of type \a queryType and sets the
1096 protocol tag to be \a protocolTag. This constructor is suitable
1097 for QNetworkProxyQuery::TcpSocket queries, because it sets the
1098 peer hostname to \a hostname and the peer's port number to \a
1099 port.
1100*/
1101QNetworkProxyQuery::QNetworkProxyQuery(const QString &hostname, int port,
1102 const QString &protocolTag,
1103 QueryType queryType)
1104{
1105 d->remote.setScheme(protocolTag);
1106 d->remote.setHost(host: hostname);
1107 d->remote.setPort(port);
1108 d->type = queryType;
1109}
1110
1111/*!
1112 Constructs a QNetworkProxyQuery of type \a queryType and sets the
1113 protocol tag to be \a protocolTag. This constructor is suitable
1114 for QNetworkProxyQuery::TcpSocket queries because it sets the
1115 local port number to \a bindPort.
1116
1117 Note that \a bindPort is of type quint16 to indicate the exact
1118 port number that is requested. The value of -1 (unknown) is not
1119 allowed in this context.
1120
1121 \sa localPort()
1122*/
1123QNetworkProxyQuery::QNetworkProxyQuery(quint16 bindPort, const QString &protocolTag,
1124 QueryType queryType)
1125{
1126 d->remote.setScheme(protocolTag);
1127 d->localPort = bindPort;
1128 d->type = queryType;
1129}
1130
1131#if !defined(QT_NO_BEARERMANAGEMENT) && QT_DEPRECATED_SINCE(5, 10)
1132/*!
1133 \deprecated
1134
1135 Constructs a QNetworkProxyQuery with the URL \a requestUrl and
1136 sets the query type to \a queryType. The specified \a networkConfiguration
1137 parameter is ignored.
1138
1139 \sa protocolTag(), peerHostName(), peerPort(), networkConfiguration()
1140*/
1141QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration,
1142 const QUrl &requestUrl, QueryType queryType)
1143{
1144 Q_UNUSED(networkConfiguration)
1145 d->remote = requestUrl;
1146 d->type = queryType;
1147}
1148
1149/*!
1150 \deprecated
1151
1152 Constructs a QNetworkProxyQuery of type \a queryType and sets the
1153 protocol tag to be \a protocolTag. This constructor is suitable
1154 for QNetworkProxyQuery::TcpSocket queries, because it sets the
1155 peer hostname to \a hostname and the peer's port number to \a
1156 port. The specified \a networkConfiguration parameter is ignored.
1157
1158 \sa networkConfiguration()
1159*/
1160QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration,
1161 const QString &hostname, int port,
1162 const QString &protocolTag,
1163 QueryType queryType)
1164{
1165 Q_UNUSED(networkConfiguration);
1166 d->remote.setScheme(protocolTag);
1167 d->remote.setHost(host: hostname);
1168 d->remote.setPort(port);
1169 d->type = queryType;
1170}
1171
1172/*!
1173 \deprecated
1174
1175 Constructs a QNetworkProxyQuery of type \a queryType and sets the
1176 protocol tag to be \a protocolTag. This constructor is suitable
1177 for QNetworkProxyQuery::TcpSocket queries because it sets the
1178 local port number to \a bindPort. The specified \a networkConfiguration
1179 parameter is ignored.
1180
1181 Note that \a bindPort is of type quint16 to indicate the exact
1182 port number that is requested. The value of -1 (unknown) is not
1183 allowed in this context.
1184
1185 \sa localPort(), networkConfiguration()
1186*/
1187QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration,
1188 quint16 bindPort, const QString &protocolTag,
1189 QueryType queryType)
1190{
1191 Q_UNUSED(networkConfiguration);
1192 d->remote.setScheme(protocolTag);
1193 d->localPort = bindPort;
1194 d->type = queryType;
1195}
1196#endif // !defined(QT_NO_BEARERMANAGEMENT) && QT_DEPRECATED_SINCE(5, 10)
1197
1198/*!
1199 Constructs a QNetworkProxyQuery object that is a copy of \a other.
1200*/
1201QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkProxyQuery &other)
1202 : d(other.d)
1203{
1204}
1205
1206/*!
1207 Destroys this QNetworkProxyQuery object.
1208*/
1209QNetworkProxyQuery::~QNetworkProxyQuery()
1210{
1211 // QSharedDataPointer automatically deletes
1212}
1213
1214/*!
1215 Copies the contents of \a other.
1216*/
1217QNetworkProxyQuery &QNetworkProxyQuery::operator=(const QNetworkProxyQuery &other)
1218{
1219 d = other.d;
1220 return *this;
1221}
1222
1223/*!
1224 \fn void QNetworkProxyQuery::swap(QNetworkProxyQuery &other)
1225 \since 5.0
1226
1227 Swaps this network proxy query instance with \a other. This
1228 function is very fast and never fails.
1229*/
1230
1231/*!
1232 Returns \c true if this QNetworkProxyQuery object contains the same
1233 data as \a other.
1234*/
1235bool QNetworkProxyQuery::operator==(const QNetworkProxyQuery &other) const
1236{
1237 return d == other.d || (d && other.d && *d == *other.d);
1238}
1239
1240/*!
1241 \fn bool QNetworkProxyQuery::operator!=(const QNetworkProxyQuery &other) const
1242
1243 Returns \c true if this QNetworkProxyQuery object does not contain
1244 the same data as \a other.
1245*/
1246
1247/*!
1248 Returns the query type.
1249*/
1250QNetworkProxyQuery::QueryType QNetworkProxyQuery::queryType() const
1251{
1252 return d ? d->type : TcpSocket;
1253}
1254
1255/*!
1256 Sets the query type of this object to be \a type.
1257*/
1258void QNetworkProxyQuery::setQueryType(QueryType type)
1259{
1260 d->type = type;
1261}
1262
1263/*!
1264 Returns the port number for the outgoing request or -1 if the port
1265 number is not known.
1266
1267 If the query type is QNetworkProxyQuery::UrlRequest, this function
1268 returns the port number of the URL being requested. In general,
1269 frameworks will fill in the port number from their default values.
1270
1271 \sa peerHostName(), localPort(), setPeerPort()
1272*/
1273int QNetworkProxyQuery::peerPort() const
1274{
1275 return d ? d->remote.port() : -1;
1276}
1277
1278/*!
1279 Sets the requested port number for the outgoing connection to be
1280 \a port. Valid values are 1 to 65535, or -1 to indicate that the
1281 remote port number is unknown.
1282
1283 The peer port number can also be used to indicate the expected
1284 port number of an incoming connection in the case of
1285 QNetworkProxyQuery::UdpSocket or QNetworkProxyQuery::TcpServer
1286 query types.
1287
1288 \sa peerPort(), setPeerHostName(), setLocalPort()
1289*/
1290void QNetworkProxyQuery::setPeerPort(int port)
1291{
1292 d->remote.setPort(port);
1293}
1294
1295/*!
1296 Returns the host name or IP address being of the outgoing
1297 connection being requested, or an empty string if the remote
1298 hostname is not known.
1299
1300 If the query type is QNetworkProxyQuery::UrlRequest, this function
1301 returns the host component of the URL being requested.
1302
1303 \sa peerPort(), localPort(), setPeerHostName()
1304*/
1305QString QNetworkProxyQuery::peerHostName() const
1306{
1307 return d ? d->remote.host() : QString();
1308}
1309
1310/*!
1311 Sets the hostname of the outgoing connection being requested to \a
1312 hostname. An empty hostname can be used to indicate that the
1313 remote host is unknown.
1314
1315 The peer host name can also be used to indicate the expected
1316 source address of an incoming connection in the case of
1317 QNetworkProxyQuery::UdpSocket or QNetworkProxyQuery::TcpServer
1318 query types.
1319
1320 \sa peerHostName(), setPeerPort(), setLocalPort()
1321*/
1322void QNetworkProxyQuery::setPeerHostName(const QString &hostname)
1323{
1324 d->remote.setHost(host: hostname);
1325}
1326
1327/*!
1328 Returns the port number of the socket that will accept incoming
1329 packets from remote servers or -1 if the port is not known.
1330
1331 \sa peerPort(), peerHostName(), setLocalPort()
1332*/
1333int QNetworkProxyQuery::localPort() const
1334{
1335 return d ? d->localPort : -1;
1336}
1337
1338/*!
1339 Sets the port number that the socket wishes to use locally to
1340 accept incoming packets from remote servers to \a port. The local
1341 port is most often used with the QNetworkProxyQuery::TcpServer
1342 and QNetworkProxyQuery::UdpSocket query types.
1343
1344 Valid values are 0 to 65535 (with 0 indicating that any port
1345 number will be acceptable) or -1, which means the local port
1346 number is unknown or not applicable.
1347
1348 In some circumstances, for special protocols, it's the local port
1349 number can also be used with a query of type
1350 QNetworkProxyQuery::TcpSocket. When that happens, the socket is
1351 indicating it wishes to use the port number \a port when
1352 connecting to a remote host.
1353
1354 \sa localPort(), setPeerPort(), setPeerHostName()
1355*/
1356void QNetworkProxyQuery::setLocalPort(int port)
1357{
1358 d->localPort = port;
1359}
1360
1361/*!
1362 Returns the protocol tag for this QNetworkProxyQuery object, or an
1363 empty QString in case the protocol tag is unknown.
1364
1365 In the case of queries of type QNetworkProxyQuery::UrlRequest,
1366 this function returns the value of the scheme component of the
1367 URL.
1368
1369 \sa setProtocolTag(), url()
1370*/
1371QString QNetworkProxyQuery::protocolTag() const
1372{
1373 return d ? d->remote.scheme() : QString();
1374}
1375
1376/*!
1377 Sets the protocol tag for this QNetworkProxyQuery object to be \a
1378 protocolTag.
1379
1380 The protocol tag is an arbitrary string that indicates which
1381 protocol is being talked over the socket, such as "http", "xmpp",
1382 "telnet", etc. The protocol tag is used by the backend to
1383 return a request that is more specific to the protocol in
1384 question: for example, a HTTP connection could be use a caching
1385 HTTP proxy server, while all other connections use a more powerful
1386 SOCKSv5 proxy server.
1387
1388 \sa protocolTag()
1389*/
1390void QNetworkProxyQuery::setProtocolTag(const QString &protocolTag)
1391{
1392 d->remote.setScheme(protocolTag);
1393}
1394
1395/*!
1396 Returns the URL component of this QNetworkProxyQuery object in
1397 case of a query of type QNetworkProxyQuery::UrlRequest.
1398
1399 \sa setUrl()
1400*/
1401QUrl QNetworkProxyQuery::url() const
1402{
1403 return d ? d->remote : QUrl();
1404}
1405
1406/*!
1407 Sets the URL component of this QNetworkProxyQuery object to be \a
1408 url. Setting the URL will also set the protocol tag, the remote
1409 host name and port number. This is done so as to facilitate the
1410 implementation of the code that determines the proxy server to be
1411 used.
1412
1413 \sa url(), peerHostName(), peerPort()
1414*/
1415void QNetworkProxyQuery::setUrl(const QUrl &url)
1416{
1417 d->remote = url;
1418}
1419
1420#if !defined(QT_NO_BEARERMANAGEMENT) && QT_DEPRECATED_SINCE(5, 10)
1421/*!
1422 \deprecated
1423
1424 Returns QNetworkConfiguration().
1425
1426 \sa setNetworkConfiguration()
1427*/
1428QNetworkConfiguration QNetworkProxyQuery::networkConfiguration() const
1429{
1430 return QNetworkConfiguration();
1431}
1432
1433/*!
1434 \deprecated
1435
1436 This function does nothing. The specified \a networkConfiguration parameter
1437 is ignored.
1438
1439 \sa networkConfiguration()
1440*/
1441void QNetworkProxyQuery::setNetworkConfiguration(const QNetworkConfiguration &networkConfiguration)
1442{
1443 Q_UNUSED(networkConfiguration);
1444}
1445#endif // !defined(QT_NO_BEARERMANAGEMENT) && QT_DEPRECATED_SINCE(5, 10)
1446
1447/*!
1448 \class QNetworkProxyFactory
1449 \brief The QNetworkProxyFactory class provides fine-grained proxy selection.
1450 \since 4.5
1451
1452 \ingroup network
1453 \inmodule QtNetwork
1454
1455 QNetworkProxyFactory is an extension to QNetworkProxy, allowing
1456 applications to have a more fine-grained control over which proxy
1457 servers are used, depending on the socket requesting the
1458 proxy. This allows an application to apply different settings,
1459 according to the protocol or destination hostname, for instance.
1460
1461 QNetworkProxyFactory can be set globally for an application, in
1462 which case it will override any global proxies set with
1463 QNetworkProxy::setApplicationProxy(). If set globally, any sockets
1464 created with Qt will query the factory to determine the proxy to
1465 be used.
1466
1467 A factory can also be set in certain frameworks that support
1468 multiple connections, such as QNetworkAccessManager. When set on
1469 such object, the factory will be queried for sockets created by
1470 that framework only.
1471
1472 \section1 System Proxies
1473
1474 You can configure a factory to use the system proxy's settings.
1475 Call the setUseSystemConfiguration() function with true to enable
1476 this behavior, or false to disable it.
1477
1478 Similarly, you can use a factory to make queries directly to the
1479 system proxy by calling its systemProxyForQuery() function.
1480
1481 \warning Depending on the configuration of the user's system, the
1482 use of system proxy features on certain platforms may be subject
1483 to limitations. The systemProxyForQuery() documentation contains a
1484 list of these limitations for those platforms that are affected.
1485*/
1486
1487/*!
1488 Creates a QNetworkProxyFactory object.
1489
1490 Since QNetworkProxyFactory is an abstract class, you cannot create
1491 objects of type QNetworkProxyFactory directly.
1492*/
1493QNetworkProxyFactory::QNetworkProxyFactory()
1494{
1495}
1496
1497/*!
1498 Destroys the QNetworkProxyFactory object.
1499*/
1500QNetworkProxyFactory::~QNetworkProxyFactory()
1501{
1502}
1503
1504/*!
1505 \since 5.8
1506
1507 Returns whether the use of platform-specific proxy settings are enabled.
1508*/
1509bool QNetworkProxyFactory::usesSystemConfiguration()
1510{
1511 if (globalNetworkProxy())
1512 return globalNetworkProxy()->usesSystemConfiguration();
1513 return false;
1514}
1515
1516/*!
1517 \since 4.6
1518
1519 Enables the use of the platform-specific proxy settings, and only those.
1520 See systemProxyForQuery() for more information.
1521
1522 Calling this function with \a enable set to \c true resets any proxy
1523 or QNetworkProxyFactory that is already set.
1524
1525 \note See the systemProxyForQuery() documentation for a list of
1526 limitations related to the use of system proxies.
1527*/
1528void QNetworkProxyFactory::setUseSystemConfiguration(bool enable)
1529{
1530 if (globalNetworkProxy())
1531 globalNetworkProxy()->setUseSystemConfiguration(enable);
1532}
1533
1534/*!
1535 Sets the application-wide proxy factory to be \a factory. This
1536 function will take ownership of that object and will delete it
1537 when necessary.
1538
1539 The application-wide proxy is used as a last-resort when all other
1540 proxy selection requests returned QNetworkProxy::DefaultProxy. For
1541 example, QTcpSocket objects can have a proxy set with
1542 QTcpSocket::setProxy, but if none is set, the proxy factory class
1543 set with this function will be queried.
1544
1545 If you set a proxy factory with this function, any application
1546 level proxies set with QNetworkProxy::setApplicationProxy will be
1547 overridden, and usesSystemConfiguration() will return \c{false}.
1548
1549 \sa QNetworkProxy::setApplicationProxy(),
1550 QAbstractSocket::proxy(), QAbstractSocket::setProxy()
1551*/
1552void QNetworkProxyFactory::setApplicationProxyFactory(QNetworkProxyFactory *factory)
1553{
1554 if (globalNetworkProxy())
1555 globalNetworkProxy()->setApplicationProxyFactory(factory);
1556}
1557
1558/*!
1559 \fn QList<QNetworkProxy> QNetworkProxyFactory::queryProxy(const QNetworkProxyQuery &query)
1560
1561 This function takes the query request, \a query,
1562 examines the details of the type of socket or request and returns
1563 a list of QNetworkProxy objects that indicate the proxy servers to
1564 be used, in order of preference.
1565
1566 When reimplementing this class, take care to return at least one
1567 element.
1568
1569 If you cannot determine a better proxy alternative, use
1570 QNetworkProxy::DefaultProxy, which tells the code querying for a
1571 proxy to use a higher alternative. For example, if this factory is
1572 set to a QNetworkAccessManager object, DefaultProxy will tell it
1573 to query the application-level proxy settings.
1574
1575 If this factory is set as the application proxy factory,
1576 DefaultProxy and NoProxy will have the same meaning.
1577*/
1578
1579/*!
1580 \fn QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &query)
1581
1582 This function takes the query request, \a query,
1583 examines the details of the type of socket or request and returns
1584 a list of QNetworkProxy objects that indicate the proxy servers to
1585 be used, in order of preference.
1586
1587 This function can be used to determine the platform-specific proxy
1588 settings. This function will use the libraries provided by the
1589 operating system to determine the proxy for a given connection, if
1590 such libraries exist. If they don't, this function will just return a
1591 QNetworkProxy of type QNetworkProxy::NoProxy.
1592
1593 On Windows, this function will use the WinHTTP DLL functions. Despite
1594 its name, Microsoft suggests using it for all applications that
1595 require network connections, not just HTTP. This will respect the
1596 proxy settings set on the registry with the proxycfg.exe tool. If
1597 those settings are not found, this function will attempt to obtain
1598 Internet Explorer's settings and use them.
1599
1600 On \macos, this function will obtain the proxy settings using the
1601 SystemConfiguration framework from Apple. It will apply the FTP,
1602 HTTP and HTTPS proxy configurations for queries that contain the
1603 protocol tag "ftp", "http" and "https", respectively. If the SOCKS
1604 proxy is enabled in that configuration, this function will use the
1605 SOCKS server for all queries. If SOCKS isn't enabled, it will use
1606 the HTTPS proxy for all TcpSocket and UrlRequest queries.
1607
1608 On other systems, this function will pick up proxy settings from
1609 the "http_proxy" environment variable. This variable must be a URL
1610 using one of the following schemes: "http", "socks5" or "socks5h".
1611
1612 \section1 Limitations
1613
1614 These are the limitations for the current version of this
1615 function. Future versions of Qt may lift some of the limitations
1616 listed here.
1617
1618 \list
1619 \li On \macos, this function will ignore the Proxy Auto Configuration
1620 settings, since it cannot execute the associated ECMAScript code.
1621
1622 \li On Windows platforms, this function may take several seconds to
1623 execute depending on the configuration of the user's system.
1624 \endlist
1625*/
1626
1627/*!
1628 This function takes the query request, \a query,
1629 examines the details of the type of socket or request and returns
1630 a list of QNetworkProxy objects that indicate the proxy servers to
1631 be used, in order of preference.
1632*/
1633QList<QNetworkProxy> QNetworkProxyFactory::proxyForQuery(const QNetworkProxyQuery &query)
1634{
1635 if (!globalNetworkProxy())
1636 return QList<QNetworkProxy>() << QNetworkProxy(QNetworkProxy::NoProxy);
1637 return globalNetworkProxy()->proxyForQuery(query);
1638}
1639
1640#ifndef QT_NO_DEBUG_STREAM
1641QDebug operator<<(QDebug debug, const QNetworkProxy &proxy)
1642{
1643 QDebugStateSaver saver(debug);
1644 debug.resetFormat().nospace();
1645 QNetworkProxy::ProxyType type = proxy.type();
1646 switch (type) {
1647 case QNetworkProxy::NoProxy:
1648 debug << "NoProxy ";
1649 break;
1650 case QNetworkProxy::DefaultProxy:
1651 debug << "DefaultProxy ";
1652 break;
1653 case QNetworkProxy::Socks5Proxy:
1654 debug << "Socks5Proxy ";
1655 break;
1656 case QNetworkProxy::HttpProxy:
1657 debug << "HttpProxy ";
1658 break;
1659 case QNetworkProxy::HttpCachingProxy:
1660 debug << "HttpCachingProxy ";
1661 break;
1662 case QNetworkProxy::FtpCachingProxy:
1663 debug << "FtpCachingProxy ";
1664 break;
1665 default:
1666 debug << "Unknown proxy " << int(type);
1667 break;
1668 }
1669 debug << '"' << proxy.hostName() << ':' << proxy.port() << "\" ";
1670 QNetworkProxy::Capabilities caps = proxy.capabilities();
1671 QStringList scaps;
1672 if (caps & QNetworkProxy::TunnelingCapability)
1673 scaps << QStringLiteral("Tunnel");
1674 if (caps & QNetworkProxy::ListeningCapability)
1675 scaps << QStringLiteral("Listen");
1676 if (caps & QNetworkProxy::UdpTunnelingCapability)
1677 scaps << QStringLiteral("UDP");
1678 if (caps & QNetworkProxy::CachingCapability)
1679 scaps << QStringLiteral("Caching");
1680 if (caps & QNetworkProxy::HostNameLookupCapability)
1681 scaps << QStringLiteral("NameLookup");
1682 if (caps & QNetworkProxy::SctpTunnelingCapability)
1683 scaps << QStringLiteral("SctpTunnel");
1684 if (caps & QNetworkProxy::SctpListeningCapability)
1685 scaps << QStringLiteral("SctpListen");
1686 debug << '[' << scaps.join(sep: QLatin1Char(' ')) << ']';
1687 return debug;
1688}
1689
1690QDebug operator<<(QDebug debug, const QNetworkProxyQuery &proxyQuery)
1691{
1692 QDebugStateSaver saver(debug);
1693 debug.resetFormat().nospace()
1694 << "ProxyQuery("
1695 << "type: " << proxyQuery.queryType()
1696 << ", protocol: " << proxyQuery.protocolTag()
1697 << ", peerPort: " << proxyQuery.peerPort()
1698 << ", peerHostName: " << proxyQuery.peerHostName()
1699 << ", localPort: " << proxyQuery.localPort()
1700 << ", url: " << proxyQuery.url()
1701 << ')';
1702 return debug;
1703}
1704#endif
1705
1706QT_END_NAMESPACE
1707
1708#endif // QT_NO_NETWORKPROXY
1709

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