Imported Upstream version 17.20.0
[platform/upstream/libzypp.git] / zypp / media / MediaAccess.cc
index e8c9b95..265684e 100644 (file)
 #include <ctype.h>
 
 #include <iostream>
+#include <map>
 
 #include "zypp/base/Logger.h"
+#include "zypp/ZConfig.h"
+#include "zypp/PluginScript.h"
 #include "zypp/ExternalProgram.h"
 
 #include "zypp/media/MediaException.h"
 #include "zypp/media/MediaDISK.h"
 #include "zypp/media/MediaCIFS.h"
 #include "zypp/media/MediaCurl.h"
-#include "zypp/media/MediaAria2c.h"
+#include "zypp/media/MediaMultiCurl.h"
 #include "zypp/media/MediaISO.h"
+#include "zypp/media/MediaPlugin.h"
+#include "zypp/media/UrlResolverPlugin.h"
 
 using namespace std;
 
@@ -96,18 +101,21 @@ MediaAccess::dependsOnParent(MediaAccessId parentId,
 
 // open URL
 void
-MediaAccess::open (const Url& url, const Pathname & preferred_attach_point)
+MediaAccess::open (const Url& o_url, const Pathname & preferred_attach_point)
 {
-    if(!url.isValid()) {
+    if(!o_url.isValid()) {
        MIL << "Url is not valid" << endl;
-        ZYPP_THROW(MediaBadUrlException(url));
+        ZYPP_THROW(MediaBadUrlException(o_url));
     }
 
     close();
 
-    std::string scheme = url.getScheme();
+    UrlResolverPlugin::HeaderList custom_headers;
+    Url url = UrlResolverPlugin::resolveUrl(o_url, custom_headers);
 
+    std::string scheme = url.getScheme();
     MIL << "Trying scheme '" << scheme << "'" << endl;
+
     /*
     ** WARNING: Don't forget to update MediaAccess::downloads(url)
     **          if you are adding a new url scheme / handler!
@@ -124,30 +132,56 @@ MediaAccess::open (const Url& url, const Pathname & preferred_attach_point)
         _handler = new MediaDISK (url,preferred_attach_point);
     else if (scheme == "cifs" || scheme == "smb")
        _handler = new MediaCIFS (url,preferred_attach_point);
-    else if (scheme == "ftp" || scheme == "http" || scheme == "https")
+    else if (scheme == "ftp" || scheme == "tftp" || scheme == "http" || scheme == "https")
     {
-        // Another good idea would be activate MediaAria2c handler via external var
-        bool use_aria = true;
-        const char *ariaenv = getenv( "ZYPP_ARIA2C" );
-        // if user disabled it manually
-        if ( ariaenv && ( strcmp(ariaenv, "0" ) == 0 ) )
+        bool use_multicurl = true;
+        string urlmediahandler ( url.getQueryParam("mediahandler") );
+        if ( urlmediahandler == "multicurl" )
         {
-            WAR << "aria2c manually disabled. Falling back to curl" << endl;
-            use_aria = false;
+          use_multicurl = true;
         }
-
-        // disable if it does not exist
-        if ( use_aria && ! MediaAria2c::existsAria2cmd() )
+        else if ( urlmediahandler == "curl" )
         {
-            WAR << "aria2c not found. Falling back to curl" << endl;
-            use_aria = false;
+          use_multicurl = false;
         }
-
-        if ( use_aria )
-            _handler = new MediaAria2c (url,preferred_attach_point);
         else
-            _handler = new MediaCurl (url,preferred_attach_point);
+        {
+          if ( ! urlmediahandler.empty() )
+          {
+            WAR << "unknown mediahandler set: " << urlmediahandler << endl;
+          }
+          const char *multicurlenv = getenv( "ZYPP_MULTICURL" );
+          // if user disabled it manually
+          if ( use_multicurl && multicurlenv && ( strcmp(multicurlenv, "0" ) == 0 ) )
+          {
+              WAR << "multicurl manually disabled." << endl;
+              use_multicurl = false;
+          }
+          else if ( !use_multicurl && multicurlenv && ( strcmp(multicurlenv, "1" ) == 0 ) )
+          {
+              WAR << "multicurl manually enabled." << endl;
+              use_multicurl = true;
+          }
+        }
+
+        MediaCurl *curl;
+
+        if ( use_multicurl )
+            curl = new MediaMultiCurl (url,preferred_attach_point);
+       else
+            curl = new MediaCurl (url,preferred_attach_point);
+
+        for ( const auto & el : custom_headers ) {
+            std::string header { el.first };
+           header += ": ";
+           header += el.second;
+            MIL << "Added custom header -> " << header << endl;
+            curl->settings().addHeader( std::move(header) );
+        }
+        _handler = curl;
     }
+    else if (scheme == "plugin" )
+       _handler = new MediaPlugin (url,preferred_attach_point);
     else
     {
        ZYPP_THROW(MediaUnsupportedUrlSchemeException(url));
@@ -302,13 +336,13 @@ MediaAccess::release( const std::string & ejectDev )
 // filename is interpreted relative to the attached url
 // and a path prefix is preserved to destination
 void
-MediaAccess::provideFile( const Pathname & filename ) const
+MediaAccess::provideFile(const Pathname & filename , const ByteCount &expectedFileSize) const
 {
   if ( !_handler ) {
     ZYPP_THROW(MediaNotOpenException("provideFile(" + filename.asString() + ")"));
   }
 
-  _handler->provideFile( filename );
+  _handler->provideFile( filename, expectedFileSize );
 }
 
 void
@@ -435,7 +469,7 @@ void MediaAccess::getFile( const Url &from, const Pathname &to )
   try {
     media.open( u );
     media.attach();
-    media._handler->provideFileCopy( base, to );
+    media._handler->provideFileCopy( base, to, 0 );
     media.release();
   }
   catch (const MediaException & excpt_r)