1 #ifndef ZYPP_NG_MEDIA_CURL_DOWNLOADER_H_INCLUDED
2 #define ZYPP_NG_MEDIA_CURL_DOWNLOADER_H_INCLUDED
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>
11 #include <zypp/ByteCount.h>
15 class TransferSettings;
21 class NetworkRequestDispatcher;
22 class DownloaderPrivate;
25 using TransferSettings = zypp::media::TransferSettings;
28 * @brief The Downloader class
30 * Provides a high level interface to the \sa HttpRequestDispatcher,
31 * implementing Metalink on top. If in doubt which one to use, always
34 class LIBZYPP_NG_EXPORT Downloader : public Base
36 ZYPP_DECLARE_PRIVATE( Downloader )
39 using Ptr = std::shared_ptr<Downloader>;
40 using WeakPtr = std::shared_ptr<Downloader>;
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
50 std::shared_ptr<Download> downloadFile ( Url file, zypp::filesystem::Pathname targetPath, zypp::ByteCount expectedFileSize = zypp::ByteCount() );
53 * Returns the internally used \sa zyppng::NetworkRequestDispatcher used by the \a Downloader
54 * to enqueue network requests
56 std::shared_ptr<NetworkRequestDispatcher> requestDispatcher () const;
59 * Emitted when a \sa zyppng::Download created by this Downloader instance was started
61 SignalProxy<void ( Downloader &parent, Download& download )> sigStarted ( );
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
67 SignalProxy<void ( Downloader &parent, Download& download )> sigFinished ( );
70 * Signal is always emitted when there are not Downloads anymore waiting in the queue
72 SignalProxy<void ( Downloader &parent )> queueEmpty ( );
75 class DownloadPrivate;
78 * The Download class represents a possibly multipart download.
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.
85 * zyppng::EventDispatcher::Ptr loop = zyppng::EventDispatcher::createMain();
86 * zyppng::Downloader dl;
88 * dl.queueEmpty().connect( [ &loop ]( zyppng::Downloader & ) {
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");
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;
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;
106 * req->sigAlive().connect( []( zyppng::Download &dl, off_t dlnow ) {
107 * std::cout << dl.targetPath().asString() << " at: " << std::endl
108 * << "dlnow: "<< dlnow<< std::endl;
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;
123 class LIBZYPP_NG_EXPORT Download : public Base
125 ZYPP_DECLARE_PRIVATE( Download )
129 using Ptr = std::shared_ptr<Download>;
130 using WeakPtr = std::shared_ptr<Download>;
133 * The states of the internal state machine. Each of them represents a different
134 * stage of the lifetime of a Download.
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
147 * A download can only directly be created by the \sa zyppng::Downloader
149 Download ( DownloadPrivate &&prv );
152 * Returns the source URL of the download
157 * Returns the target file path, this is where the downloaded data is stored
159 zypp::Pathname targetPath () const;
162 * Returns the current internal state of the Download
163 * \sa zyppng::Download::State
165 State state () const;
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
173 NetworkRequestError lastRequestError () const;
176 * Returns a readable reason why the download failed.
177 * \sa lastRequestError
179 std::string errorString () const;
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.
186 TransferSettings &settings ();
189 * Triggers the start of the download, this needs to be called in order for the statemachine
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
199 void setMultiPartHandlingEnabled ( bool enable = true );
202 * Enables a special mode, in this case only the existance of the file is checked but no data is actually downloaded
204 void setCheckExistsOnly ( bool set = true );
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
210 void setDeltaFile ( const zypp::Pathname &file );
213 * Returns a reference to the internally used \sa zyppng::NetworkRequestDispatcher
215 NetworkRequestDispatcher &dispatcher () const;
218 * Signals that the dispatcher dequeued the request and actually starts downloading data
220 SignalProxy<void ( Download &req )> sigStarted ();
223 * Signals that the state of the \a Download has changed
225 SignalProxy<void ( Download &req, State state )> sigStateChanged ();
228 * Signals that the download is alive but still in initial stage ( trying to figure out if metalink / zsync )
230 SignalProxy<void ( Download &req, off_t dlnow )> sigAlive ();
233 * Signals if there was data read from the download
235 SignalProxy<void ( Download &req, off_t dltotal, off_t dlnow )> sigProgress ();
238 * Signals that the download finished.
240 SignalProxy<void ( Download &req )> sigFinished ( );
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.
246 SignalProxy<void ( Download &req, NetworkAuthData &auth, const std::string &availAuth )> sigAuthRequired ( );