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 
244 #ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section
245 #include <QtNetwork/QNetworkConfiguration>
246 #endif
247 
248 QT_BEGIN_NAMESPACE
249 
250 class QSocks5SocketEngineHandler;
251 class QHttpSocketEngineHandler;
252 
253 class QGlobalNetworkProxy
254 {
255 public:
QGlobalNetworkProxy()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 
~QGlobalNetworkProxy()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 
usesSystemConfiguration() const291     bool usesSystemConfiguration() const
292     {
293         return useSystemProxies;
294     }
295 
setUseSystemConfiguration(bool enable)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 
setApplicationProxy(const QNetworkProxy & proxy)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 
setApplicationProxyFactory(QNetworkProxyFactory * factory)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 
applicationProxy()332     QNetworkProxy applicationProxy()
333     {
334         return proxyForQuery(QNetworkProxyQuery()).constFirst();
335     }
336 
337     QList<QNetworkProxy> proxyForQuery(const QNetworkProxyQuery &query);
338 
339 private:
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 
proxyForQuery(const QNetworkProxyQuery & query)352 QList<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(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("QNetworkProxyFactory: factory %p has returned an empty result set",
391                  applicationLevelProxyFactory);
392         result << QNetworkProxy(QNetworkProxy::NoProxy);
393     }
394     return result;
395 }
396 
397 Q_GLOBAL_STATIC(QGlobalNetworkProxy, globalNetworkProxy)
398 
399 namespace {
400     template<bool> struct StaticAssertTest;
401     template<> struct StaticAssertTest<true> { enum { Value = 1 }; };
402 }
403 
qt_noop_with_arg(int)404 static inline void qt_noop_with_arg(int) {}
405 #define q_static_assert(expr)   qt_noop_with_arg(sizeof(StaticAssertTest< expr >::Value))
406 
defaultCapabilitiesForType(QNetworkProxy::ProxyType type)407 static 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 
448 class QNetworkProxyPrivate: public QSharedData
449 {
450 public:
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 
QNetworkProxyPrivate(QNetworkProxy::ProxyType t=QNetworkProxy::DefaultProxy,const QString & h=QString (),quint16 p=0,const QString & u=QString (),const QString & pw=QString ())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(t)),
467           port(p),
468           type(t),
469           capabilitiesSet(false)
470     { }
471 
operator ==(const QNetworkProxyPrivate & other) const472     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 
detach()483 template<> 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 */
QNetworkProxy()503 QNetworkProxy::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 */
QNetworkProxy(ProxyType type,const QString & hostName,quint16 port,const QString & user,const QString & password)520 QNetworkProxy::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 */
QNetworkProxy(const QNetworkProxy & other)533 QNetworkProxy::QNetworkProxy(const QNetworkProxy &other)
534     : d(other.d)
535 {
536 }
537 
538 /*!
539     Destroys the QNetworkProxy object.
540 */
~QNetworkProxy()541 QNetworkProxy::~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 */
operator ==(const QNetworkProxy & other) const552 bool 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 */
operator =(const QNetworkProxy & other)570 QNetworkProxy &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 */
setType(QNetworkProxy::ProxyType type)593 void 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 */
type() const605 QNetworkProxy::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 */
setCapabilities(Capabilities capabilities)617 void 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 */
capabilities() const630 QNetworkProxy::Capabilities QNetworkProxy::capabilities() const
631 {
632     return d ? d->capabilities : defaultCapabilitiesForType(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 */
isCachingProxy() const647 bool 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 */
isTransparentProxy() const665 bool 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 */
setUser(const QString & user)675 void 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 */
user() const685 QString 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 */
setPassword(const QString & password)695 void 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 */
password() const705 QString 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 */
setHostName(const QString & hostName)715 void 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 */
hostName() const725 QString 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 */
setPort(quint16 port)735 void 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 */
port() const745 quint16 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 */
setApplicationProxy(const QNetworkProxy & networkProxy)765 void 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 */
applicationProxy()785 QNetworkProxy 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 */
header(QNetworkRequest::KnownHeaders header) const800 QVariant QNetworkProxy::header(QNetworkRequest::KnownHeaders header) const
801 {
802     if (d->type != HttpProxy && d->type != HttpCachingProxy)
803         return QVariant();
804     return d->headers.cookedHeaders.value(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 */
setHeader(QNetworkRequest::KnownHeaders header,const QVariant & value)818 void 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 */
hasRawHeader(const QByteArray & headerName) const832 bool QNetworkProxy::hasRawHeader(const QByteArray &headerName) const
833 {
834     if (d->type != HttpProxy && d->type != HttpCachingProxy)
835         return false;
836     return d->headers.findRawHeader(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 */
rawHeader(const QByteArray & headerName) const851 QByteArray 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(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 */
rawHeaderList() const872 QList<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 */
setRawHeader(const QByteArray & headerName,const QByteArray & headerValue)902 void QNetworkProxy::setRawHeader(const QByteArray &headerName, const QByteArray &headerValue)
903 {
904     if (d->type == HttpProxy || d->type == HttpCachingProxy)
905         d->headers.setRawHeader(headerName, headerValue);
906 }
907 
908 class QNetworkProxyQueryPrivate: public QSharedData
909 {
910 public:
QNetworkProxyQueryPrivate()911     inline QNetworkProxyQueryPrivate()
912         : localPort(-1), type(QNetworkProxyQuery::TcpSocket)
913     { }
914 
operator ==(const QNetworkProxyQueryPrivate & other) const915     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 
detach()927 template<> 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 */
QNetworkProxyQuery()1078 QNetworkProxyQuery::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 */
QNetworkProxyQuery(const QUrl & requestUrl,QueryType queryType)1088 QNetworkProxyQuery::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 */
QNetworkProxyQuery(const QString & hostname,int port,const QString & protocolTag,QueryType queryType)1101 QNetworkProxyQuery::QNetworkProxyQuery(const QString &hostname, int port,
1102                                        const QString &protocolTag,
1103                                        QueryType queryType)
1104 {
1105     d->remote.setScheme(protocolTag);
1106     d->remote.setHost(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 */
QNetworkProxyQuery(quint16 bindPort,const QString & protocolTag,QueryType queryType)1123 QNetworkProxyQuery::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 */
QNetworkProxyQuery(const QNetworkConfiguration & networkConfiguration,const QUrl & requestUrl,QueryType queryType)1141 QNetworkProxyQuery::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 */
QNetworkProxyQuery(const QNetworkConfiguration & networkConfiguration,const QString & hostname,int port,const QString & protocolTag,QueryType queryType)1160 QNetworkProxyQuery::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(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 */
QNetworkProxyQuery(const QNetworkConfiguration & networkConfiguration,quint16 bindPort,const QString & protocolTag,QueryType queryType)1187 QNetworkProxyQuery::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 */
QNetworkProxyQuery(const QNetworkProxyQuery & other)1201 QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkProxyQuery &other)
1202     : d(other.d)
1203 {
1204 }
1205 
1206 /*!
1207     Destroys this QNetworkProxyQuery object.
1208 */
~QNetworkProxyQuery()1209 QNetworkProxyQuery::~QNetworkProxyQuery()
1210 {
1211     // QSharedDataPointer automatically deletes
1212 }
1213 
1214 /*!
1215     Copies the contents of \a other.
1216 */
operator =(const QNetworkProxyQuery & other)1217 QNetworkProxyQuery &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 */
operator ==(const QNetworkProxyQuery & other) const1235 bool 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 */
queryType() const1250 QNetworkProxyQuery::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 */
setQueryType(QueryType type)1258 void 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 */
peerPort() const1273 int 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 */
setPeerPort(int port)1290 void 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 */
peerHostName() const1305 QString 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 */
setPeerHostName(const QString & hostname)1322 void QNetworkProxyQuery::setPeerHostName(const QString &hostname)
1323 {
1324     d->remote.setHost(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 */
localPort() const1333 int 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 */
setLocalPort(int port)1356 void 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 */
protocolTag() const1371 QString 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 */
setProtocolTag(const QString & protocolTag)1390 void 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 */
url() const1401 QUrl 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 */
setUrl(const QUrl & url)1415 void 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 */
networkConfiguration() const1428 QNetworkConfiguration 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 */
setNetworkConfiguration(const QNetworkConfiguration & networkConfiguration)1441 void 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 */
QNetworkProxyFactory()1493 QNetworkProxyFactory::QNetworkProxyFactory()
1494 {
1495 }
1496 
1497 /*!
1498     Destroys the QNetworkProxyFactory object.
1499 */
~QNetworkProxyFactory()1500 QNetworkProxyFactory::~QNetworkProxyFactory()
1501 {
1502 }
1503 
1504 /*!
1505     \since 5.8
1506 
1507     Returns whether the use of platform-specific proxy settings are enabled.
1508 */
usesSystemConfiguration()1509 bool 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 */
setUseSystemConfiguration(bool enable)1528 void 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 */
setApplicationProxyFactory(QNetworkProxyFactory * factory)1552 void 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 */
proxyForQuery(const QNetworkProxyQuery & query)1633 QList<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
operator <<(QDebug debug,const QNetworkProxy & proxy)1641 QDebug 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(QLatin1Char(' ')) << ']';
1687     return debug;
1688 }
1689 
operator <<(QDebug debug,const QNetworkProxyQuery & proxyQuery)1690 QDebug 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 
1706 QT_END_NAMESPACE
1707 
1708 #endif // QT_NO_NETWORKPROXY
1709