Qt 4.8
qnetworkaccessbackend.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtNetwork module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
44 #include "qnetworkconfigmanager.h"
45 #include "qnetworkrequest.h"
46 #include "qnetworkreply.h"
47 #include "qnetworkreply_p.h"
48 #include "QtCore/qhash.h"
49 #include "QtCore/qmutex.h"
50 #include "QtNetwork/private/qnetworksession_p.h"
51 
53 #include "qabstractnetworkcache.h"
54 #include "qhostinfo.h"
55 
56 #include "private/qnoncontiguousbytedevice_p.h"
57 
59 
60 class QNetworkAccessBackendFactoryData: public QList<QNetworkAccessBackendFactory *>
61 {
62 public:
64  {
65  valid.ref();
66  }
68  {
69  QMutexLocker locker(&mutex); // why do we need to lock?
70  valid.deref();
71  }
72 
74  //this is used to avoid (re)constructing factory data from destructors of other global classes
76 };
79 
81 {
82  QMutexLocker locker(&factoryData()->mutex);
83  factoryData()->append(this);
84 }
85 
87 {
88  if (QNetworkAccessBackendFactoryData::valid) {
89  QMutexLocker locker(&factoryData()->mutex);
90  factoryData()->removeAll(this);
91  }
92 }
93 
95  const QNetworkRequest &request)
96 {
97  if (QNetworkAccessBackendFactoryData::valid) {
98  QMutexLocker locker(&factoryData()->mutex);
99  QNetworkAccessBackendFactoryData::ConstIterator it = factoryData()->constBegin(),
100  end = factoryData()->constEnd();
101  while (it != end) {
102  QNetworkAccessBackend *backend = (*it)->create(op, request);
103  if (backend) {
104  backend->manager = this;
105  return backend; // found a factory that handled our request
106  }
107  ++it;
108  }
109  }
110  return 0;
111 }
112 
114 {
115  if (reply->outgoingDataBuffer)
116  uploadByteDevice = QSharedPointer<QNonContiguousByteDevice>(QNonContiguousByteDeviceFactory::create(reply->outgoingDataBuffer));
117  else if (reply->outgoingData) {
119  } else {
120  return 0;
121  }
122 
123  bool bufferDisallowed =
124  reply->request.attribute(QNetworkRequest::DoNotBufferUploadDataAttribute,
125  QVariant(false)) == QVariant(true);
126  if (bufferDisallowed)
127  uploadByteDevice->disableReset();
128 
129  // We want signal emissions only for normal asynchronous uploads
130  if (!isSynchronous())
131  connect(uploadByteDevice.data(), SIGNAL(readProgress(qint64,qint64)), this, SLOT(emitReplyUploadProgress(qint64,qint64)));
132 
133  return uploadByteDevice.data();
134 }
135 
136 // need to have this function since the reply is a private member variable
137 // and the special backends need to access this.
139 {
140  if (reply->isFinished)
141  return;
142  reply->emitUploadProgress(bytesSent, bytesTotal);
143 }
144 
146  : manager(0)
147  , reply(0)
148  , synchronous(false)
149 {
150 }
151 
153 {
154 }
155 
157 {
158  // do nothing
159 }
160 
162 {
163  Q_UNUSED(b);
164  // do nothing
165 }
166 
168 {
169  Q_UNUSED(size);
170  // do nothing
171 }
172 
174 {
175  Q_UNUSED(size);
176  // do nothing
177 }
178 
180 {
181  // do nothing
182 }
183 
185 {
186  // do nothing
187 }
188 
190 {
191  Q_UNUSED(errors);
192  // do nothing
193 }
194 
196 {
197  // do nothing
198 }
199 
201 {
202  // do nothing
203 }
204 
206 {
207  return QNetworkCacheMetaData();
208 }
209 
211 {
212  return reply->operation;
213 }
214 
216 {
217  return reply->request;
218 }
219 
220 #ifndef QT_NO_NETWORKPROXY
222 {
223  return reply->proxyList;
224 }
225 #endif
226 
228 {
229  if (!manager)
230  return 0;
231  return manager->networkCache;
232 }
233 
235 {
236  reply->setCachingEnabled(enable);
237 }
238 
240 {
241  return reply->isCachingEnabled();
242 }
243 
245 {
246  return reply->nextDownstreamBlockSize();
247 }
248 
250 {
252 }
253 
255 {
257 }
258 
259 // not actually appending data, it was already written to the user buffer
261 {
262  reply->appendDownstreamDataDownloadBuffer(bytesReceived, bytesTotal);
263 }
264 
266 {
267  return reply->getDownloadBuffer(size);
268 }
269 
271 {
272  return reply->q_func()->header(header);
273 }
274 
276 {
277  reply->setCookedHeader(header, value);
278 }
279 
281 {
282  return reply->q_func()->hasRawHeader(headerName);
283 }
284 
286 {
287  return reply->q_func()->rawHeader(headerName);
288 }
289 
291 {
292  return reply->q_func()->rawHeaderList();
293 }
294 
296 {
297  reply->setRawHeader(headerName, headerValue);
298 }
299 
301 {
302  return reply->q_func()->attribute(code);
303 }
304 
306 {
307  if (value.isValid())
308  reply->attributes.insert(code, value);
309  else
310  reply->attributes.remove(code);
311 }
313 {
314  return reply->url;
315 }
316 
318 {
319  reply->url = url;
320 }
321 
323 {
324  reply->finished();
325 }
326 
328 {
329  reply->error(code, errorString);
330 }
331 
332 #ifndef QT_NO_NETWORKPROXY
334  QAuthenticator *authenticator)
335 {
336  manager->proxyAuthenticationRequired(this, proxy, authenticator);
337 }
338 #endif
339 
341 {
342  manager->authenticationRequired(this, authenticator);
343 }
344 
346 {
348 }
349 
351 {
352  reply->redirectionRequested(target);
353 }
354 
356 {
357 #ifndef QT_NO_OPENSSL
358  reply->sslErrors(errors);
359 #else
360  Q_UNUSED(errors);
361 #endif
362 }
363 
370 {
371 #ifndef QT_NO_BEARERMANAGEMENT
372  // For bearer, check if session start is required
374  if (networkSession) {
375  // session required
376  if (networkSession->isOpen() &&
377  networkSession->state() == QNetworkSession::Connected) {
378  // Session is already open and ready to use.
379  // copy network session down to the backend
380  setProperty("_q_networksession", QVariant::fromValue(networkSession));
381  } else {
382  // Session not ready, but can skip for loopback connections
383 
384  // This is not ideal.
385  const QString host = reply->url.host();
386 
387  if (host == QLatin1String("localhost") ||
390  // Don't need an open session for localhost access.
391  } else {
392  // need to wait for session to be opened
393  return false;
394  }
395  }
396  }
397 #endif
398 
399 #ifndef QT_NO_NETWORKPROXY
400 #ifndef QT_NO_BEARERMANAGEMENT
401  // Get the proxy settings from the network session (in the case of service networks,
402  // the proxy settings change depending which AP was activated)
403  QNetworkSession *session = networkSession.data();
404  QNetworkConfiguration config;
405  if (session) {
406  QNetworkConfigurationManager configManager;
407  // The active configuration tells us what IAP is in use
408  QVariant v = session->sessionProperty(QLatin1String("ActiveConfiguration"));
409  if (v.isValid())
410  config = configManager.configurationFromIdentifier(qvariant_cast<QString>(v));
411  // Fallback to using the configuration if no active configuration
412  if (!config.isValid())
413  config = session->configuration();
414  // or unspecified configuration if that is no good either
415  if (!config.isValid())
416  config = QNetworkConfiguration();
417  }
419 #else // QT_NO_BEARERMANAGEMENT
420  // Without bearer management, the proxy depends only on the url
422 #endif
423 #endif
424 
425  // now start the request
426  open();
427  return true;
428 }
429 
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
void appendDownstreamDataDownloadBuffer(qint64, qint64)
virtual void emitReadBufferFreed(qint64 size)
virtual void setSslConfiguration(const QSslConfiguration &configuration)
QVariant sessionProperty(const QString &key) const
Returns the value for property key.
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void setAttribute(QNetworkRequest::Attribute code, const QVariant &value)
The QMutex class provides access serialization between threads.
Definition: qmutex.h:60
int remove(const Key &key)
Removes all the items that have the key from the hash.
Definition: qhash.h:784
#define it(className, varName)
static QByteArray headerName(QNetworkRequest::KnownHeaders header)
virtual void setReadBufferSize(qint64 size)
QVariant header(QNetworkRequest::KnownHeaders header) const
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
void setRawHeader(const QByteArray &key, const QByteArray &value)
#define SLOT(a)
Definition: qobjectdefs.h:226
bool setProperty(const char *name, const QVariant &value)
Sets the value of the object&#39;s name property to value.
Definition: qobject.cpp:3755
NetworkError
Indicates all possible error conditions found during the processing of the request.
Definition: qnetworkreply.h:70
Operation
Indicates the operation this reply is processing.
void proxyAuthenticationRequired(QNetworkAccessBackend *backend, const QNetworkProxy &proxy, QAuthenticator *authenticator)
QList< QNetworkProxy > proxyList
virtual void fetchSslConfiguration(QSslConfiguration &configuration) const
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
virtual QNetworkCacheMetaData fetchCacheMetaData(const QNetworkCacheMetaData &metaData) const
qint64 nextDownstreamBlockSize() const
The QNetworkConfigurationManager class manages the network configurations provided by the system...
The QUrl class provides a convenient interface for working with URLs.
Definition: qurl.h:61
The QString class provides a Unicode character string.
Definition: qstring.h:83
QString host() const
Returns the host of the URL if it is defined; otherwise an empty string is returned.
Definition: qurl.cpp:4837
void writeDownstreamDataDownloadBuffer(qint64, qint64)
QSharedPointer< QNetworkSession > getNetworkSession() const
void appendDownstreamData(QByteDataBuffer &data)
#define Q_BASIC_ATOMIC_INITIALIZER(a)
Definition: qbasicatomic.h:218
KnownHeaders
List of known header types that QNetworkRequest parses.
qint64 nextDownstreamBlockSize() const
bool hasRawHeader(const QByteArray &headerName) const
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
QNetworkAccessManagerPrivate * manager
Q_GUI_EXPORT QString errorString(EGLint code=eglGetError())
Definition: qegl.cpp:743
void redirectionRequested(const QUrl &target)
QNetworkConfiguration configuration() const
Returns the QNetworkConfiguration that this network session object is based on.
#define SIGNAL(a)
Definition: qobjectdefs.h:227
bool isValid() const
Returns true if this QNetworkConfiguration object is valid.
The QNetworkProxy class provides a network layer proxy.
QNonContiguousByteDevice * createUploadByteDevice()
The QNetworkConfiguration class provides an abstraction of one or more access point configurations...
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QNetworkReplyImplPrivate * reply
virtual void setDownstreamLimited(bool b)
void emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal)
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:270
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
void setRawHeader(const QByteArray &headerName, const QByteArray &value)
QList< QNetworkProxy > proxyList() const
static const char * data(const QByteArray &arr)
char * getDownloadBuffer(qint64 size)
QNetworkAccessManager::Operation operation
void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
__int64 qint64
Definition: qglobal.h:942
static QVariant fromValue(const T &value)
Returns a QVariant containing a copy of value.
Definition: qvariant.h:336
QNetworkAccessManager::Operation operation() const
QByteArray rawHeader(const QByteArray &headerName) const
The QAuthenticator class provides an authentication object.
QAbstractNetworkCache * networkCache() const
Attribute
Attribute codes for the QNetworkRequest and QNetworkReply.
The QNetworkProxyQuery class is used to query the proxy settings for a socket.
Definition: qnetworkproxy.h:60
QNetworkRequest request
void authenticationRequired(QAuthenticator *auth)
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
void error(QNetworkReply::NetworkError code, const QString &errorString)
The QNetworkSession class provides control over the system&#39;s access points and enables session manage...
QNetworkRequest request() const
void sslErrors(const QList< QSslError > &errors)
void setUrl(const QUrl &url)
const_iterator ConstIterator
Qt-style synonym for QList::const_iterator.
Definition: qlist.h:279
void error(QNetworkReply::NetworkError code, const QString &errorString)
void writeDownstreamData(QByteDataBuffer &list)
QVariant attribute(QNetworkRequest::Attribute code) const
static QNonContiguousByteDevice * create(QIODevice *device)
Create a QNonContiguousByteDevice out of a QIODevice.
The QNetworkRequest class holds a request to be sent with QNetworkAccessManager.
void authenticationRequired(QNetworkAccessBackend *backend, QAuthenticator *authenticator)
QNetworkAccessBackend * findBackend(QNetworkAccessManager::Operation op, const QNetworkRequest &request)
QNetworkConfiguration configurationFromIdentifier(const QString &identifier) const
Returns the QNetworkConfiguration for identifier; otherwise returns an invalid QNetworkConfiguration...
void setCookedHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
void setCachingEnabled(bool enable)
A QNonContiguousByteDevice is a representation of a file, array or buffer that allows access with a r...
The QSslConfiguration class holds the configuration and state of an SSL connection.
void setCachingEnabled(bool enable)
The QHostAddress class provides an IP address.
Definition: qhostaddress.h:70
virtual void copyFinished(QIODevice *)
QAbstractNetworkCache * networkCache
bool isValid() const
Returns true if the storage type of this variant is not QVariant::Invalid; otherwise returns false...
Definition: qvariant.h:485
QList< QNetworkProxy > queryProxy(const QNetworkProxyQuery &query)
virtual void open()=0
The QIODevice class is the base interface class of all I/O devices in Qt.
Definition: qiodevice.h:66
static QByteArray headerValue(QNetworkRequest::KnownHeaders header, const QVariant &value)
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
QList< QByteArray > rawHeaderList() const
The QNetworkCacheMetaData class provides cache information.
virtual bool start()
Starts the backend.
void redirectionRequested(const QUrl &destination)
void sslErrors(const QList< QSslError > &errors)
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth)
The QAbstractNetworkCache class provides the interface for cache implementations. ...