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

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

trunk: Merged in qt 4.6.2 sources.

File size: 9.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 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::setDownstreamLimited(bool b)
165{
166 Q_UNUSED(b);
167 // do nothing
168}
169
170void QNetworkAccessBackend::copyFinished(QIODevice *)
171{
172 // do nothing
173}
174
175void QNetworkAccessBackend::ignoreSslErrors()
176{
177 // do nothing
178}
179
180void QNetworkAccessBackend::ignoreSslErrors(const QList<QSslError> &errors)
181{
182 Q_UNUSED(errors);
183 // do nothing
184}
185
186void QNetworkAccessBackend::fetchSslConfiguration(QSslConfiguration &) const
187{
188 // do nothing
189}
190
191void QNetworkAccessBackend::setSslConfiguration(const QSslConfiguration &)
192{
193 // do nothing
194}
195
196QNetworkCacheMetaData QNetworkAccessBackend::fetchCacheMetaData(const QNetworkCacheMetaData &) const
197{
198 return QNetworkCacheMetaData();
199}
200
201QNetworkAccessManager::Operation QNetworkAccessBackend::operation() const
202{
203 return reply->operation;
204}
205
206QNetworkRequest QNetworkAccessBackend::request() const
207{
208 return reply->request;
209}
210
211#ifndef QT_NO_NETWORKPROXY
212QList<QNetworkProxy> QNetworkAccessBackend::proxyList() const
213{
214 return reply->proxyList;
215}
216#endif
217
218QAbstractNetworkCache *QNetworkAccessBackend::networkCache() const
219{
220 if (!manager)
221 return 0;
222 return manager->networkCache;
223}
224
225void QNetworkAccessBackend::setCachingEnabled(bool enable)
226{
227 reply->setCachingEnabled(enable);
228}
229
230bool QNetworkAccessBackend::isCachingEnabled() const
231{
232 return reply->isCachingEnabled();
233}
234
235qint64 QNetworkAccessBackend::nextDownstreamBlockSize() const
236{
237 return reply->nextDownstreamBlockSize();
238}
239
240void QNetworkAccessBackend::writeDownstreamData(QByteDataBuffer &list)
241{
242 reply->appendDownstreamData(list);
243}
244
245void QNetworkAccessBackend::writeDownstreamData(QIODevice *data)
246{
247 reply->appendDownstreamData(data);
248}
249
250QVariant QNetworkAccessBackend::header(QNetworkRequest::KnownHeaders header) const
251{
252 return reply->q_func()->header(header);
253}
254
255void QNetworkAccessBackend::setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
256{
257 reply->setCookedHeader(header, value);
258}
259
260bool QNetworkAccessBackend::hasRawHeader(const QByteArray &headerName) const
261{
262 return reply->q_func()->hasRawHeader(headerName);
263}
264
265QByteArray QNetworkAccessBackend::rawHeader(const QByteArray &headerName) const
266{
267 return reply->q_func()->rawHeader(headerName);
268}
269
270QList<QByteArray> QNetworkAccessBackend::rawHeaderList() const
271{
272 return reply->q_func()->rawHeaderList();
273}
274
275void QNetworkAccessBackend::setRawHeader(const QByteArray &headerName, const QByteArray &headerValue)
276{
277 reply->setRawHeader(headerName, headerValue);
278}
279
280QVariant QNetworkAccessBackend::attribute(QNetworkRequest::Attribute code) const
281{
282 return reply->q_func()->attribute(code);
283}
284
285void QNetworkAccessBackend::setAttribute(QNetworkRequest::Attribute code, const QVariant &value)
286{
287 if (value.isValid())
288 reply->attributes.insert(code, value);
289 else
290 reply->attributes.remove(code);
291}
292QUrl QNetworkAccessBackend::url() const
293{
294 return reply->url;
295}
296
297void QNetworkAccessBackend::setUrl(const QUrl &url)
298{
299 reply->url = url;
300}
301
302void QNetworkAccessBackend::finished()
303{
304 reply->finished();
305}
306
307void QNetworkAccessBackend::error(QNetworkReply::NetworkError code, const QString &errorString)
308{
309 reply->error(code, errorString);
310}
311
312#ifndef QT_NO_NETWORKPROXY
313void QNetworkAccessBackend::proxyAuthenticationRequired(const QNetworkProxy &proxy,
314 QAuthenticator *authenticator)
315{
316 manager->proxyAuthenticationRequired(this, proxy, authenticator);
317}
318#endif
319
320void QNetworkAccessBackend::authenticationRequired(QAuthenticator *authenticator)
321{
322 manager->authenticationRequired(this, authenticator);
323}
324
325void QNetworkAccessBackend::metaDataChanged()
326{
327 reply->metaDataChanged();
328}
329
330void QNetworkAccessBackend::redirectionRequested(const QUrl &target)
331{
332 reply->redirectionRequested(target);
333}
334
335void QNetworkAccessBackend::sslErrors(const QList<QSslError> &errors)
336{
337#ifndef QT_NO_OPENSSL
338 reply->sslErrors(errors);
339#else
340 Q_UNUSED(errors);
341#endif
342}
343
344QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.