Merge branch 'master' of scm.dev.nokia.troll.no:qt/qt-doc-staging
[qt:qt.git] / src / network / access / qnetworkaccessmanager.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtNetwork module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
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 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qnetworkaccessmanager.h"
43 #include "qnetworkaccessmanager_p.h"
44 #include "qnetworkrequest.h"
45 #include "qnetworkreply.h"
46 #include "qnetworkreply_p.h"
47 #include "qnetworkcookie.h"
48 #include "qabstractnetworkcache.h"
49
50 #include "QtNetwork/qnetworksession.h"
51 #include "QtNetwork/private/qsharednetworksession_p.h"
52
53 #include "qnetworkaccesshttpbackend_p.h"
54 #include "qnetworkaccessftpbackend_p.h"
55 #include "qnetworkaccessfilebackend_p.h"
56 #include "qnetworkaccessdebugpipebackend_p.h"
57 #include "qnetworkaccesscachebackend_p.h"
58 #include "qnetworkreplydataimpl_p.h"
59 #include "qnetworkreplyfileimpl_p.h"
60
61 #include "QtCore/qbuffer.h"
62 #include "QtCore/qurl.h"
63 #include "QtCore/qvector.h"
64 #include "QtNetwork/qauthenticator.h"
65 #include "QtNetwork/qsslconfiguration.h"
66 #include "QtNetwork/qnetworkconfigmanager.h"
67 #include "QtNetwork/qhttpmultipart.h"
68 #include "qhttpmultipart_p.h"
69
70 #include "qthread.h"
71
72 QT_BEGIN_NAMESPACE
73
74 #ifndef QT_NO_HTTP
75 Q_GLOBAL_STATIC(QNetworkAccessHttpBackendFactory, httpBackend)
76 #endif // QT_NO_HTTP
77 Q_GLOBAL_STATIC(QNetworkAccessFileBackendFactory, fileBackend)
78 #ifndef QT_NO_FTP
79 Q_GLOBAL_STATIC(QNetworkAccessFtpBackendFactory, ftpBackend)
80 #endif // QT_NO_FTP
81
82 #ifdef QT_BUILD_INTERNAL
83 Q_GLOBAL_STATIC(QNetworkAccessDebugPipeBackendFactory, debugpipeBackend)
84 #endif
85
86 static void ensureInitialized()
87 {
88 #ifndef QT_NO_HTTP
89     (void) httpBackend();
90 #endif // QT_NO_HTTP
91
92 #ifndef QT_NO_FTP
93     (void) ftpBackend();
94 #endif
95
96 #ifdef QT_BUILD_INTERNAL
97     (void) debugpipeBackend();
98 #endif
99
100     // leave this one last since it will query the special QAbstractFileEngines
101     (void) fileBackend();
102 }
103
104 /*!
105     \class QNetworkAccessManager
106     \brief The QNetworkAccessManager class allows the application to
107     send network requests and receive replies
108     \since 4.4
109
110     \ingroup network
111     \inmodule QtNetwork
112     \reentrant
113
114     The Network Access API is constructed around one QNetworkAccessManager
115     object, which holds the common configuration and settings for the requests
116     it sends. It contains the proxy and cache configuration, as well as the
117     signals related to such issues, and reply signals that can be used to
118     monitor the progress of a network operation. One QNetworkAccessManager
119     should be enough for the whole Qt application.
120
121     Once a QNetworkAccessManager object has been created, the application can
122     use it to send requests over the network. A group of standard functions
123     are supplied that take a request and optional data, and each return a
124     QNetworkReply object. The returned object is used to obtain any data
125     returned in response to the corresponding request.
126
127     A simple download off the network could be accomplished with:
128     \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 0
129
130     QNetworkAccessManager has an asynchronous API.
131     When the \tt replyFinished slot above is called, the parameter it
132     takes is the QNetworkReply object containing the downloaded data
133     as well as meta-data (headers, etc.).
134
135     \note After the request has finished, it is the responsibility of the user
136     to delete the QNetworkReply object at an appropriate time. Do not directly
137     delete it inside the slot connected to finished(). You can use the
138     deleteLater() function.
139
140     \note QNetworkAccessManager queues the requests it receives. The number
141     of requests executed in parallel is dependent on the protocol.
142     Currently, for the HTTP protocol on desktop platforms, 6 requests are
143     executed in parallel for one host/port combination.
144
145     A more involved example, assuming the manager is already existent,
146     can be:
147     \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 1
148
149     \section1 Network and Roaming support
150
151     With the addition of the \l {Bearer Management} API to Qt 4.7
152     QNetworkAccessManager gained the ability to manage network connections.
153     QNetworkAccessManager can start the network interface if the device is
154     offline and terminates the interface if the current process is the last
155     one to use the uplink. Note that some platform utilize grace periods from
156     when the last application stops using a uplink until the system actually
157     terminates the connectivity link. Roaming is equally transparent. Any
158     queued/pending network requests are automatically transferred to new
159     access point.
160
161     Clients wanting to utilize this feature should not require any changes. In fact
162     it is likely that existing platform specific connection code can simply be
163     removed from the application.
164
165     \note The network and roaming support in QNetworkAccessManager is conditional
166     upon the platform supporting connection management. The
167     \l QNetworkConfigurationManager::NetworkSessionRequired can be used to
168     detect whether QNetworkAccessManager utilizes this feature. Currently only
169     Meego/Harmattan and Symbian platforms provide connection management support.
170
171     \note This feature cannot be used in combination with the Bearer Management
172     API as provided by QtMobility. Applications have to migrate to the Qt version
173     of Bearer Management.
174
175     \section1 Symbian Platform Security Requirements
176
177     On Symbian, processes which use this class must have the
178     \c NetworkServices platform security capability. If the client
179     process lacks this capability, operations will result in a panic.
180
181     Platform security capabilities are added via the
182     \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY}
183     qmake variable.
184
185     \sa QNetworkRequest, QNetworkReply, QNetworkProxy
186 */
187
188 /*!
189     \enum QNetworkAccessManager::Operation
190
191     Indicates the operation this reply is processing.
192
193     \value HeadOperation        retrieve headers operation (created
194     with head())
195
196     \value GetOperation         retrieve headers and download contents
197     (created with get())
198
199     \value PutOperation         upload contents operation (created
200     with put())
201
202     \value PostOperation        send the contents of an HTML form for
203     processing via HTTP POST (created with post())
204
205     \value DeleteOperation      delete contents operation (created with
206     deleteResource())
207
208     \value CustomOperation      custom operation (created with
209     sendCustomRequest())    \since 4.7
210
211     \omitvalue UnknownOperation
212
213     \sa QNetworkReply::operation()
214 */
215
216 /*!
217     \enum QNetworkAccessManager::NetworkAccessibility
218
219     Indicates whether the network is accessible via this network access manager.
220
221     \value UnknownAccessibility     The network accessibility cannot be determined.
222     \value NotAccessible            The network is not currently accessible, either because there
223                                     is currently no network coverage or network access has been
224                                     explicitly disabled by a call to setNetworkAccessible().
225     \value Accessible               The network is accessible.
226
227     \sa networkAccessible
228 */
229
230 /*!
231     \property QNetworkAccessManager::networkAccessible
232     \brief whether the network is currently accessible via this network access manager.
233
234     \since 4.7
235
236     If the network is \l {NotAccessible}{not accessible} the network access manager will not
237     process any new network requests, all such requests will fail with an error.  Requests with
238     URLs with the file:// scheme will still be processed.
239
240     By default the value of this property reflects the physical state of the device.  Applications
241     may override it to disable all network requests via this network access manager by calling
242
243     \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 4
244
245     Network requests can be reenabled again by calling
246
247     \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 5
248
249     \note Calling setNetworkAccessible() does not change the network state.
250 */
251
252 /*!
253     \fn void QNetworkAccessManager::networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility accessible)
254
255     This signal is emitted when the value of the \l networkAccessible property changes.
256     \a accessible is the new network accessibility.
257 */
258
259 /*!
260     \fn void QNetworkAccessManager::networkSessionConnected()
261
262     \since 4.7
263
264     \internal
265
266     This signal is emitted when the status of the network session changes into a usable (Connected)
267     state. It is used to signal to QNetworkReplys to start or migrate their network operation once
268     the network session has been opened or finished roaming.
269 */
270
271 /*!
272     \fn void QNetworkAccessManager::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
273
274     This signal is emitted whenever a proxy requests authentication
275     and QNetworkAccessManager cannot find a valid, cached
276     credential. The slot connected to this signal should fill in the
277     credentials for the proxy \a proxy in the \a authenticator object.
278
279     QNetworkAccessManager will cache the credentials internally. The
280     next time the proxy requests authentication, QNetworkAccessManager
281     will automatically send the same credential without emitting the
282     proxyAuthenticationRequired signal again.
283
284     If the proxy rejects the credentials, QNetworkAccessManager will
285     emit the signal again.
286
287     \sa proxy(), setProxy(), authenticationRequired()
288 */
289
290 /*!
291     \fn void QNetworkAccessManager::authenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator)
292
293     This signal is emitted whenever a final server requests
294     authentication before it delivers the requested contents. The slot
295     connected to this signal should fill the credentials for the
296     contents (which can be determined by inspecting the \a reply
297     object) in the \a authenticator object.
298
299     QNetworkAccessManager will cache the credentials internally and
300     will send the same values if the server requires authentication
301     again, without emitting the authenticationRequired() signal. If it
302     rejects the credentials, this signal will be emitted again.
303
304     \note It is not possible to use a QueuedConnection to connect to
305     this signal, as the connection will fail if the authenticator has
306     not been filled in with new information when the signal returns.
307
308     \sa proxyAuthenticationRequired()
309 */
310
311 /*!
312     \fn void QNetworkAccessManager::finished(QNetworkReply *reply)
313
314     This signal is emitted whenever a pending network reply is
315     finished. The \a reply parameter will contain a pointer to the
316     reply that has just finished. This signal is emitted in tandem
317     with the QNetworkReply::finished() signal.
318
319     See QNetworkReply::finished() for information on the status that
320     the object will be in.
321
322     \note Do not delete the \a reply object in the slot connected to this
323     signal. Use deleteLater().
324
325     \sa QNetworkReply::finished(), QNetworkReply::error()
326 */
327
328 /*!
329     \fn void QNetworkAccessManager::sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
330
331     This signal is emitted if the SSL/TLS session encountered errors
332     during the set up, including certificate verification errors. The
333     \a errors parameter contains the list of errors and \a reply is
334     the QNetworkReply that is encountering these errors.
335
336     To indicate that the errors are not fatal and that the connection
337     should proceed, the QNetworkReply::ignoreSslErrors() function should be called
338     from the slot connected to this signal. If it is not called, the
339     SSL session will be torn down before any data is exchanged
340     (including the URL).
341
342     This signal can be used to display an error message to the user
343     indicating that security may be compromised and display the
344     SSL settings (see sslConfiguration() to obtain it). If the user
345     decides to proceed after analyzing the remote certificate, the
346     slot should call ignoreSslErrors().
347
348     \sa QSslSocket::sslErrors(), QNetworkReply::sslErrors(),
349     QNetworkReply::sslConfiguration(), QNetworkReply::ignoreSslErrors()
350 */
351
352
353 /*!
354     Constructs a QNetworkAccessManager object that is the center of
355     the Network Access API and sets \a parent as the parent object.
356 */
357 QNetworkAccessManager::QNetworkAccessManager(QObject *parent)
358     : QObject(*new QNetworkAccessManagerPrivate, parent)
359 {
360     ensureInitialized();
361
362     qRegisterMetaType<QNetworkReply::NetworkError>("QNetworkReply::NetworkError");
363 }
364
365 /*!
366     Destroys the QNetworkAccessManager object and frees up any
367     resources. Note that QNetworkReply objects that are returned from
368     this class have this object set as their parents, which means that
369     they will be deleted along with it if you don't call
370     QObject::setParent() on them.
371 */
372 QNetworkAccessManager::~QNetworkAccessManager()
373 {
374 #ifndef QT_NO_NETWORKPROXY
375     delete d_func()->proxyFactory;
376 #endif
377
378     // Delete the QNetworkReply children first.
379     // Else a QAbstractNetworkCache might get deleted in ~QObject
380     // before a QNetworkReply that accesses the QAbstractNetworkCache
381     // object in its destructor.
382     qDeleteAll(findChildren<QNetworkReply *>());
383     // The other children will be deleted in this ~QObject
384     // FIXME instead of this "hack" make the QNetworkReplyImpl
385     // properly watch the cache deletion, e.g. via a QWeakPointer.
386 }
387
388 #ifndef QT_NO_NETWORKPROXY
389 /*!
390     Returns the QNetworkProxy that the requests sent using this
391     QNetworkAccessManager object will use. The default value for the
392     proxy is QNetworkProxy::DefaultProxy.
393
394     \sa setProxy(), setProxyFactory(), proxyAuthenticationRequired()
395 */
396 QNetworkProxy QNetworkAccessManager::proxy() const
397 {
398     return d_func()->proxy;
399 }
400
401 /*!
402     Sets the proxy to be used in future requests to be \a proxy. This
403     does not affect requests that have already been sent. The
404     proxyAuthenticationRequired() signal will be emitted if the proxy
405     requests authentication.
406
407     A proxy set with this function will be used for all requests
408     issued by QNetworkAccessManager. In some cases, it might be
409     necessary to select different proxies depending on the type of
410     request being sent or the destination host. If that's the case,
411     you should consider using setProxyFactory().
412
413     \sa proxy(), proxyAuthenticationRequired()
414 */
415 void QNetworkAccessManager::setProxy(const QNetworkProxy &proxy)
416 {
417     Q_D(QNetworkAccessManager);
418     delete d->proxyFactory;
419     d->proxy = proxy;
420     d->proxyFactory = 0;
421 }
422
423 /*!
424     \fn QNetworkProxyFactory *QNetworkAccessManager::proxyFactory() const
425     \since 4.5
426
427     Returns the proxy factory that this QNetworkAccessManager object
428     is using to determine the proxies to be used for requests.
429
430     Note that the pointer returned by this function is managed by
431     QNetworkAccessManager and could be deleted at any time.
432
433     \sa setProxyFactory(), proxy()
434 */
435 QNetworkProxyFactory *QNetworkAccessManager::proxyFactory() const
436 {
437     return d_func()->proxyFactory;
438 }
439
440 /*!
441     \since 4.5
442
443     Sets the proxy factory for this class to be \a factory. A proxy
444     factory is used to determine a more specific list of proxies to be
445     used for a given request, instead of trying to use the same proxy
446     value for all requests.
447
448     All queries sent by QNetworkAccessManager will have type
449     QNetworkProxyQuery::UrlRequest.
450
451     For example, a proxy factory could apply the following rules:
452     \list
453       \o if the target address is in the local network (for example,
454          if the hostname contains no dots or if it's an IP address in
455          the organization's range), return QNetworkProxy::NoProxy
456       \o if the request is FTP, return an FTP proxy
457       \o if the request is HTTP or HTTPS, then return an HTTP proxy
458       \o otherwise, return a SOCKSv5 proxy server
459     \endlist
460
461     The lifetime of the object \a factory will be managed by
462     QNetworkAccessManager. It will delete the object when necessary.
463
464     \note If a specific proxy is set with setProxy(), the factory will not
465     be used.
466
467     \sa proxyFactory(), setProxy(), QNetworkProxyQuery
468 */
469 void QNetworkAccessManager::setProxyFactory(QNetworkProxyFactory *factory)
470 {
471     Q_D(QNetworkAccessManager);
472     delete d->proxyFactory;
473     d->proxyFactory = factory;
474     d->proxy = QNetworkProxy();
475 }
476 #endif
477
478 /*!
479     \since 4.5
480
481     Returns the cache that is used to store data obtained from the network.
482
483     \sa setCache()
484 */
485 QAbstractNetworkCache *QNetworkAccessManager::cache() const
486 {
487     Q_D(const QNetworkAccessManager);
488     return d->networkCache;
489 }
490
491 /*!
492     \since 4.5
493
494     Sets the manager's network cache to be the \a cache specified. The cache
495     is used for all requests dispatched by the manager.
496
497     Use this function to set the network cache object to a class that implements
498     additional features, like saving the cookies to permanent storage.
499
500     \note QNetworkAccessManager takes ownership of the \a cache object.
501
502     QNetworkAccessManager by default does not have a set cache.
503     Qt provides a simple disk cache, QNetworkDiskCache, which can be used.
504
505     \sa cache(), QNetworkRequest::CacheLoadControl
506 */
507 void QNetworkAccessManager::setCache(QAbstractNetworkCache *cache)
508 {
509     Q_D(QNetworkAccessManager);
510     if (d->networkCache != cache) {
511         delete d->networkCache;
512         d->networkCache = cache;
513         if (d->networkCache)
514             d->networkCache->setParent(this);
515     }
516 }
517
518 /*!
519     Returns the QNetworkCookieJar that is used to store cookies
520     obtained from the network as well as cookies that are about to be
521     sent.
522
523     \sa setCookieJar()
524 */
525 QNetworkCookieJar *QNetworkAccessManager::cookieJar() const
526 {
527     Q_D(const QNetworkAccessManager);
528     if (!d->cookieJar)
529         d->createCookieJar();
530     return d->cookieJar;
531 }
532
533 /*!
534     Sets the manager's cookie jar to be the \a cookieJar specified.
535     The cookie jar is used by all requests dispatched by the manager.
536
537     Use this function to set the cookie jar object to a class that
538     implements additional features, like saving the cookies to permanent
539     storage.
540
541     \note QNetworkAccessManager takes ownership of the \a cookieJar object.
542
543     If \a cookieJar is in the same thread as this QNetworkAccessManager,
544     it will set the parent of the \a cookieJar
545     so that the cookie jar is deleted when this
546     object is deleted as well. If you want to share cookie jars
547     between different QNetworkAccessManager objects, you may want to
548     set the cookie jar's parent to 0 after calling this function.
549
550     QNetworkAccessManager by default does not implement any cookie
551     policy of its own: it accepts all cookies sent by the server, as
552     long as they are well formed and meet the minimum security
553     requirements (cookie domain matches the request's and cookie path
554     matches the request's). In order to implement your own security
555     policy, override the QNetworkCookieJar::cookiesForUrl() and
556     QNetworkCookieJar::setCookiesFromUrl() virtual functions. Those
557     functions are called by QNetworkAccessManager when it detects a
558     new cookie.
559
560     \sa cookieJar(), QNetworkCookieJar::cookiesForUrl(), QNetworkCookieJar::setCookiesFromUrl()
561 */
562 void QNetworkAccessManager::setCookieJar(QNetworkCookieJar *cookieJar)
563 {
564     Q_D(QNetworkAccessManager);
565     d->cookieJarCreated = true;
566     if (d->cookieJar != cookieJar) {
567         if (d->cookieJar && d->cookieJar->parent() == this)
568             delete d->cookieJar;
569         d->cookieJar = cookieJar;
570         if (thread() == cookieJar->thread())
571             d->cookieJar->setParent(this);
572     }
573 }
574
575 /*!
576     Posts a request to obtain the network headers for \a request
577     and returns a new QNetworkReply object which will contain such headers.
578
579     The function is named after the HTTP request associated (HEAD).
580 */
581 QNetworkReply *QNetworkAccessManager::head(const QNetworkRequest &request)
582 {
583     return d_func()->postProcess(createRequest(QNetworkAccessManager::HeadOperation, request));
584 }
585
586 /*!
587     Posts a request to obtain the contents of the target \a request
588     and returns a new QNetworkReply object opened for reading which emits the 
589     \l{QIODevice::readyRead()}{readyRead()} signal whenever new data 
590     arrives.
591
592     The contents as well as associated headers will be downloaded.
593
594     \sa post(), put(), deleteResource(), sendCustomRequest()
595 */
596 QNetworkReply *QNetworkAccessManager::get(const QNetworkRequest &request)
597 {
598     return d_func()->postProcess(createRequest(QNetworkAccessManager::GetOperation, request));
599 }
600
601 /*!
602     Sends an HTTP POST request to the destination specified by \a request
603     and returns a new QNetworkReply object opened for reading that will 
604     contain the reply sent by the server. The contents of  the \a data 
605     device will be uploaded to the server.
606
607     \a data must be open for reading and must remain valid until the 
608     finished() signal is emitted for this reply.
609
610     \note Sending a POST request on protocols other than HTTP and
611     HTTPS is undefined and will probably fail.
612
613     \sa get(), put(), deleteResource(), sendCustomRequest()
614 */
615 QNetworkReply *QNetworkAccessManager::post(const QNetworkRequest &request, QIODevice *data)
616 {
617     return d_func()->postProcess(createRequest(QNetworkAccessManager::PostOperation, request, data));
618 }
619
620 /*!
621     \overload
622
623     Sends the contents of the \a data byte array to the destination 
624     specified by \a request.
625 */
626 QNetworkReply *QNetworkAccessManager::post(const QNetworkRequest &request, const QByteArray &data)
627 {
628     QBuffer *buffer = new QBuffer;
629     buffer->setData(data);
630     buffer->open(QIODevice::ReadOnly);
631
632     QNetworkReply *reply = post(request, buffer);
633     buffer->setParent(reply);
634     return reply;
635 }
636
637 /*!
638     \since 4.8
639
640     \overload
641
642     Sends the contents of the \a multiPart message to the destination
643     specified by \a request.
644
645     This can be used for sending MIME multipart messages over HTTP.
646
647     \sa QHttpMultiPart, QHttpPart, put()
648 */
649 QNetworkReply *QNetworkAccessManager::post(const QNetworkRequest &request, QHttpMultiPart *multiPart)
650 {
651     QNetworkRequest newRequest = d_func()->prepareMultipart(request, multiPart);
652     QIODevice *device = multiPart->d_func()->device;
653     QNetworkReply *reply = post(newRequest, device);
654     return reply;
655 }
656
657 /*!
658     \since 4.8
659
660     \overload
661
662     Sends the contents of the \a multiPart message to the destination
663     specified by \a request.
664
665     This can be used for sending MIME multipart messages over HTTP.
666
667     \sa QHttpMultiPart, QHttpPart, post()
668 */
669 QNetworkReply *QNetworkAccessManager::put(const QNetworkRequest &request, QHttpMultiPart *multiPart)
670 {
671     QNetworkRequest newRequest = d_func()->prepareMultipart(request, multiPart);
672     QIODevice *device = multiPart->d_func()->device;
673     QNetworkReply *reply = put(newRequest, device);
674     return reply;
675 }
676
677 /*!
678     Uploads the contents of \a data to the destination \a request and
679     returnes a new QNetworkReply object that will be open for reply.
680
681     \a data must be opened for reading when this function is called
682     and must remain valid until the finished() signal is emitted for
683     this reply.
684
685     Whether anything will be available for reading from the returned
686     object is protocol dependent. For HTTP, the server may send a 
687     small HTML page indicating the upload was successful (or not). 
688     Other protocols will probably have content in their replies.
689
690     \note For HTTP, this request will send a PUT request, which most servers
691     do not allow. Form upload mechanisms, including that of uploading
692     files through HTML forms, use the POST mechanism.
693
694     \sa get(), post(), deleteResource(), sendCustomRequest()
695 */
696 QNetworkReply *QNetworkAccessManager::put(const QNetworkRequest &request, QIODevice *data)
697 {
698     return d_func()->postProcess(createRequest(QNetworkAccessManager::PutOperation, request, data));
699 }
700
701 /*!
702     \overload
703
704     Sends the contents of the \a data byte array to the destination
705     specified by \a request.
706 */
707 QNetworkReply *QNetworkAccessManager::put(const QNetworkRequest &request, const QByteArray &data)
708 {
709     QBuffer *buffer = new QBuffer;
710     buffer->setData(data);
711     buffer->open(QIODevice::ReadOnly);
712
713     QNetworkReply *reply = put(request, buffer);
714     buffer->setParent(reply);
715     return reply;
716 }
717
718 /*!
719     \since 4.6
720
721     Sends a request to delete the resource identified by the URL of \a request.
722
723     \note This feature is currently available for HTTP only, performing an 
724     HTTP DELETE request.
725
726     \sa get(), post(), put(), sendCustomRequest()
727 */
728 QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &request)
729 {
730     return d_func()->postProcess(createRequest(QNetworkAccessManager::DeleteOperation, request));
731 }
732
733 #ifndef QT_NO_BEARERMANAGEMENT
734
735 /*!
736     \since 4.7
737
738     Sets the network configuration that will be used when creating the
739     \l {QNetworkSession}{network session} to \a config.
740
741     The network configuration is used to create and open a network session before any request that
742     requires network access is process.  If no network configuration is explicitly set via this
743     function the network configuration returned by
744     QNetworkConfigurationManager::defaultConfiguration() will be used.
745
746     To restore the default network configuration set the network configuration to the value
747     returned from QNetworkConfigurationManager::defaultConfiguration().
748
749     \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 2
750
751     If an invalid network configuration is set, a network session will not be created.  In this
752     case network requests will be processed regardless, but may fail.  For example:
753
754     \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 3
755
756     \sa configuration(), QNetworkSession
757 */
758 void QNetworkAccessManager::setConfiguration(const QNetworkConfiguration &config)
759 {
760     d_func()->createSession(config);
761 }
762
763 /*!
764     \since 4.7
765
766     Returns the network configuration that will be used to create the
767     \l {QNetworkSession}{network session} which will be used when processing network requests.
768
769     \sa setConfiguration(), activeConfiguration()
770 */
771 QNetworkConfiguration QNetworkAccessManager::configuration() const
772 {
773     Q_D(const QNetworkAccessManager);
774
775     if (d->networkSession)
776         return d->networkSession->configuration();
777     else
778         return QNetworkConfiguration();
779 }
780
781 /*!
782     \since 4.7
783
784     Returns the current active network configuration.
785
786     If the network configuration returned by configuration() is of type
787     QNetworkConfiguration::ServiceNetwork this function will return the current active child
788     network configuration of that configuration.  Otherwise returns the same network configuration
789     as configuration().
790
791     Use this function to return the actual network configuration currently in use by the network
792     session.
793
794     \sa configuration()
795 */
796 QNetworkConfiguration QNetworkAccessManager::activeConfiguration() const
797 {
798     Q_D(const QNetworkAccessManager);
799
800     if (d->networkSession) {
801         QNetworkConfigurationManager manager;
802
803         return manager.configurationFromIdentifier(
804             d->networkSession->sessionProperty(QLatin1String("ActiveConfiguration")).toString());
805     } else {
806         return QNetworkConfiguration();
807     }
808 }
809
810 /*!
811     \since 4.7
812
813     Overrides the reported network accessibility.  If \a accessible is NotAccessible the reported
814     network accessiblity will always be NotAccessible.  Otherwise the reported network
815     accessibility will reflect the actual device state.
816 */
817 void QNetworkAccessManager::setNetworkAccessible(QNetworkAccessManager::NetworkAccessibility accessible)
818 {
819     Q_D(QNetworkAccessManager);
820
821     if (d->networkAccessible != accessible) {
822         NetworkAccessibility previous = networkAccessible();
823         d->networkAccessible = accessible;
824         NetworkAccessibility current = networkAccessible();
825         if (previous != current)
826             emit networkAccessibleChanged(current);
827     }
828 }
829
830 /*!
831     \since 4.7
832
833     Returns the current network accessibility.
834 */
835 QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccessible() const
836 {
837     Q_D(const QNetworkAccessManager);
838
839     if (d->networkSession) {
840         // d->online holds online/offline state of this network session.
841         if (d->online)
842             return d->networkAccessible;
843         else
844             return NotAccessible;
845     } else {
846         // Network accessibility is either disabled or unknown.
847         return (d->networkAccessible == NotAccessible) ? NotAccessible : UnknownAccessibility;
848     }
849 }
850
851 #endif // QT_NO_BEARERMANAGEMENT
852
853 /*!
854     \since 4.7
855
856     Sends a custom request to the server identified by the URL of \a request.
857
858     It is the user's responsibility to send a \a verb to the server that is valid
859     according to the HTTP specification.
860
861     This method provides means to send verbs other than the common ones provided
862     via get() or post() etc., for instance sending an HTTP OPTIONS command.
863
864     If \a data is not empty, the contents of the \a data
865     device will be uploaded to the server; in that case, data must be open for
866     reading and must remain valid until the finished() signal is emitted for this reply.
867
868     \note This feature is currently available for HTTP only.
869
870     \sa get(), post(), put(), deleteResource()
871 */
872 QNetworkReply *QNetworkAccessManager::sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data)
873 {
874     QNetworkRequest newRequest(request);
875     newRequest.setAttribute(QNetworkRequest::CustomVerbAttribute, verb);
876     return d_func()->postProcess(createRequest(QNetworkAccessManager::CustomOperation, newRequest, data));
877 }
878
879 /*!
880     Returns a new QNetworkReply object to handle the operation \a op
881     and request \a req. The device \a outgoingData is always 0 for Get and
882     Head requests, but is the value passed to post() and put() in
883     those operations (the QByteArray variants will pass a QBuffer
884     object).
885
886     The default implementation calls QNetworkCookieJar::cookiesForUrl()
887     on the cookie jar set with setCookieJar() to obtain the cookies to
888     be sent to the remote server.
889
890     The returned object must be in an open state.
891 */
892 QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Operation op,
893                                                     const QNetworkRequest &req,
894                                                     QIODevice *outgoingData)
895 {
896     Q_D(QNetworkAccessManager);
897
898     bool isLocalFile = req.url().isLocalFile();
899     QString scheme = req.url().scheme().toLower();
900
901     // fast path for GET on file:// URLs
902     // The QNetworkAccessFileBackend will right now only be used for PUT
903     if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation)
904         && (isLocalFile || scheme == QLatin1String("qrc"))) {
905         return new QNetworkReplyFileImpl(this, req, op);
906     }
907
908     if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation)
909             && scheme == QLatin1String("data")) {
910         return new QNetworkReplyDataImpl(this, req, op);
911     }
912
913     // A request with QNetworkRequest::AlwaysCache does not need any bearer management
914     QNetworkRequest::CacheLoadControl mode =
915         static_cast<QNetworkRequest::CacheLoadControl>(
916             req.attribute(QNetworkRequest::CacheLoadControlAttribute,
917                               QNetworkRequest::PreferNetwork).toInt());
918     if (mode == QNetworkRequest::AlwaysCache
919         && (op == QNetworkAccessManager::GetOperation
920         || op == QNetworkAccessManager::HeadOperation)) {
921         // FIXME Implement a QNetworkReplyCacheImpl instead, see QTBUG-15106
922         QNetworkReplyImpl *reply = new QNetworkReplyImpl(this);
923         QNetworkReplyImplPrivate *priv = reply->d_func();
924         priv->manager = this;
925         priv->backend = new QNetworkAccessCacheBackend();
926         priv->backend->manager = this->d_func();
927         priv->backend->setParent(reply);
928         priv->backend->reply = priv;
929         priv->setup(op, req, outgoingData);
930         return reply;
931     }
932
933 #ifndef QT_NO_BEARERMANAGEMENT
934     // Return a disabled network reply if network access is disabled.
935     // Except if the scheme is empty or file://.
936     if (!d->networkAccessible && !isLocalFile) {
937         return new QDisabledNetworkReply(this, req, op);
938     }
939
940     if (!d->networkSession && (d->initializeSession || !d->networkConfiguration.isEmpty())) {
941         QNetworkConfigurationManager manager;
942         if (!d->networkConfiguration.isEmpty()) {
943             d->createSession(manager.configurationFromIdentifier(d->networkConfiguration));
944         } else {
945             if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)
946                 d->createSession(manager.defaultConfiguration());
947             else
948                 d->initializeSession = false;
949         }
950     }
951
952     if (d->networkSession)
953         d->networkSession->setSessionProperty(QLatin1String("AutoCloseSessionTimeout"), -1);
954 #endif
955
956     QNetworkRequest request = req;
957     if (!request.header(QNetworkRequest::ContentLengthHeader).isValid() &&
958         outgoingData && !outgoingData->isSequential()) {
959         // request has no Content-Length
960         // but the data that is outgoing is random-access
961         request.setHeader(QNetworkRequest::ContentLengthHeader, outgoingData->size());
962     }
963
964     if (static_cast<QNetworkRequest::LoadControl>
965         (request.attribute(QNetworkRequest::CookieLoadControlAttribute,
966                            QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Automatic) {
967         if (d->cookieJar) {
968             QList<QNetworkCookie> cookies = d->cookieJar->cookiesForUrl(request.url());
969             if (!cookies.isEmpty())
970                 request.setHeader(QNetworkRequest::CookieHeader, QVariant::fromValue(cookies));
971         }
972     }
973
974     // first step: create the reply
975     QUrl url = request.url();
976     QNetworkReplyImpl *reply = new QNetworkReplyImpl(this);
977 #ifndef QT_NO_BEARERMANAGEMENT
978     if (!isLocalFile) {
979         connect(this, SIGNAL(networkSessionConnected()),
980                 reply, SLOT(_q_networkSessionConnected()));
981     }
982 #endif
983     QNetworkReplyImplPrivate *priv = reply->d_func();
984     priv->manager = this;
985
986     // second step: fetch cached credentials
987     // This is not done for the time being, we should use signal emissions to request
988     // the credentials from cache.
989
990     // third step: find a backend
991     priv->backend = d->findBackend(op, request);
992
993 #ifndef QT_NO_NETWORKPROXY
994     QList<QNetworkProxy> proxyList = d->queryProxy(QNetworkProxyQuery(request.url()));
995     priv->proxyList = proxyList;
996 #endif
997     if (priv->backend) {
998         priv->backend->setParent(reply);
999         priv->backend->reply = priv;
1000     }
1001
1002 #ifndef QT_NO_OPENSSL
1003     reply->setSslConfiguration(request.sslConfiguration());
1004 #endif
1005
1006     // fourth step: setup the reply
1007     priv->setup(op, request, outgoingData);
1008
1009     return reply;
1010 }
1011
1012 void QNetworkAccessManagerPrivate::_q_replyFinished()
1013 {
1014     Q_Q(QNetworkAccessManager);
1015
1016     QNetworkReply *reply = qobject_cast<QNetworkReply *>(q->sender());
1017     if (reply)
1018         emit q->finished(reply);
1019
1020 #ifndef QT_NO_BEARERMANAGEMENT
1021     if (networkSession && q->findChildren<QNetworkReply *>().count() == 1)
1022         networkSession->setSessionProperty(QLatin1String("AutoCloseSessionTimeout"), 120000);
1023 #endif
1024 }
1025
1026 void QNetworkAccessManagerPrivate::_q_replySslErrors(const QList<QSslError> &errors)
1027 {
1028 #ifndef QT_NO_OPENSSL
1029     Q_Q(QNetworkAccessManager);
1030     QNetworkReply *reply = qobject_cast<QNetworkReply *>(q->sender());
1031     if (reply)
1032         emit q->sslErrors(reply, errors);
1033 #else
1034     Q_UNUSED(errors);
1035 #endif
1036 }
1037
1038 QNetworkReply *QNetworkAccessManagerPrivate::postProcess(QNetworkReply *reply)
1039 {
1040     Q_Q(QNetworkAccessManager);
1041     QNetworkReplyPrivate::setManager(reply, q);
1042     q->connect(reply, SIGNAL(finished()), SLOT(_q_replyFinished()));
1043 #ifndef QT_NO_OPENSSL
1044     /* In case we're compiled without SSL support, we don't have this signal and we need to
1045      * avoid getting a connection error. */
1046     q->connect(reply, SIGNAL(sslErrors(QList<QSslError>)), SLOT(_q_replySslErrors(QList<QSslError>)));
1047 #endif
1048
1049     return reply;
1050 }
1051
1052 void QNetworkAccessManagerPrivate::createCookieJar() const
1053 {
1054     if (!cookieJarCreated) {
1055         // keep the ugly hack in here
1056         QNetworkAccessManagerPrivate *that = const_cast<QNetworkAccessManagerPrivate *>(this);
1057         that->cookieJar = new QNetworkCookieJar(that->q_func());
1058         that->cookieJarCreated = true;
1059     }
1060 }
1061
1062 void QNetworkAccessManagerPrivate::authenticationRequired(QNetworkAccessBackend *backend,
1063                                                           QAuthenticator *authenticator)
1064 {
1065     Q_Q(QNetworkAccessManager);
1066
1067     // FIXME: Add support for domains (i.e., the leading path)
1068     QUrl url = backend->reply->url;
1069
1070     // don't try the cache for the same URL twice in a row
1071     // being called twice for the same URL means the authentication failed
1072     // also called when last URL is empty, e.g. on first call
1073     if (backend->reply->urlForLastAuthentication.isEmpty()
1074             || url != backend->reply->urlForLastAuthentication) {
1075         QNetworkAuthenticationCredential cred = authenticationManager->fetchCachedCredentials(url, authenticator);
1076         if (!cred.isNull()) {
1077             authenticator->setUser(cred.user);
1078             authenticator->setPassword(cred.password);
1079             backend->reply->urlForLastAuthentication = url;
1080             return;
1081         }
1082     }
1083
1084     // if we emit a signal here in synchronous mode, the user might spin
1085     // an event loop, which might recurse and lead to problems
1086     if (backend->isSynchronous())
1087         return;
1088
1089     backend->reply->urlForLastAuthentication = url;
1090     emit q->authenticationRequired(backend->reply->q_func(), authenticator);
1091     authenticationManager->cacheCredentials(url, authenticator);
1092 }
1093
1094 #ifndef QT_NO_NETWORKPROXY
1095 void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(QNetworkAccessBackend *backend,
1096                                                                const QNetworkProxy &proxy,
1097                                                                QAuthenticator *authenticator)
1098 {
1099     Q_Q(QNetworkAccessManager);
1100     // ### FIXME Tracking of successful authentications
1101     // This code is a bit broken right now for SOCKS authentication
1102     // first request: proxyAuthenticationRequired gets emitted, credentials gets saved
1103     // second request: (proxy != backend->reply->lastProxyAuthentication) does not evaluate to true,
1104     //      proxyAuthenticationRequired gets emitted again
1105     // possible solution: some tracking inside the authenticator
1106     //      or a new function proxyAuthenticationSucceeded(true|false)
1107     if (proxy != backend->reply->lastProxyAuthentication) {
1108         QNetworkAuthenticationCredential cred = authenticationManager->fetchCachedProxyCredentials(proxy);
1109         if (!cred.isNull()) {
1110             authenticator->setUser(cred.user);
1111             authenticator->setPassword(cred.password);
1112             return;
1113         }
1114     }
1115
1116     // if we emit a signal here in synchronous mode, the user might spin
1117     // an event loop, which might recurse and lead to problems
1118     if (backend->isSynchronous())
1119         return;
1120
1121     backend->reply->lastProxyAuthentication = proxy;
1122     emit q->proxyAuthenticationRequired(proxy, authenticator);
1123     authenticationManager->cacheProxyCredentials(proxy, authenticator);
1124 }
1125
1126 QList<QNetworkProxy> QNetworkAccessManagerPrivate::queryProxy(const QNetworkProxyQuery &query)
1127 {
1128     QList<QNetworkProxy> proxies;
1129     if (proxyFactory) {
1130         proxies = proxyFactory->queryProxy(query);
1131         if (proxies.isEmpty()) {
1132             qWarning("QNetworkAccessManager: factory %p has returned an empty result set",
1133                      proxyFactory);
1134             proxies << QNetworkProxy::NoProxy;
1135         }
1136     } else if (proxy.type() == QNetworkProxy::DefaultProxy) {
1137         // no proxy set, query the application
1138         return QNetworkProxyFactory::proxyForQuery(query);
1139     } else {
1140         proxies << proxy;
1141     }
1142
1143     return proxies;
1144 }
1145 #endif
1146
1147 void QNetworkAccessManagerPrivate::clearCache(QNetworkAccessManager *manager)
1148 {
1149     manager->d_func()->objectCache.clear();
1150     manager->d_func()->authenticationManager->clearCache();
1151
1152     if (manager->d_func()->httpThread) {
1153         // The thread will deleteLater() itself from its finished() signal
1154         manager->d_func()->httpThread->quit();
1155         manager->d_func()->httpThread = 0;
1156     }
1157 }
1158
1159 QNetworkAccessManagerPrivate::~QNetworkAccessManagerPrivate()
1160 {
1161     if (httpThread) {
1162         // The thread will deleteLater() itself from its finished() signal
1163         httpThread->quit();
1164         httpThread = 0;
1165     }
1166 }
1167
1168 #ifndef QT_NO_BEARERMANAGEMENT
1169 void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &config)
1170 {
1171     Q_Q(QNetworkAccessManager);
1172
1173     initializeSession = false;
1174
1175     QSharedPointer<QNetworkSession> newSession;
1176     if (config.isValid())
1177         newSession = QSharedNetworkSessionManager::getSession(config);
1178
1179     if (networkSession) {
1180         //do nothing if new and old session are the same
1181         if (networkSession == newSession)
1182             return;
1183         //disconnect from old session
1184         QObject::disconnect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()));
1185         QObject::disconnect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()));
1186         QObject::disconnect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)),
1187             q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)));
1188     }
1189
1190     //switch to new session (null if config was invalid)
1191     networkSession = newSession;
1192
1193     if (!networkSession) {
1194         online = false;
1195
1196         if (networkAccessible == QNetworkAccessManager::NotAccessible)
1197             emit q->networkAccessibleChanged(QNetworkAccessManager::NotAccessible);
1198         else
1199             emit q->networkAccessibleChanged(QNetworkAccessManager::UnknownAccessibility);
1200
1201         return;
1202     }
1203
1204     //connect to new session
1205     QObject::connect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()), Qt::QueuedConnection);
1206     //QueuedConnection is used to avoid deleting the networkSession inside its closed signal
1207     QObject::connect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()), Qt::QueuedConnection);
1208     QObject::connect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)),
1209                      q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection);
1210
1211     _q_networkSessionStateChanged(networkSession->state());
1212 }
1213
1214 void QNetworkAccessManagerPrivate::_q_networkSessionClosed()
1215 {
1216     Q_Q(QNetworkAccessManager);
1217     if (networkSession) {
1218         networkConfiguration = networkSession->configuration().identifier();
1219
1220         //disconnect from old session
1221         QObject::disconnect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()));
1222         QObject::disconnect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()));
1223         QObject::disconnect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)),
1224             q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)));
1225         networkSession.clear();
1226     }
1227 }
1228
1229 void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession::State state)
1230 {
1231     Q_Q(QNetworkAccessManager);
1232
1233     //Do not emit the networkSessionConnected signal here, except for roaming -> connected
1234     //transition, otherwise it is emitted twice in a row when opening a connection.
1235     if (state == QNetworkSession::Connected && lastSessionState == QNetworkSession::Roaming)
1236         emit q->networkSessionConnected();
1237     lastSessionState = state;
1238
1239     if (online) {
1240         if (state != QNetworkSession::Connected && state != QNetworkSession::Roaming) {
1241             online = false;
1242             emit q->networkAccessibleChanged(QNetworkAccessManager::NotAccessible);
1243         }
1244     } else {
1245         if (state == QNetworkSession::Connected || state == QNetworkSession::Roaming) {
1246             online = true;
1247             emit q->networkAccessibleChanged(networkAccessible);
1248         }
1249     }
1250 }
1251 #endif // QT_NO_BEARERMANAGEMENT
1252
1253 QNetworkRequest QNetworkAccessManagerPrivate::prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart)
1254 {
1255     // copy the request, we probably need to add some headers
1256     QNetworkRequest newRequest(request);
1257
1258     // add Content-Type header if not there already
1259     if (!request.header(QNetworkRequest::ContentTypeHeader).isValid()) {
1260         QByteArray contentType;
1261         contentType.reserve(34 + multiPart->d_func()->boundary.count());
1262         contentType += "multipart/";
1263         switch (multiPart->d_func()->contentType) {
1264         case QHttpMultiPart::RelatedType:
1265             contentType += "related";
1266             break;
1267         case QHttpMultiPart::FormDataType:
1268             contentType += "form-data";
1269             break;
1270         case QHttpMultiPart::AlternativeType:
1271             contentType += "alternative";
1272             break;
1273         default:
1274             contentType += "mixed";
1275             break;
1276         }
1277         // putting the boundary into quotes, recommended in RFC 2046 section 5.1.1
1278         contentType += "; boundary=\"" + multiPart->d_func()->boundary + "\"";
1279         newRequest.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentType));
1280     }
1281
1282     // add MIME-Version header if not there already (we must include the header
1283     // if the message conforms to RFC 2045, see section 4 of that RFC)
1284     QByteArray mimeHeader("MIME-Version");
1285     if (!request.hasRawHeader(mimeHeader))
1286         newRequest.setRawHeader(mimeHeader, QByteArray("1.0"));
1287
1288     QIODevice *device = multiPart->d_func()->device;
1289     if (!device->isReadable()) {
1290         if (!device->isOpen()) {
1291             if (!device->open(QIODevice::ReadOnly))
1292                 qWarning("could not open device for reading");
1293         } else {
1294             qWarning("device is not readable");
1295         }
1296     }
1297
1298     return newRequest;
1299 }
1300
1301 QT_END_NAMESPACE
1302
1303 #include "moc_qnetworkaccessmanager.cpp"