Imported Upstream version 17.11.1
[platform/upstream/libzypp.git] / zypp / media / MediaCurl.h
index 02ba82e..0d5adaa 100644 (file)
@@ -12,6 +12,8 @@
 #ifndef ZYPP_MEDIA_MEDIACURL_H
 #define ZYPP_MEDIA_MEDIACURL_H
 
+#include "zypp/base/Flags.h"
+#include "zypp/media/TransferSettings.h"
 #include "zypp/media/MediaHandler.h"
 #include "zypp/ZYppCallbacks.h"
 
@@ -27,13 +29,31 @@ namespace zypp {
  * @short Implementation class for FTP, HTTP and HTTPS MediaHandler
  * @see MediaHandler
  **/
-class MediaCurl : public MediaHandler {
+class MediaCurl : public MediaHandler
+{
+  public:
+    enum RequestOption
+    {
+        /** Defaults */
+        OPTION_NONE = 0x0,
+        /** retrieve only a range of the file */
+        OPTION_RANGE = 0x1,
+        /** only issue a HEAD (or equivalent) request */
+        OPTION_HEAD = 0x02,
+        /** to not add a IFMODSINCE header if target exists */
+        OPTION_NO_IFMODSINCE = 0x04,
+        /** do not send a start ProgressReport */
+        OPTION_NO_REPORT_START = 0x08,
+    };
+    ZYPP_DECLARE_FLAGS(RequestOptions,RequestOption);
 
   protected:
 
+    Url clearQueryString(const Url &url) const;
+
     virtual void attachTo (bool next = false);
     virtual void releaseFrom( const std::string & ejectDev );
-    virtual void getFile( const Pathname & filename ) const;
+    virtual void getFile( const Pathname & filename, const ByteCount &expectedFileSize_r ) const override;
     virtual void getDir( const Pathname & dirname, bool recurse_r ) const;
     virtual void getDirInfo( std::list<std::string> & retlist,
                              const Pathname & dirname, bool dots = true ) const;
@@ -62,14 +82,14 @@ class MediaCurl : public MediaHandler {
      * \throws MediaException
      *
      */
-    virtual void getFileCopy( const Pathname & srcFilename, const Pathname & targetFilename) const;
+    virtual void getFileCopy( const Pathname & srcFilename, const Pathname & targetFilename, const ByteCount &expectedFileSize_r) const override;
 
     /**
      *
      * \throws MediaException
      *
      */
-    virtual void doGetFileCopy( const Pathname & srcFilename, const Pathname & targetFilename, callback::SendReport<DownloadProgressReport> & _report) const;
+    virtual void doGetFileCopy( const Pathname & srcFilename, const Pathname & targetFilename, callback::SendReport<DownloadProgressReport> & _report, const ByteCount &expectedFileSize_r,  RequestOptions options = OPTION_NONE ) const;
 
 
     virtual bool checkAttachPoint(const Pathname &apoint) const;
@@ -81,6 +101,8 @@ class MediaCurl : public MediaHandler {
 
     virtual ~MediaCurl() { try { release(); } catch(...) {} }
 
+    TransferSettings & settings();
+
     static void setCookieFile( const Pathname & );
 
     class Callbacks
@@ -91,12 +113,45 @@ class MediaCurl : public MediaHandler {
     };
 
   protected:
+//     /** Callback sending just an alive trigger to the UI, without stats (e.g. during metalink download). */
+    static int aliveCallback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow );
+    /** Callback reporting download progress. */
+    static int progressCallback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow );
+    static CURL *progressCallback_getcurl( void *clientp );
+    /**
+     * check the url is supported by the curl library
+     * \throws MediaBadUrlException if there is a problem
+     **/
+    void checkProtocol(const Url &url) const;
 
-    static int progressCallback( void *clientp, double dltotal, double dlnow,
-                                 double ultotal, double ulnow );
+    /**
+     * initializes the curl easy handle with the data from the url
+     * \throws MediaCurlSetOptException if there is a problem
+     **/
+    virtual void setupEasy();
+    /**
+     * concatenate the attach url and the filename to a complete
+     * download url
+     **/
+    Url getFileUrl(const Pathname & filename) const;
+
+    /**
+     * Evaluates a curl return code and throws the right MediaException
+     * \p filename Filename being downloaded
+     * \p code Code curl returnes
+     * \p timeout Whether we reached timeout, which we need to differentiate
+     *    in case the codes aborted-by-callback or timeout are returned by curl
+     *    Otherwise we can't differentiate abort from timeout. Here you may
+     *    want to pass the progress data object timeout-reached value, or
+     *    just true if you are not doing user interaction.
+     *
+     * \throws MediaException If there is a problem
+     */
+    void evaluateCurlCode(const zypp::Pathname &filename, CURLcode code, bool timeout) const;
 
-    /** The user agent string */
-    static const char *const agentString();
+    void doGetFileCopyFile( const Pathname & srcFilename, const Pathname & dest, FILE *file, callback::SendReport<DownloadProgressReport> & _report, const ByteCount &expectedFileSize_r, RequestOptions options = OPTION_NONE ) const;
+
+    static void resetExpectedFileSize ( void *clientp, const ByteCount &expectedFileSize );
 
   private:
     /**
@@ -105,20 +160,25 @@ class MediaCurl : public MediaHandler {
      */
     std::string getAuthHint() const;
 
+    bool authenticate(const std::string & availAuthTypes, bool firstTry) const;
+
+    bool detectDirIndex() const;
+
   private:
-    CURL *_curl;
-    char _curlError[ CURL_ERROR_SIZE ];
     long _curlDebug;
 
-    mutable std::string _userpwd;
-    std::string _proxy;
-    std::string _proxyuserpwd;
     std::string _currentCookieFile;
-    std::string _ca_path;
-    long        _xfer_timeout;
-
     static Pathname _cookieFile;
+
+    mutable std::string _lastRedirect; ///< to log/report redirections
+
+  protected:
+    CURL *_curl;
+    char _curlError[ CURL_ERROR_SIZE ];
+    curl_slist *_customHeaders;
+    TransferSettings _settings;
 };
+ZYPP_DECLARE_OPERATORS_FOR_FLAGS(MediaCurl::RequestOptions);
 
 ///////////////////////////////////////////////////////////////////