source: trunk/src/network/access/qnetworkaccessbackend.cpp@ 632

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

trunk: Merged in qt 4.6.1 sources.

File size: 9.4 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#include "qnetworkaccessbackend_p.h"
43#include "qnetworkaccessmanager_p.h"
44#include "qnetworkrequest.h"
45#include "qnetworkreply.h"
46#include "qnetworkreply_p.h"
47#include "QtCore/qhash.h"
48#include "QtCore/qmutex.h"
49
50#include "qnetworkaccesscachebackend_p.h"
51#include "qabstractnetworkcache.h"
52
53#include "private/qnoncontiguousbytedevice_p.h"
54
55QT_BEGIN_NAMESPACE
56
57static bool factoryDataShutdown = false;
58class QNetworkAccessBackendFactoryData: public QList<QNetworkAccessBackendFactory *>
59{
60public:
61 QNetworkAccessBackendFactoryData() : mutex(QMutex::Recursive) { }
62 ~QNetworkAccessBackendFactoryData()
63 {
64 QMutexLocker locker(&mutex); // why do we need to lock?
65 factoryDataShutdown = true;
66 }
67
68 QMutex mutex;
69};
70Q_GLOBAL_STATIC(QNetworkAccessBackendFactoryData, factoryData)
71
72QNetworkAccessBackendFactory::QNetworkAccessBackendFactory()
73{
74 QMutexLocker locker(&factoryData()->mutex);
75 factoryData()->prepend(this);
76}
77
78QNetworkAccessBackendFactory::~QNetworkAccessBackendFactory()
79{
80 if (!factoryDataShutdown) {
81 QMutexLocker locker(&factoryData()->mutex);
82 factoryData()->removeAll(this);
83 }
84}
85
86QNetworkAccessBackend *QNetworkAccessManagerPrivate::findBackend(QNetworkAccessManager::Operation op,
87 const QNetworkRequest &request)
88{
89 QNetworkRequest::CacheLoadControl mode =
90 static_cast<QNetworkRequest::CacheLoadControl>(
91 request.attribute(QNetworkRequest::CacheLoadControlAttribute,
92 QNetworkRequest::PreferNetwork).toInt());
93 if (mode == QNetworkRequest::AlwaysCache
94 && (op == QNetworkAccessManager::GetOperation
95 || op == QNetworkAccessManager::HeadOperation)) {
96 QNetworkAccessBackend *backend = new QNetworkAccessCacheBackend;
97 backend->manager = this;
98 return backend;
99 }
100
101 if (!factoryDataShutdown) {
102 QMutexLocker locker(&factoryData()->mutex);
103 QNetworkAccessBackendFactoryData::ConstIterator it = factoryData()->constBegin(),
104 end = factoryData()->constEnd();
105 while (it != end) {
106 QNetworkAccessBackend *backend = (*it)->create(op, request);
107 if (backend) {
108 backend->manager = this;
109 return backend; // found a factory that handled our request
110 }
111 ++it;
112 }
113 }
114 return 0;
115}
116
117QNonContiguousByteDevice* QNetworkAccessBackend::createUploadByteDevice()
118{
119 QNonContiguousByteDevice* device = 0;
120
121 if (reply->outgoingDataBuffer)
122 device = QNonContiguousByteDeviceFactory::create(reply->outgoingDataBuffer);
123 else
124 device = QNonContiguousByteDeviceFactory::create(reply->outgoingData);
125
126 bool bufferDisallowed =
127 reply->request.attribute(QNetworkRequest::DoNotBufferUploadDataAttribute,
128 QVariant(false)) == QVariant(true);
129 if (bufferDisallowed)
130 device->disableReset();
131
132 // make sure we delete this later
133 device->setParent(this);
134
135 connect(device, SIGNAL(readProgress(qint64,qint64)), this, SLOT(emitReplyUploadProgress(qint64,qint64)));
136
137 return device;
138}
139
140// need to have this function since the reply is a private member variable
141// and the special backends need to access this.
142void QNetworkAccessBackend::emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal)
143{
144 if (reply->isFinished())
145 return;
146 reply->emitUploadProgress(bytesSent, bytesTotal);
147}
148
149QNetworkAccessBackend::QNetworkAccessBackend()
150 : manager(0)
151 , reply(0)
152{
153}
154
155QNetworkAccessBackend::~QNetworkAccessBackend()
156{
157}
158
159void QNetworkAccessBackend::downstreamReadyWrite()
160{
161 // do nothing
162}
163
164void QNetworkAccessBackend::copyFinished(QIODevice *)
165{
166 // do nothing
167}
168
169void QNetworkAccessBackend::ignoreSslErrors()
170{
171 // do nothing
172}
173
174void QNetworkAccessBackend::ignoreSslErrors(const QList<QSslError> &errors)
175{
176 Q_UNUSED(errors);
177 // do nothing
178}
179
180void QNetworkAccessBackend::fetchSslConfiguration(QSslConfiguration &) const
181{
182 // do nothing
183}
184
185void QNetworkAccessBackend::setSslConfiguration(const QSslConfiguration &)
186{
187 // do nothing
188}
189
190QNetworkCacheMetaData QNetworkAccessBackend::fetchCacheMetaData(const QNetworkCacheMetaData &) const
191{
192 return QNetworkCacheMetaData();
193}
194
195QNetworkAccessManager::Operation QNetworkAccessBackend::operation() const
196{
197 return reply->operation;
198}
199
200QNetworkRequest QNetworkAccessBackend::request() const
201{
202 return reply->request;
203}
204
205#ifndef QT_NO_NETWORKPROXY
206QList<QNetworkProxy> QNetworkAccessBackend::proxyList() const
207{
208 return reply->proxyList;
209}
210#endif
211
212QAbstractNetworkCache *QNetworkAccessBackend::networkCache() const
213{
214 if (!manager)
215 return 0;
216 return manager->networkCache;
217}
218
219void QNetworkAccessBackend::setCachingEnabled(bool enable)
220{
221 reply->setCachingEnabled(enable);
222}
223
224bool QNetworkAccessBackend::isCachingEnabled() const
225{
226 return reply->isCachingEnabled();
227}
228
229qint64 QNetworkAccessBackend::nextDownstreamBlockSize() const
230{
231 return reply->nextDownstreamBlockSize();
232}
233
234void QNetworkAccessBackend::writeDownstreamData(QByteDataBuffer &list)
235{
236 reply->appendDownstreamData(list);
237}
238
239void QNetworkAccessBackend::writeDownstreamData(QIODevice *data)
240{
241 reply->appendDownstreamData(data);
242}
243
244QVariant QNetworkAccessBackend::header(QNetworkRequest::KnownHeaders header) const
245{
246 return reply->q_func()->header(header);
247}
248
249void QNetworkAccessBackend::setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
250{
251 reply->setCookedHeader(header, value);
252}
253
254bool QNetworkAccessBackend::hasRawHeader(const QByteArray &headerName) const
255{
256 return reply->q_func()->hasRawHeader(headerName);
257}
258
259QByteArray QNetworkAccessBackend::rawHeader(const QByteArray &headerName) const
260{
261 return reply->q_func()->rawHeader(headerName);
262}
263
264QList<QByteArray> QNetworkAccessBackend::rawHeaderList() const
265{
266 return reply->q_func()->rawHeaderList();
267}
268
269void QNetworkAccessBackend::setRawHeader(const QByteArray &headerName, const QByteArray &headerValue)
270{
271 reply->setRawHeader(headerName, headerValue);
272}
273
274QVariant QNetworkAccessBackend::attribute(QNetworkRequest::Attribute code) const
275{
276 return reply->q_func()->attribute(code);
277}
278
279void QNetworkAccessBackend::setAttribute(QNetworkRequest::Attribute code, const QVariant &value)
280{
281 if (value.isValid())
282 reply->attributes.insert(code, value);
283 else
284 reply->attributes.remove(code);
285}
286QUrl QNetworkAccessBackend::url() const
287{
288 return reply->url;
289}
290
291void QNetworkAccessBackend::setUrl(const QUrl &url)
292{
293 reply->url = url;
294}
295
296void QNetworkAccessBackend::finished()
297{
298 reply->finished();
299}
300
301void QNetworkAccessBackend::error(QNetworkReply::NetworkError code, const QString &errorString)
302{
303 reply->error(code, errorString);
304}
305
306#ifndef QT_NO_NETWORKPROXY
307void QNetworkAccessBackend::proxyAuthenticationRequired(const QNetworkProxy &proxy,
308 QAuthenticator *authenticator)
309{
310 manager->proxyAuthenticationRequired(this, proxy, authenticator);
311}
312#endif
313
314void QNetworkAccessBackend::authenticationRequired(QAuthenticator *authenticator)
315{
316 manager->authenticationRequired(this, authenticator);
317}
318
319void QNetworkAccessBackend::metaDataChanged()
320{
321 reply->metaDataChanged();
322}
323
324void QNetworkAccessBackend::redirectionRequested(const QUrl &target)
325{
326 reply->redirectionRequested(target);
327}
328
329void QNetworkAccessBackend::sslErrors(const QList<QSslError> &errors)
330{
331#ifndef QT_NO_OPENSSL
332 reply->sslErrors(errors);
333#else
334 Q_UNUSED(errors);
335#endif
336}
337
338QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.