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

Last change on this file since 352 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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