source: trunk/src/network/kernel/qnetworkproxy.cpp@ 603

Last change on this file since 603 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 41.0 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtNetwork module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42
43/*!
44 \class QNetworkProxy
45
46 \since 4.1
47
48 \brief The QNetworkProxy class provides a network layer proxy.
49
50 \reentrant
51 \ingroup network
52 \inmodule QtNetwork
53
54 QNetworkProxy provides the method for configuring network layer
55 proxy support to the Qt network classes. The currently supported
56 classes are QAbstractSocket, QTcpSocket, QUdpSocket, QTcpServer,
57 QNetworkAccessManager and QFtp. The proxy support is designed to
58 be as transparent as possible. This means that existing
59 network-enabled applications that you have written should
60 automatically support network proxy using the following code.
61
62 \snippet doc/src/snippets/code/src_network_kernel_qnetworkproxy.cpp 0
63
64 An alternative to setting an application wide proxy is to specify
65 the proxy for individual sockets using QAbstractSocket::setProxy()
66 and QTcpServer::setProxy(). In this way, it is possible to disable
67 the use of a proxy for specific sockets using the following code:
68
69 \snippet doc/src/snippets/code/src_network_kernel_qnetworkproxy.cpp 1
70
71 Network proxy is not used if the address used in \l
72 {QAbstractSocket::connectToHost()}{connectToHost()}, \l
73 {QUdpSocket::bind()}{bind()} or \l
74 {QTcpServer::listen()}{listen()} is equivalent to
75 QHostAddress::LocalHost or QHostAddress::LocalHostIPv6.
76
77 Each type of proxy support has certain restrictions associated with it.
78 You should read the \l{ProxyType} documentation carefully before
79 selecting a proxy type to use.
80
81 \note Changes made to currently connected sockets do not take effect.
82 If you need to change a connected socket, you should reconnect it.
83
84 \section1 SOCKS5
85
86 The SOCKS5 support in Qt 4 is based on \l{RFC 1928} and \l{RFC 1929}.
87 The supported authentication methods are no authentication and
88 username/password authentication. Both IPv4 and IPv6 are
89 supported. Domain names are resolved through the SOCKS5 server if
90 the QNetworkProxy::HostNameLookupCapability is enabled, otherwise
91 they are resolved locally and the IP address is sent to the
92 server. There are several things to remember when using SOCKS5
93 with QUdpSocket and QTcpServer:
94
95 With QUdpSocket, a call to \l {QUdpSocket::bind()}{bind()} may fail
96 with a timeout error. If a port number other than 0 is passed to
97 \l {QUdpSocket::bind()}{bind()}, it is not guaranteed that it is the
98 specified port that will be used.
99 Use \l{QUdpSocket::localPort()}{localPort()} and
100 \l{QUdpSocket::localAddress()}{localAddress()} to get the actual
101 address and port number in use. Because proxied UDP goes through
102 two UDP connections, it is more likely that packets will be dropped.
103
104 With QTcpServer a call to \l{QTcpServer::listen()}{listen()} may
105 fail with a timeout error. If a port number other than 0 is passed
106 to \l{QTcpServer::listen()}{listen()}, then it is not guaranteed
107 that it is the specified port that will be used.
108 Use \l{QTcpServer::serverPort()}{serverPort()} and
109 \l{QTcpServer::serverAddress()}{serverAddress()} to get the actual
110 address and port used to listen for connections. SOCKS5 only supports
111 one accepted connection per call to \l{QTcpServer::listen()}{listen()},
112 and each call is likely to result in a different
113 \l{QTcpServer::serverPort()}{serverPort()} being used.
114
115 \sa QAbstractSocket, QTcpServer
116*/
117
118/*!
119 \enum QNetworkProxy::ProxyType
120
121 This enum describes the types of network proxying provided in Qt.
122
123 There are two types of proxies that Qt understands:
124 transparent proxies and caching proxies. The first group consists
125 of proxies that can handle any arbitrary data transfer, while the
126 second can only handle specific requests. The caching proxies only
127 make sense for the specific classes where they can be used.
128
129 \value NoProxy No proxying is used
130 \value DefaultProxy Proxy is determined based on the application proxy set using setApplicationProxy()
131 \value Socks5Proxy \l Socks5 proxying is used
132 \value HttpProxy HTTP transparent proxying is used
133 \value HttpCachingProxy Proxying for HTTP requests only
134 \value FtpCachingProxy Proxying for FTP requests only
135
136 The table below lists different proxy types and their
137 capabilities. Since each proxy type has different capabilities, it
138 is important to understand them before choosing a proxy type.
139
140 \table
141 \header
142 \o Proxy type
143 \o Description
144 \o Default capabilities
145
146 \row
147 \o SOCKS 5
148 \o Generic proxy for any kind of connection. Supports TCP,
149 UDP, binding to a port (incoming connections) and
150 authentication.
151 \o TunnelingCapability, ListeningCapability,
152 UdpTunnelingCapability, HostNameLookupCapability
153
154 \row
155 \o HTTP
156 \o Implemented using the "CONNECT" command, supports only
157 outgoing TCP connections; supports authentication.
158 \o TunnelingCapability, CachingCapability, HostNameLookupCapability
159
160 \row
161 \o Caching-only HTTP
162 \o Implemented using normal HTTP commands, it is useful only
163 in the context of HTTP requests (see QNetworkAccessManager)
164 \o CachingCapability, HostNameLookupCapability
165
166 \row
167 \o Caching FTP
168 \o Implemented using an FTP proxy, it is useful only in the
169 context of FTP requests (see QFtp,
170 QNetworkAccessManager)
171 \o 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
219#include "qnetworkproxy.h"
220
221#ifndef QT_NO_NETWORKPROXY
222
223#include "private/qnetworkproxy_p.h"
224#include "private/qsocks5socketengine_p.h"
225#include "private/qhttpsocketengine_p.h"
226#include "qauthenticator.h"
227#include "qhash.h"
228#include "qmutex.h"
229#include "qurl.h"
230
231QT_BEGIN_NAMESPACE
232
233class QSocks5SocketEngineHandler;
234class QHttpSocketEngineHandler;
235
236class QGlobalNetworkProxy
237{
238public:
239 QGlobalNetworkProxy()
240 : mutex(QMutex::Recursive)
241 , applicationLevelProxy(0)
242 , applicationLevelProxyFactory(0)
243 , socks5SocketEngineHandler(0)
244 , httpSocketEngineHandler(0)
245 {
246 }
247
248 ~QGlobalNetworkProxy()
249 {
250 delete applicationLevelProxy;
251 delete applicationLevelProxyFactory;
252 delete socks5SocketEngineHandler;
253 delete httpSocketEngineHandler;
254 }
255
256 void init()
257 {
258 QMutexLocker lock(&mutex);
259#ifndef QT_NO_SOCKS5
260 if (!socks5SocketEngineHandler)
261 socks5SocketEngineHandler = new QSocks5SocketEngineHandler();
262#endif
263#ifndef QT_NO_HTTP
264 if (!httpSocketEngineHandler)
265 httpSocketEngineHandler = new QHttpSocketEngineHandler();
266#endif
267 }
268
269 void setApplicationProxy(const QNetworkProxy &proxy)
270 {
271 QMutexLocker lock(&mutex);
272 if (!applicationLevelProxy)
273 applicationLevelProxy = new QNetworkProxy;
274 *applicationLevelProxy = proxy;
275 delete applicationLevelProxyFactory;
276 applicationLevelProxyFactory = 0;
277 }
278
279 void setApplicationProxyFactory(QNetworkProxyFactory *factory)
280 {
281 QMutexLocker lock(&mutex);
282 if (applicationLevelProxy)
283 *applicationLevelProxy = QNetworkProxy();
284 delete applicationLevelProxyFactory;
285 applicationLevelProxyFactory = factory;
286 }
287
288 QNetworkProxy applicationProxy()
289 {
290 return proxyForQuery(QNetworkProxyQuery()).first();
291 }
292
293 QList<QNetworkProxy> proxyForQuery(const QNetworkProxyQuery &query);
294
295private:
296 QMutex mutex;
297 QNetworkProxy *applicationLevelProxy;
298 QNetworkProxyFactory *applicationLevelProxyFactory;
299 QSocks5SocketEngineHandler *socks5SocketEngineHandler;
300 QHttpSocketEngineHandler *httpSocketEngineHandler;
301};
302
303QList<QNetworkProxy> QGlobalNetworkProxy::proxyForQuery(const QNetworkProxyQuery &query)
304{
305 QMutexLocker locker(&mutex);
306
307 QList<QNetworkProxy> result;
308 if (!applicationLevelProxyFactory) {
309 if (applicationLevelProxy
310 && applicationLevelProxy->type() != QNetworkProxy::DefaultProxy)
311 result << *applicationLevelProxy;
312 else
313 result << QNetworkProxy(QNetworkProxy::NoProxy);
314 return result;
315 }
316
317 // we have a factory
318 result = applicationLevelProxyFactory->queryProxy(query);
319 if (result.isEmpty()) {
320 qWarning("QNetworkProxyFactory: factory %p has returned an empty result set",
321 applicationLevelProxyFactory);
322 result << QNetworkProxy(QNetworkProxy::NoProxy);
323 }
324 return result;
325}
326
327Q_GLOBAL_STATIC(QGlobalNetworkProxy, globalNetworkProxy)
328
329namespace {
330 template<bool> struct StaticAssertTest;
331 template<> struct StaticAssertTest<true> { enum { Value = 1 }; };
332}
333
334static inline void qt_noop_with_arg(int) {}
335#define q_static_assert(expr) qt_noop_with_arg(sizeof(StaticAssertTest< expr >::Value))
336
337static QNetworkProxy::Capabilities defaultCapabilitiesForType(QNetworkProxy::ProxyType type)
338{
339 q_static_assert(int(QNetworkProxy::DefaultProxy) == 0);
340 q_static_assert(int(QNetworkProxy::FtpCachingProxy) == 5);
341 static const int defaults[] =
342 {
343 /* [QNetworkProxy::DefaultProxy] = */
344 (int(QNetworkProxy::ListeningCapability) |
345 int(QNetworkProxy::TunnelingCapability) |
346 int(QNetworkProxy::UdpTunnelingCapability)),
347 /* [QNetworkProxy::Socks5Proxy] = */
348 (int(QNetworkProxy::TunnelingCapability) |
349 int(QNetworkProxy::ListeningCapability) |
350 int(QNetworkProxy::UdpTunnelingCapability) |
351 int(QNetworkProxy::HostNameLookupCapability)),
352 // it's weird to talk about the proxy capabilities of a "not proxy"...
353 /* [QNetworkProxy::NoProxy] = */
354 (int(QNetworkProxy::ListeningCapability) |
355 int(QNetworkProxy::TunnelingCapability) |
356 int(QNetworkProxy::UdpTunnelingCapability)),
357 /* [QNetworkProxy::HttpProxy] = */
358 (int(QNetworkProxy::TunnelingCapability) |
359 int(QNetworkProxy::CachingCapability) |
360 int(QNetworkProxy::HostNameLookupCapability)),
361 /* [QNetworkProxy::HttpCachingProxy] = */
362 (int(QNetworkProxy::CachingCapability) |
363 int(QNetworkProxy::HostNameLookupCapability)),
364 /* [QNetworkProxy::FtpCachingProxy] = */
365 (int(QNetworkProxy::CachingCapability) |
366 int(QNetworkProxy::HostNameLookupCapability)),
367 };
368
369 if (int(type) < 0 || int(type) > int(QNetworkProxy::FtpCachingProxy))
370 type = QNetworkProxy::DefaultProxy;
371 return QNetworkProxy::Capabilities(defaults[int(type)]);
372}
373
374class QNetworkProxyPrivate: public QSharedData
375{
376public:
377 QString hostName;
378 QString user;
379 QString password;
380 QNetworkProxy::Capabilities capabilities;
381 quint16 port;
382 QNetworkProxy::ProxyType type;
383 bool capabilitiesSet;
384
385 inline QNetworkProxyPrivate(QNetworkProxy::ProxyType t = QNetworkProxy::DefaultProxy,
386 const QString &h = QString(), quint16 p = 0,
387 const QString &u = QString(), const QString &pw = QString())
388 : hostName(h),
389 user(u),
390 password(pw),
391 capabilities(defaultCapabilitiesForType(t)),
392 port(p),
393 type(t),
394 capabilitiesSet(false)
395 { }
396
397 inline bool operator==(const QNetworkProxyPrivate &other) const
398 {
399 return type == other.type &&
400 port == other.port &&
401 hostName == other.hostName &&
402 user == other.user &&
403 password == other.password &&
404 capabilities == other.capabilities;
405 }
406};
407
408template<> void QSharedDataPointer<QNetworkProxyPrivate>::detach()
409{
410 if (d && d->ref == 1)
411 return;
412 QNetworkProxyPrivate *x = (d ? new QNetworkProxyPrivate(*d)
413 : new QNetworkProxyPrivate);
414 x->ref.ref();
415 if (d && !d->ref.deref())
416 delete d;
417 d = x;
418}
419
420/*!
421 Constructs a QNetworkProxy with DefaultProxy type; the proxy type is
422 determined by applicationProxy(), which defaults to NoProxy.
423
424 \sa setType(), setApplicationProxy()
425*/
426QNetworkProxy::QNetworkProxy()
427 : d(0)
428{
429 globalNetworkProxy()->init();
430}
431
432/*!
433 Constructs a QNetworkProxy with \a type, \a hostName, \a port,
434 \a user and \a password.
435
436 The default capabilities for proxy type \a type are set automatically.
437
438 \sa capabilities()
439*/
440QNetworkProxy::QNetworkProxy(ProxyType type, const QString &hostName, quint16 port,
441 const QString &user, const QString &password)
442 : d(new QNetworkProxyPrivate(type, hostName, port, user, password))
443{
444 globalNetworkProxy()->init();
445}
446
447/*!
448 Constructs a copy of \a other.
449*/
450QNetworkProxy::QNetworkProxy(const QNetworkProxy &other)
451 : d(other.d)
452{
453}
454
455/*!
456 Destroys the QNetworkProxy object.
457*/
458QNetworkProxy::~QNetworkProxy()
459{
460 // QSharedDataPointer takes care of deleting for us
461}
462
463/*!
464 \since 4.4
465
466 Compares the value of this network proxy to \a other and returns true
467 if they are equal (same proxy type, server as well as username and password)
468*/
469bool QNetworkProxy::operator==(const QNetworkProxy &other) const
470{
471 return d == other.d || (d && other.d && *d == *other.d);
472}
473
474/*!
475 \fn bool QNetworkProxy::operator!=(const QNetworkProxy &other) const
476 \since 4.4
477
478 Compares the value of this network proxy to \a other and returns true
479 if they differ.
480\*/
481
482/*!
483 \since 4.2
484
485 Assigns the value of the network proxy \a other to this network proxy.
486*/
487QNetworkProxy &QNetworkProxy::operator=(const QNetworkProxy &other)
488{
489 d = other.d;
490 return *this;
491}
492
493/*!
494 Sets the proxy type for this instance to be \a type.
495
496 Note that changing the type of a proxy does not change
497 the set of capabilities this QNetworkProxy object holds if any
498 capabilities have been set with setCapabilities().
499
500 \sa type(), setCapabilities()
501*/
502void QNetworkProxy::setType(QNetworkProxy::ProxyType type)
503{
504 d->type = type;
505 if (!d->capabilitiesSet)
506 d->capabilities = defaultCapabilitiesForType(type);
507}
508
509/*!
510 Returns the proxy type for this instance.
511
512 \sa setType()
513*/
514QNetworkProxy::ProxyType QNetworkProxy::type() const
515{
516 return d ? d->type : DefaultProxy;
517}
518
519/*!
520 \since 4.5
521
522 Sets the capabilities of this proxy to \a capabilities.
523
524 \sa setType(), capabilities()
525*/
526void QNetworkProxy::setCapabilities(Capabilities capabilities)
527{
528 d->capabilities = capabilities;
529 d->capabilitiesSet = true;
530}
531
532/*!
533 \since 4.5
534
535 Returns the capabilities of this proxy server.
536
537 \sa setCapabilities(), type()
538*/
539QNetworkProxy::Capabilities QNetworkProxy::capabilities() const
540{
541 return d ? d->capabilities : defaultCapabilitiesForType(DefaultProxy);
542}
543
544/*!
545 \since 4.4
546
547 Returns true if this proxy supports the
548 QNetworkProxy::CachingCapability capability.
549
550 In Qt 4.4, the capability was tied to the proxy type, but since Qt
551 4.5 it is possible to remove the capability of caching from a
552 proxy by calling setCapabilities().
553
554 \sa capabilities(), type(), isTransparentProxy()
555*/
556bool QNetworkProxy::isCachingProxy() const
557{
558 return capabilities() & CachingCapability;
559}
560
561/*!
562 \since 4.4
563
564 Returns true if this proxy supports transparent tunneling of TCP
565 connections. This matches the QNetworkProxy::TunnelingCapability
566 capability.
567
568 In Qt 4.4, the capability was tied to the proxy type, but since Qt
569 4.5 it is possible to remove the capability of caching from a
570 proxy by calling setCapabilities().
571
572 \sa capabilities(), type(), isCachingProxy()
573*/
574bool QNetworkProxy::isTransparentProxy() const
575{
576 return capabilities() & TunnelingCapability;
577}
578
579/*!
580 Sets the user name for proxy authentication to be \a user.
581
582 \sa user(), setPassword(), password()
583*/
584void QNetworkProxy::setUser(const QString &user)
585{
586 d->user = user;
587}
588
589/*!
590 Returns the user name used for authentication.
591
592 \sa setUser(), setPassword(), password()
593*/
594QString QNetworkProxy::user() const
595{
596 return d ? d->user : QString();
597}
598
599/*!
600 Sets the password for proxy authentication to be \a password.
601
602 \sa user(), setUser(), password()
603*/
604void QNetworkProxy::setPassword(const QString &password)
605{
606 d->password = password;
607}
608
609/*!
610 Returns the password used for authentication.
611
612 \sa user(), setPassword(), setUser()
613*/
614QString QNetworkProxy::password() const
615{
616 return d ? d->password : QString();
617}
618
619/*!
620 Sets the host name of the proxy host to be \a hostName.
621
622 \sa hostName(), setPort(), port()
623*/
624void QNetworkProxy::setHostName(const QString &hostName)
625{
626 d->hostName = hostName;
627}
628
629/*!
630 Returns the host name of the proxy host.
631
632 \sa setHostName(), setPort(), port()
633*/
634QString QNetworkProxy::hostName() const
635{
636 return d ? d->hostName : QString();
637}
638
639/*!
640 Sets the port of the proxy host to be \a port.
641
642 \sa hostName(), setHostName(), port()
643*/
644void QNetworkProxy::setPort(quint16 port)
645{
646 d->port = port;
647}
648
649/*!
650 Returns the port of the proxy host.
651
652 \sa setHostName(), setPort(), hostName()
653*/
654quint16 QNetworkProxy::port() const
655{
656 return d ? d->port : 0;
657}
658
659/*!
660 Sets the application level network proxying to be \a networkProxy.
661
662 If a QAbstractSocket or QTcpSocket has the
663 QNetworkProxy::DefaultProxy type, then the QNetworkProxy set with
664 this function is used. If you want more flexibility in determining
665 which the proxy, use the QNetworkProxyFactory class.
666
667 Setting a default proxy value with this function will override the
668 application proxy factory set with
669 QNetworkProxyFactory::setApplicationProxyFactory.
670
671 \sa QNetworkProxyFactory, applicationProxy(), QAbstractSocket::setProxy(), QTcpServer::setProxy()
672*/
673void QNetworkProxy::setApplicationProxy(const QNetworkProxy &networkProxy)
674{
675 if (globalNetworkProxy()) {
676 // don't accept setting the proxy to DefaultProxy
677 if (networkProxy.type() == DefaultProxy)
678 globalNetworkProxy()->setApplicationProxy(QNetworkProxy::NoProxy);
679 else
680 globalNetworkProxy()->setApplicationProxy(networkProxy);
681 }
682}
683
684/*!
685 Returns the application level network proxying.
686
687 If a QAbstractSocket or QTcpSocket has the
688 QNetworkProxy::DefaultProxy type, then the QNetworkProxy returned
689 by this function is used.
690
691 \sa QNetworkProxyFactory, setApplicationProxy(), QAbstractSocket::proxy(), QTcpServer::proxy()
692*/
693QNetworkProxy QNetworkProxy::applicationProxy()
694{
695 if (globalNetworkProxy())
696 return globalNetworkProxy()->applicationProxy();
697 return QNetworkProxy();
698}
699
700class QNetworkProxyQueryPrivate: public QSharedData
701{
702public:
703 inline QNetworkProxyQueryPrivate()
704 : localPort(-1), type(QNetworkProxyQuery::TcpSocket)
705 { }
706
707 bool operator==(const QNetworkProxyQueryPrivate &other) const
708 {
709 return type == other.type &&
710 localPort == other.localPort &&
711 remote == other.remote;
712 }
713
714 QUrl remote;
715 int localPort;
716 QNetworkProxyQuery::QueryType type;
717};
718
719template<> void QSharedDataPointer<QNetworkProxyQueryPrivate>::detach()
720{
721 if (d && d->ref == 1)
722 return;
723 QNetworkProxyQueryPrivate *x = (d ? new QNetworkProxyQueryPrivate(*d)
724 : new QNetworkProxyQueryPrivate);
725 x->ref.ref();
726 if (d && !d->ref.deref())
727 delete d;
728 d = x;
729}
730
731/*!
732 \class QNetworkProxyQuery
733 \since 4.5
734 \inmodule QtNetwork
735 \brief The QNetworkProxyQuery class is used to query the proxy
736 settings for a socket
737
738 QNetworkProxyQuery holds the details of a socket being created or
739 request being made. It is used by QNetworkProxy and
740 QNetworkProxyFactory to allow applications to have a more
741 fine-grained control over which proxy servers are used, depending
742 on the details of the query. This allows an application to apply
743 different settings, according to the protocol or destination
744 hostname, for instance.
745
746 QNetworkProxyQuery supports the following criteria for selecting
747 the proxy:
748
749 \list
750 \o the type of query
751 \o the local port number to use
752 \o the destination host name
753 \o the destination port number
754 \o the protocol name, such as "http" or "ftp"
755 \o the URL being requested
756 \endlist
757
758 The destination host name is the host in the connection in the
759 case of outgoing connection sockets. It is the \c hostName
760 parameter passed to QTcpSocket::connectToHost() or the host
761 component of a URL requested with QNetworkRequest.
762
763 The destination port number is the requested port to connect to in
764 the case of outgoing sockets, while the local port number is the
765 port the socket wishes to use locally before attempting the
766 external connection. In most cases, the local port number is used
767 by listening sockets only (QTcpSocket) or by datagram sockets
768 (QUdpSocket).
769
770 The protocol name is an arbitrary string that indicates the type
771 of connection being attempted. For example, it can match the
772 scheme of a URL, like "http", "https" and "ftp". In most cases,
773 the proxy selection will not change depending on the protocol, but
774 this information is provided in case a better choice can be made,
775 like choosing an caching HTTP proxy for HTTP-based connections,
776 but a more powerful SOCKSv5 proxy for all others.
777
778 Some of the criteria may not make sense in all of the types of
779 query. The following table lists the criteria that are most
780 commonly used, according to the type of query.
781
782 \table
783 \header
784 \o Query type
785 \o Description
786
787 \row
788 \o TcpSocket
789 \o Normal sockets requesting a connection to a remote server,
790 like QTcpSocket. The peer hostname and peer port match the
791 values passed to QTcpSocket::connectToHost(). The local port
792 is usually -1, indicating the socket has no preference in
793 which port should be used. The URL component is not used.
794
795 \row
796 \o UdpSocket
797 \o Datagram-based sockets, which can both send and
798 receive. The local port, remote host or remote port fields
799 can all be used or be left unused, depending on the
800 characteristics of the socket. The URL component is not used.
801
802 \row
803 \o TcpServer
804 \o Passive server sockets that listen on a port and await
805 incoming connections from the network. Normally, only the
806 local port is used, but the remote address could be used in
807 specific circumstances, for example to indicate which remote
808 host a connection is expected from. The URL component is not used.
809
810 \row
811 \o UrlRequest
812 \o A more high-level request, such as those coming from
813 QNetworkAccessManager. These requests will inevitably use an
814 outgoing TCP socket, but the this query type is provided to
815 indicate that more detailed information is present in the URL
816 component. For ease of implementation, the URL's host and
817 port are set as the destination address.
818 \endtable
819
820 It should be noted that any of the criteria may be missing or
821 unknown (an empty QString for the hostname or protocol name, -1
822 for the port numbers). If that happens, the functions executing
823 the query should make their best guess or apply some
824 implementation-defined default values.
825
826 \sa QNetworkProxy, QNetworkProxyFactory, QNetworkAccessManager,
827 QAbstractSocket::setProxy()
828*/
829
830/*!
831 \enum QNetworkProxyQuery::QueryType
832
833 Describes the type of one QNetworkProxyQuery query.
834
835 \value TcpSocket a normal, outgoing TCP socket
836 \value UdpSocket a datagram-based UDP socket, which could send
837 to multiple destinations
838 \value TcpServer a TCP server that listens for incoming
839 connections from the network
840 \value UrlRequest a more complex request which involves loading
841 of a URL
842
843 \sa queryType(), setQueryType()
844*/
845
846/*!
847 Constructs a default QNetworkProxyQuery object. By default, the
848 query type will be QNetworkProxyQuery::TcpSocket.
849*/
850QNetworkProxyQuery::QNetworkProxyQuery()
851{
852}
853
854/*!
855 Constructs a QNetworkProxyQuery with the URL \a requestUrl and
856 sets the query type to \a queryType.
857
858 \sa protocolTag(), peerHostName(), peerPort()
859*/
860QNetworkProxyQuery::QNetworkProxyQuery(const QUrl &requestUrl, QueryType queryType)
861{
862 d->remote = requestUrl;
863 d->type = queryType;
864}
865
866/*!
867 Constructs a QNetworkProxyQuery of type \a queryType and sets the
868 protocol tag to be \a protocolTag. This constructor is suitable
869 for QNetworkProxyQuery::TcpSocket queries, because it sets the
870 peer hostname to \a hostname and the peer's port number to \a
871 port.
872*/
873QNetworkProxyQuery::QNetworkProxyQuery(const QString &hostname, int port,
874 const QString &protocolTag,
875 QueryType queryType)
876{
877 d->remote.setScheme(protocolTag);
878 d->remote.setHost(hostname);
879 d->remote.setPort(port);
880 d->type = queryType;
881}
882
883/*!
884 Constructs a QNetworkProxyQuery of type \a queryType and sets the
885 protocol tag to be \a protocolTag. This constructor is suitable
886 for QNetworkProxyQuery::TcpSocket queries because it sets the
887 local port number to \a bindPort.
888
889 Note that \a bindPort is of type quint16 to indicate the exact
890 port number that is requested. The value of -1 (unknown) is not
891 allowed in this context.
892
893 \sa localPort()
894*/
895QNetworkProxyQuery::QNetworkProxyQuery(quint16 bindPort, const QString &protocolTag,
896 QueryType queryType)
897{
898 d->remote.setScheme(protocolTag);
899 d->localPort = bindPort;
900 d->type = queryType;
901}
902
903/*!
904 Constructs a QNetworkProxyQuery object that is a copy of \a other.
905*/
906QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkProxyQuery &other)
907 : d(other.d)
908{
909}
910
911/*!
912 Destroys this QNetworkProxyQuery object.
913*/
914QNetworkProxyQuery::~QNetworkProxyQuery()
915{
916 // QSharedDataPointer automatically deletes
917}
918
919/*!
920 Copies the contents of \a other.
921*/
922QNetworkProxyQuery &QNetworkProxyQuery::operator=(const QNetworkProxyQuery &other)
923{
924 d = other.d;
925 return *this;
926}
927
928/*!
929 Returns true if this QNetworkProxyQuery object contains the same
930 data as \a other.
931*/
932bool QNetworkProxyQuery::operator==(const QNetworkProxyQuery &other) const
933{
934 return d == other.d || (d && other.d && *d == *other.d);
935}
936
937/*!
938 \fn bool QNetworkProxyQuery::operator!=(const QNetworkProxyQuery &other) const
939
940 Returns true if this QNetworkProxyQuery object does not contain
941 the same data as \a other.
942*/
943
944/*!
945 Returns the query type.
946*/
947QNetworkProxyQuery::QueryType QNetworkProxyQuery::queryType() const
948{
949 return d ? d->type : TcpSocket;
950}
951
952/*!
953 Sets the query type of this object to be \a type.
954*/
955void QNetworkProxyQuery::setQueryType(QueryType type)
956{
957 d->type = type;
958}
959
960/*!
961 Returns the port number for the outgoing request or -1 if the port
962 number is not known.
963
964 If the query type is QNetworkProxyQuery::UrlRequest, this function
965 returns the port number of the URL being requested. In general,
966 frameworks will fill in the port number from their default values.
967
968 \sa peerHostName(), localPort(), setPeerPort()
969*/
970int QNetworkProxyQuery::peerPort() const
971{
972 return d ? d->remote.port() : -1;
973}
974
975/*!
976 Sets the requested port number for the outgoing connection to be
977 \a port. Valid values are 1 to 65535, or -1 to indicate that the
978 remote port number is unknown.
979
980 The peer port number can also be used to indicate the expected
981 port number of an incoming connection in the case of
982 QNetworkProxyQuery::UdpSocket or QNetworkProxyQuery::TcpServer
983 query types.
984
985 \sa peerPort(), setPeerHostName(), setLocalPort()
986*/
987void QNetworkProxyQuery::setPeerPort(int port)
988{
989 d->remote.setPort(port);
990}
991
992/*!
993 Returns the host name or IP address being of the outgoing
994 connection being requested, or an empty string if the remote
995 hostname is not known.
996
997 If the query type is QNetworkProxyQuery::UrlRequest, this function
998 returns the host component of the URL being requested.
999
1000 \sa peerPort(), localPort(), setPeerHostName()
1001*/
1002QString QNetworkProxyQuery::peerHostName() const
1003{
1004 return d ? d->remote.host() : QString();
1005}
1006
1007/*!
1008 Sets the hostname of the outgoing connection being requested to \a
1009 hostname. An empty hostname can be used to indicate that the
1010 remote host is unknown.
1011
1012 The peer host name can also be used to indicate the expected
1013 source address of an incoming connection in the case of
1014 QNetworkProxyQuery::UdpSocket or QNetworkProxyQuery::TcpServer
1015 query types.
1016
1017 \sa peerHostName(), setPeerPort(), setLocalPort()
1018*/
1019void QNetworkProxyQuery::setPeerHostName(const QString &hostname)
1020{
1021 d->remote.setHost(hostname);
1022}
1023
1024/*!
1025 Returns the port number of the socket that will accept incoming
1026 packets from remote servers or -1 if the port is not known.
1027
1028 \sa peerPort(), peerHostName(), setLocalPort()
1029*/
1030int QNetworkProxyQuery::localPort() const
1031{
1032 return d ? d->localPort : -1;
1033}
1034
1035/*!
1036 Sets the port number that the socket wishes to use locally to
1037 accept incoming packets from remote servers to \a port. The local
1038 port is most often used with the QNetworkProxyQuery::TcpServer
1039 and QNetworkProxyQuery::UdpSocket query types.
1040
1041 Valid values are 0 to 65535 (with 0 indicating that any port
1042 number will be acceptable) or -1, which means the local port
1043 number is unknown or not applicable.
1044
1045 In some circumstances, for special protocols, it's the local port
1046 number can also be used with a query of type
1047 QNetworkProxyQuery::TcpSocket. When that happens, the socket is
1048 indicating it wishes to use the port number \a port when
1049 connecting to a remote host.
1050
1051 \sa localPort(), setPeerPort(), setPeerHostName()
1052*/
1053void QNetworkProxyQuery::setLocalPort(int port)
1054{
1055 d->localPort = port;
1056}
1057
1058/*!
1059 Returns the protocol tag for this QNetworkProxyQuery object, or an
1060 empty QString in case the protocol tag is unknown.
1061
1062 In the case of queries of type QNetworkProxyQuery::UrlRequest,
1063 this function returns the value of the scheme component of the
1064 URL.
1065
1066 \sa setProtocolTag(), url()
1067*/
1068QString QNetworkProxyQuery::protocolTag() const
1069{
1070 return d ? d->remote.scheme() : QString();
1071}
1072
1073/*!
1074 Sets the protocol tag for this QNetworkProxyQuery object to be \a
1075 protocolTag.
1076
1077 The protocol tag is an arbitrary string that indicates which
1078 protocol is being talked over the socket, such as "http", "xmpp",
1079 "telnet", etc. The protocol tag is used by the backend to
1080 return a request that is more specific to the protocol in
1081 question: for example, a HTTP connection could be use a caching
1082 HTTP proxy server, while all other connections use a more powerful
1083 SOCKSv5 proxy server.
1084
1085 \sa protocolTag()
1086*/
1087void QNetworkProxyQuery::setProtocolTag(const QString &protocolTag)
1088{
1089 d->remote.setScheme(protocolTag);
1090}
1091
1092/*!
1093 Returns the URL component of this QNetworkProxyQuery object in
1094 case of a query of type QNetworkProxyQuery::UrlRequest.
1095
1096 \sa setUrl()
1097*/
1098QUrl QNetworkProxyQuery::url() const
1099{
1100 return d ? d->remote : QUrl();
1101}
1102
1103/*!
1104 Sets the URL component of this QNetworkProxyQuery object to be \a
1105 url. Setting the URL will also set the protocol tag, the remote
1106 host name and port number. This is done so as to facilitate the
1107 implementation of the code that determines the proxy server to be
1108 used.
1109
1110 \sa url(), peerHostName(), peerPort()
1111*/
1112void QNetworkProxyQuery::setUrl(const QUrl &url)
1113{
1114 d->remote = url;
1115}
1116
1117/*!
1118 \class QNetworkProxyFactory
1119 \brief The QNetworkProxyFactory class provides fine-grained proxy selection.
1120 \since 4.5
1121
1122 \ingroup network
1123 \inmodule QtNetwork
1124
1125 QNetworkProxyFactory is an extension to QNetworkProxy, allowing
1126 applications to have a more fine-grained control over which proxy
1127 servers are used, depending on the socket requesting the
1128 proxy. This allows an application to apply different settings,
1129 according to the protocol or destination hostname, for instance.
1130
1131 QNetworkProxyFactory can be set globally for an application, in
1132 which case it will override any global proxies set with
1133 QNetworkProxy::setApplicationProxy(). If set globally, any sockets
1134 created with Qt will query the factory to determine the proxy to
1135 be used.
1136
1137 A factory can also be set in certain frameworks that support
1138 multiple connections, such as QNetworkAccessManager. When set on
1139 such object, the factory will be queried for sockets created by
1140 that framework only.
1141*/
1142
1143/*!
1144 Creates a QNetworkProxyFactory object.
1145
1146 Since QNetworkProxyFactory is an abstract class, you cannot create
1147 objects of type QNetworkProxyFactory directly.
1148*/
1149QNetworkProxyFactory::QNetworkProxyFactory()
1150{
1151}
1152
1153/*!
1154 Destroys the QNetworkProxyFactory object.
1155*/
1156QNetworkProxyFactory::~QNetworkProxyFactory()
1157{
1158}
1159
1160
1161/*!
1162 Enables the use of the platform-specific proxy settings, and only those.
1163 See systemProxyForQuery() for more information.
1164
1165 Internally, this method (when called with \a enable set to true)
1166 sets an application-wide proxy factory. For this reason, this method
1167 is mutually exclusive with setApplicationProxyFactory: calling
1168 setApplicationProxyFactory overrides the use of the system-wide proxy,
1169 and calling setUseSystemConfiguration overrides any
1170 application proxy or proxy factory that was previously set.
1171
1172 \since 4.6
1173*/
1174void QNetworkProxyFactory::setUseSystemConfiguration(bool enable)
1175{
1176 if (enable) {
1177 setApplicationProxyFactory(new QSystemConfigurationProxyFactory);
1178 } else {
1179 setApplicationProxyFactory(0);
1180 }
1181}
1182
1183/*!
1184 Sets the application-wide proxy factory to be \a factory. This
1185 function will take ownership of that object and will delete it
1186 when necessary.
1187
1188 The application-wide proxy is used as a last-resort when all other
1189 proxy selection requests returned QNetworkProxy::DefaultProxy. For
1190 example, QTcpSocket objects can have a proxy set with
1191 QTcpSocket::setProxy, but if none is set, the proxy factory class
1192 set with this function will be queried.
1193
1194 If you set a proxy factory with this function, any application
1195 level proxies set with QNetworkProxy::setApplicationProxy will be
1196 overridden.
1197
1198 \sa QNetworkProxy::setApplicationProxy(),
1199 QAbstractSocket::proxy(), QAbstractSocket::setProxy()
1200*/
1201void QNetworkProxyFactory::setApplicationProxyFactory(QNetworkProxyFactory *factory)
1202{
1203 if (globalNetworkProxy())
1204 globalNetworkProxy()->setApplicationProxyFactory(factory);
1205}
1206
1207/*!
1208 \fn QList<QNetworkProxy> QNetworkProxyFactory::queryProxy(const QNetworkProxyQuery &query)
1209
1210 This function examines takes the query request, \a query,
1211 examines the details of the type of socket or request and returns
1212 a list of QNetworkProxy objects that indicate the proxy servers to
1213 be used, in order of preference.
1214
1215 When reimplementing this class, take care to return at least one
1216 element.
1217
1218 If you cannot determine a better proxy alternative, use
1219 QNetworkProxy::DefaultProxy, which tells the code querying for a
1220 proxy to use a higher alternative. For example, if this factory is
1221 set to a QNetworkAccessManager object, DefaultProxy will tell it
1222 to query the application-level proxy settings.
1223
1224 If this factory is set as the application proxy factory,
1225 DefaultProxy and NoProxy will have the same meaning.
1226*/
1227
1228/*!
1229 \fn QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &query)
1230
1231 This function examines takes the query request, \a query,
1232 examines the details of the type of socket or request and returns
1233 a list of QNetworkProxy objects that indicate the proxy servers to
1234 be used, in order of preference.
1235
1236 This function can be used to determine the platform-specific proxy
1237 settings. This function will use the libraries provided by the
1238 operating system to determine the proxy for a given connection, if
1239 such libraries exist. If they don't, this function will just return a
1240 QNetworkProxy of type QNetworkProxy::NoProxy.
1241
1242 On Windows, this function will use the WinHTTP DLL functions. Despite
1243 its name, Microsoft suggests using it for all applications that
1244 require network connections, not just HTTP. This will respect the
1245 proxy settings set on the registry with the proxycfg.exe tool. If
1246 those settings are not found, this function will attempt to obtain
1247 Internet Explorer's settings and use them.
1248
1249 On MacOS X, this function will obtain the proxy settings using the
1250 SystemConfiguration framework from Apple. It will apply the FTP,
1251 HTTP and HTTPS proxy configurations for queries that contain the
1252 protocol tag "ftp", "http" and "https", respectively. If the SOCKS
1253 proxy is enabled in that configuration, this function will use the
1254 SOCKS server for all queries. If SOCKS isn't enabled, it will use
1255 the HTTPS proxy for all TcpSocket and UrlRequest queries.
1256
1257 On other systems, there is no standardised method of obtaining the
1258 system proxy configuration. This function may be improved in
1259 future versions to support those systems.
1260
1261 \section1 Limitations
1262
1263 These are the limitations for the current version of this
1264 function. Future versions of Qt may lift some of the limitations
1265 listed here.
1266
1267 On MacOS X, this function will ignore the Proxy Auto Configuration
1268 settings, since it cannot execute the associated ECMAScript code.
1269*/
1270
1271/*!
1272 This function examines takes the query request, \a query,
1273 examines the details of the type of socket or request and returns
1274 a list of QNetworkProxy objects that indicate the proxy servers to
1275 be used, in order of preference.
1276*/
1277QList<QNetworkProxy> QNetworkProxyFactory::proxyForQuery(const QNetworkProxyQuery &query)
1278{
1279 if (!globalNetworkProxy())
1280 return QList<QNetworkProxy>() << QNetworkProxy(QNetworkProxy::NoProxy);
1281 return globalNetworkProxy()->proxyForQuery(query);
1282}
1283
1284QT_END_NAMESPACE
1285
1286#endif // QT_NO_NETWORKPROXY
Note: See TracBrowser for help on using the repository browser.