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

Last change on this file since 561 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;