Imported Upstream version 17.14.0
[platform/upstream/libzypp.git] / zypp / media / MediaCurl.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaCurl.h
10  *
11 */
12 #ifndef ZYPP_MEDIA_MEDIACURL_H
13 #define ZYPP_MEDIA_MEDIACURL_H
14
15 #include "zypp/base/Flags.h"
16 #include "zypp/media/TransferSettings.h"
17 #include "zypp/media/MediaHandler.h"
18 #include "zypp/ZYppCallbacks.h"
19
20 #include <curl/curl.h>
21
22 namespace zypp {
23   namespace media {
24
25 ///////////////////////////////////////////////////////////////////
26 //
27 //      CLASS NAME : MediaCurl
28 /**
29  * @short Implementation class for FTP, HTTP and HTTPS MediaHandler
30  * @see MediaHandler
31  **/
32 class MediaCurl : public MediaHandler
33 {
34   public:
35     enum RequestOption
36     {
37         /** Defaults */
38         OPTION_NONE = 0x0,
39         /** retrieve only a range of the file */
40         OPTION_RANGE = 0x1,
41         /** only issue a HEAD (or equivalent) request */
42         OPTION_HEAD = 0x02,
43         /** to not add a IFMODSINCE header if target exists */
44         OPTION_NO_IFMODSINCE = 0x04,
45         /** do not send a start ProgressReport */
46         OPTION_NO_REPORT_START = 0x08,
47     };
48     ZYPP_DECLARE_FLAGS(RequestOptions,RequestOption);
49
50   protected:
51
52     Url clearQueryString(const Url &url) const;
53
54     virtual void attachTo (bool next = false) override;
55     virtual void releaseFrom( const std::string & ejectDev ) override;
56     virtual void getFile( const Pathname & filename, const ByteCount &expectedFileSize_r ) const override;
57     virtual void getDir( const Pathname & dirname, bool recurse_r ) const override;
58     virtual void getDirInfo( std::list<std::string> & retlist,
59                              const Pathname & dirname, bool dots = true ) const override;
60     virtual void getDirInfo( filesystem::DirContent & retlist,
61                              const Pathname & dirname, bool dots = true ) const override;
62     /**
63      * Repeatedly calls doGetDoesFileExist() until it successfully returns,
64      * fails unexpectedly, or user cancels the operation. This is used to
65      * handle authentication or similar retry scenarios on media level.
66      */
67     virtual bool getDoesFileExist( const Pathname & filename ) const override;
68
69     /**
70      * \see MediaHandler::getDoesFileExist
71      */
72     virtual bool doGetDoesFileExist( const Pathname & filename ) const;
73
74     /**
75      *
76      * \throws MediaException
77      *
78      */
79     virtual void disconnectFrom() override;
80     /**
81      *
82      * \throws MediaException
83      *
84      */
85     virtual void getFileCopy( const Pathname & srcFilename, const Pathname & targetFilename, const ByteCount &expectedFileSize_r) const override;
86
87     /**
88      *
89      * \throws MediaException
90      *
91      */
92     virtual void doGetFileCopy( const Pathname & srcFilename, const Pathname & targetFilename, callback::SendReport<DownloadProgressReport> & _report, const ByteCount &expectedFileSize_r,  RequestOptions options = OPTION_NONE ) const;
93
94
95     virtual bool checkAttachPoint(const Pathname &apoint) const override;
96
97   public:
98
99     MediaCurl( const Url &      url_r,
100                const Pathname & attach_point_hint_r );
101
102     virtual ~MediaCurl() override { try { release(); } catch(...) {} }
103
104     TransferSettings & settings();
105
106     static void setCookieFile( const Pathname & );
107
108     class Callbacks
109     {
110       public:
111         virtual ~Callbacks();
112         virtual bool progress( int percent ) = 0;
113     };
114
115   protected:
116 //     /** Callback sending just an alive trigger to the UI, without stats (e.g. during metalink download). */
117     static int aliveCallback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow );
118     /** Callback reporting download progress. */
119     static int progressCallback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow );
120     static CURL *progressCallback_getcurl( void *clientp );
121     /**
122      * check the url is supported by the curl library
123      * \throws MediaBadUrlException if there is a problem
124      **/
125     void checkProtocol(const Url &url) const;
126
127     /**
128      * initializes the curl easy handle with the data from the url
129      * \throws MediaCurlSetOptException if there is a problem
130      **/
131     virtual void setupEasy();
132     /**
133      * concatenate the attach url and the filename to a complete
134      * download url
135      **/
136     Url getFileUrl(const Pathname & filename) const;
137
138     /**
139      * Evaluates a curl return code and throws the right MediaException
140      * \p filename Filename being downloaded
141      * \p code Code curl returnes
142      * \p timeout Whether we reached timeout, which we need to differentiate
143      *    in case the codes aborted-by-callback or timeout are returned by curl
144      *    Otherwise we can't differentiate abort from timeout. Here you may
145      *    want to pass the progress data object timeout-reached value, or
146      *    just true if you are not doing user interaction.
147      *
148      * \throws MediaException If there is a problem
149      */
150     void evaluateCurlCode(const zypp::Pathname &filename, CURLcode code, bool timeout) const;
151
152     void doGetFileCopyFile( const Pathname & srcFilename, const Pathname & dest, FILE *file, callback::SendReport<DownloadProgressReport> & _report, const ByteCount &expectedFileSize_r, RequestOptions options = OPTION_NONE ) const;
153
154     static void resetExpectedFileSize ( void *clientp, const ByteCount &expectedFileSize );
155
156   private:
157     /**
158      * Return a comma separated list of available authentication methods
159      * supported by server.
160      */
161     std::string getAuthHint() const;
162
163     bool authenticate(const std::string & availAuthTypes, bool firstTry) const;
164
165     bool detectDirIndex() const;
166
167   private:
168     long _curlDebug;
169
170     std::string _currentCookieFile;
171     static Pathname _cookieFile;
172
173     mutable std::string _lastRedirect;  ///< to log/report redirections
174
175   protected:
176     CURL *_curl;
177     char _curlError[ CURL_ERROR_SIZE ];
178     curl_slist *_customHeaders;
179     TransferSettings _settings;
180 };
181 ZYPP_DECLARE_OPERATORS_FOR_FLAGS(MediaCurl::RequestOptions);
182
183 ///////////////////////////////////////////////////////////////////
184
185   } // namespace media
186 } // namespace zypp
187
188 #endif // ZYPP_MEDIA_MEDIACURL_H