Imported Upstream version 17.22.1
[platform/upstream/libzypp.git] / zypp / zyppng / media / network / downloader.h
1 #ifndef ZYPP_NG_MEDIA_CURL_DOWNLOADER_H_INCLUDED
2 #define ZYPP_NG_MEDIA_CURL_DOWNLOADER_H_INCLUDED
3
4 #include <zypp/zyppng/base/zyppglobal.h>
5 #include <zypp/zyppng/base/Base>
6 #include <zypp/zyppng/base/signals.h>
7 #include <zypp/zyppng/core/Url>
8 #include <zypp/zyppng/media/network/networkrequesterror.h>
9 #include <zypp/zyppng/media/network/AuthData>
10
11 #include <zypp/ByteCount.h>
12
13 namespace zypp {
14   namespace media {
15     class TransferSettings;
16   }
17 }
18
19 namespace zyppng {
20
21   class NetworkRequestDispatcher;
22   class DownloaderPrivate;
23   class Download;
24
25   using TransferSettings = zypp::media::TransferSettings;
26
27   /**
28    * @brief The Downloader class
29    *
30    * Provides a high level interface to the \sa HttpRequestDispatcher,
31    * implementing Metalink on top. If in doubt which one to use, always
32    * use this one.
33    */
34   class LIBZYPP_NG_EXPORT Downloader : public Base
35   {
36     ZYPP_DECLARE_PRIVATE( Downloader )
37   public:
38
39     using Ptr = std::shared_ptr<Downloader>;
40     using WeakPtr = std::shared_ptr<Downloader>;
41
42     Downloader( );
43
44     /*!
45      * Generates a new Download object in waiting state
46      * \param file the \sa zyppng::Url to the source file that should be downloaded
47      * \param targetPath the local file path where the downloaded file needs to be stored
48      * \param expectedFileSize The expected file size of the source file, can be empty
49      */
50     std::shared_ptr<Download> downloadFile ( Url file, zypp::filesystem::Pathname targetPath, zypp::ByteCount expectedFileSize = zypp::ByteCount() );
51
52     /*!
53      * Returns the internally used \sa zyppng::NetworkRequestDispatcher used by the \a Downloader
54      * to enqueue network requests
55      */
56     std::shared_ptr<NetworkRequestDispatcher> requestDispatcher () const;
57
58     /*!
59      * Emitted when a \sa zyppng::Download created by this Downloader instance was started
60      */
61     SignalProxy<void ( Downloader &parent, Download& download )> sigStarted  ( );
62
63     /*!
64      * Signal that is emitted when a \sa zyppng::Download created by this Downloader instance was finished
65      * \note Just as with \sa zyppng::NetworkRequest 's the finished signal does not mean the Download was successful
66      */
67     SignalProxy<void ( Downloader &parent, Download& download )> sigFinished ( );
68
69     /*!
70      * Signal is always emitted when there are not Downloads anymore waiting in the queue
71      */
72     SignalProxy<void ( Downloader &parent )> queueEmpty ( );
73   };
74
75   class DownloadPrivate;
76
77   /*!
78    * The Download class represents a possibly multipart download.
79    *
80    * The \a Download class is a more high level interface compared to \sa zyppng::NetworkRequest, it can internally
81    * make use of features like metalinks and tries to be as resilient as possible with errors during a download. Due to this
82    * it is represented internally as a state machine. All transitions are signalled and can be followed.
83    *
84    * \code
85    * zyppng::EventDispatcher::Ptr loop = zyppng::EventDispatcher::createMain();
86    * zyppng::Downloader dl;
87    *
88    * dl.queueEmpty().connect( [ &loop ]( zyppng::Downloader & ) {
89    *   loop->quit();
90    * });
91    *
92    * zypp::Url url ( "https://download.opensuse.org/distribution/leap/15.0/repo/oss/x86_64/0ad-0.0.22-lp150.2.10.x86_64.rpm" );
93    * zypp::Pathname target("/tmp/0ad-0.0.22-lp150.2.10.x86_64.rpm");
94    *
95    * std::shared_ptr<zyppng::Download> req = dl.downloadFile( url, target );
96    * req->sigStarted().connect( []( zyppng::Download &dl ) {
97    *   std::cout << "Download started: " << dl.targetPath() << std::endl;
98    * });
99    *
100    * req->sigFinished().connect( []( zyppng::Download &dl ) {
101    *   std::cout << "Download finished: " << dl.targetPath() << std::endl;
102    *   if ( dl.state() != zyppng::Download::Success )
103    *     std::cout << "\t has error: " << dl.errorString() << std::endl;
104    * });
105    *
106    * req->sigAlive().connect( []( zyppng::Download &dl, off_t dlnow ) {
107    *   std::cout << dl.targetPath().asString() << " at: " << std::endl
108    *             << "dlnow: "<< dlnow<< std::endl;
109    * });
110    *
111    * req->sigProgress().connect( []( zyppng::Download &dl, off_t dltotal, off_t dlnow ) {
112    *   std::cout << dl.targetPath().asString() << " at: " << std::endl
113    *             << "dltotal: "<< dltotal<< std::endl
114    *             << "dlnow: "<< dlnow<< std::endl;
115    * });
116    *
117    * req->start();
118    * loop->run();
119    *
120    * \endcode
121    *
122    */
123   class LIBZYPP_NG_EXPORT Download : public Base
124   {
125     ZYPP_DECLARE_PRIVATE( Download )
126
127   public:
128
129     using Ptr = std::shared_ptr<Download>;
130     using WeakPtr = std::shared_ptr<Download>;
131
132     /*!
133      * The states of the internal state machine. Each of them represents a different
134      * stage of the lifetime of a Download.
135      */
136     enum State {
137       InitialState,  //< This is the initial state, its only set before a download starts
138       Initializing = 10,  //< This state is kept during the first 265Bytes or until the data looks like a Metalink download
139       Running      = 20,  //< This state is set once there have been more than 256 bytes downloaded and it does not look like a metalink download
140       RunningMulti = 30,  //< Signals that the file is downloaded in chunks from different mirrors
141       Success = 200, //< Shows that the Download was successful
142       Failed         //< Shows that the Download failed
143     };
144
145
146     /*!
147      * A download can only directly be created by the \sa zyppng::Downloader
148      */
149     Download ( DownloadPrivate &&prv );
150
151     /*!
152      * Returns the source URL of the download
153      */
154     Url url () const;
155
156     /*!
157      * Returns the target file path, this is where the downloaded data is stored
158      */
159     zypp::Pathname targetPath () const;
160
161     /*!
162      * Returns the current internal state of the Download
163      * \sa zyppng::Download::State
164      */
165     State state () const;
166
167     /*!
168      * Returns the last \sa zyppng::NetworkRequestError enountered while downloading the file.
169      * This will just represent the very last error that could not be recovered from. In case of
170      * a Metalink download that ususally means that all mirrors and the initial URL failed to download for
171      * some reason.
172      */
173     NetworkRequestError lastRequestError () const;
174
175     /*!
176      * Returns a readable reason why the download failed.
177      * \sa lastRequestError
178      */
179     std::string errorString () const;
180
181     /*!
182      * Returns a writeable reference to the \sa zyppng::TransferSettings for the download. The settings are reused for
183      * possible sub downloads, however authentication data is stripped if the subdownload uses a different host to
184      * fetch the data from. If there is no auth data known \sa sigAuthRequired is emitted.
185      */
186     TransferSettings &settings ();
187
188     /*!
189      * Triggers the start of the download, this needs to be called in order for the statemachine
190      * to advance.
191      */
192     void start ();
193
194     /*!
195      * Enabled or disabled multipart handling. Enabled by default.
196      * \note if Multipart is enabled the Download tells the server that it accepts metalink files by adding a specific header
197      *       to the request.
198      */
199     void setMultiPartHandlingEnabled ( bool enable = true );
200
201     /*!
202      * Enables a special mode, in this case only the existance of the file is checked but no data is actually downloaded
203      */
204     void setCheckExistsOnly ( bool set = true );
205
206     /*!
207      * Set a already existing local file to be used for partial downloading, in case of a multichunk download all chunks from the
208      * file that have the expected checksum will be reused instead of downloaded
209      */
210     void setDeltaFile ( const zypp::Pathname &file );
211
212     /*!
213      * Returns a reference to the internally used \sa zyppng::NetworkRequestDispatcher
214      */
215     NetworkRequestDispatcher &dispatcher () const;
216
217     /*!
218      * Signals that the dispatcher dequeued the request and actually starts downloading data
219      */
220     SignalProxy<void ( Download &req )> sigStarted  ();
221
222     /*!
223      * Signals that the state of the \a Download has changed
224      */
225     SignalProxy<void ( Download &req, State state )> sigStateChanged  ();
226
227     /*!
228      * Signals that the download is alive but still in initial stage ( trying to figure out if metalink / zsync )
229      */
230     SignalProxy<void ( Download &req, off_t dlnow  )> sigAlive ();
231
232     /*!
233      * Signals if there was data read from the download
234      */
235     SignalProxy<void ( Download &req, off_t dltotal, off_t dlnow )> sigProgress ();
236
237     /*!
238      * Signals that the download finished.
239      */
240     SignalProxy<void ( Download &req )> sigFinished ( );
241
242     /*!
243      * Is emitted when a request requires authentication and it was not given or if auth failed.
244      * A connected slot should fill in the \a auth information in order to provide login credentials.
245      */
246     SignalProxy<void ( Download &req, NetworkAuthData &auth, const std::string &availAuth )> sigAuthRequired ( );
247   };
248 }
249
250 #endif