Imported Upstream version 17.20.0
[platform/upstream/libzypp.git] / zypp / media / MediaAccess.cc
index ac4f1fd..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/MediaAccess.h"
 #include "zypp/media/MediaCD.h"
 #include "zypp/media/MediaDIR.h"
 #include "zypp/media/MediaDISK.h"
-#include "zypp/media/MediaSMB.h"
 #include "zypp/media/MediaCIFS.h"
 #include "zypp/media/MediaCurl.h"
+#include "zypp/media/MediaMultiCurl.h"
+#include "zypp/media/MediaISO.h"
+#include "zypp/media/MediaPlugin.h"
+#include "zypp/media/UrlResolverPlugin.h"
 
 using namespace std;
 
@@ -72,37 +79,109 @@ MediaAccess::isSharedMedia() const
                        : false;
 }
 
+void
+MediaAccess::resetParentId()
+{
+       if( _handler) _handler->resetParentId();
+}
+
+bool
+MediaAccess::dependsOnParent() const
+{
+       return _handler ? _handler->dependsOnParent() : false;
+}
+
+bool
+MediaAccess::dependsOnParent(MediaAccessId parentId,
+                             bool exactIdMatch) const
+{
+       return _handler ? _handler->dependsOnParent(parentId, exactIdMatch)
+                       : false;
+}
+
 // 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!
+    */
     if (scheme == "cd" || scheme == "dvd")
         _handler = new MediaCD (url,preferred_attach_point);
-    else if (scheme == "nfs")
+    else if (scheme == "nfs" || scheme == "nfs4")
         _handler = new MediaNFS (url,preferred_attach_point);
-//    else if (scheme == "iso")
-//        _handler = new MediaISO (url,preferred_attach_point);
+    else if (scheme == "iso")
+        _handler = new MediaISO (url,preferred_attach_point);
     else if (scheme == "file" || scheme == "dir")
         _handler = new MediaDIR (url,preferred_attach_point);
     else if (scheme == "hd")
         _handler = new MediaDISK (url,preferred_attach_point);
-    else if (scheme == "smb")
-       _handler = new MediaSMB (url,preferred_attach_point);
-    else if (scheme == "cifs")
-        _handler = new MediaCIFS (url,preferred_attach_point);
-    else if (scheme == "ftp" || scheme == "http" || scheme == "https")
-        _handler = new MediaCurl (url,preferred_attach_point);
+    else if (scheme == "cifs" || scheme == "smb")
+       _handler = new MediaCIFS (url,preferred_attach_point);
+    else if (scheme == "ftp" || scheme == "tftp" || scheme == "http" || scheme == "https")
+    {
+        bool use_multicurl = true;
+        string urlmediahandler ( url.getQueryParam("mediahandler") );
+        if ( urlmediahandler == "multicurl" )
+        {
+          use_multicurl = true;
+        }
+        else if ( urlmediahandler == "curl" )
+        {
+          use_multicurl = false;
+        }
+        else
+        {
+          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));
@@ -127,6 +206,12 @@ MediaAccess::protocol() const
   return _handler->protocol();
 }
 
+bool
+MediaAccess::downloads() const
+{
+       return _handler ? _handler->downloads() : false;
+}
+
 ///////////////////////////////////////////////////////////////////
 //
 //
@@ -182,9 +267,32 @@ MediaAccess::isAttached() const
   return( _handler && _handler->isAttached() );
 }
 
+
+bool MediaAccess::hasMoreDevices() const
+{
+  return _handler && _handler->hasMoreDevices();
+}
+
+
+void
+MediaAccess::getDetectedDevices(std::vector<std::string> & devices,
+                                unsigned int & index) const
+{
+  if (_handler)
+  {
+    _handler->getDetectedDevices(devices, index);
+    return;
+  }
+
+  if (!devices.empty())
+    devices.clear();
+  index = 0;
+}
+
+
 // local directory that corresponds to medias url
 // If media is not open an empty pathname.
-const Pathname &
+Pathname
 MediaAccess::localRoot() const
 {
   if ( !_handler )
@@ -213,38 +321,38 @@ MediaAccess::disconnect()
   _handler->disconnect();
 }
 
-// release attached media
+
 void
-MediaAccess::release( bool eject )
+MediaAccess::release( const std::string & ejectDev )
 {
   if ( !_handler )
     return;
 
-  _handler->release( eject );
+  _handler->release( ejectDev );
 }
 
-
 // provide file denoted by path to attach dir
 //
 // filename is interpreted relative to the attached url
 // and a path prefix is preserved to destination
 void
-MediaAccess::provideFile( const Pathname & filename, bool cached, bool checkonly) const
+MediaAccess::provideFile(const Pathname & filename , const ByteCount &expectedFileSize) const
 {
-  if ( cached ) {
-    PathInfo pi( localPath( filename ) );
-    if ( pi.isExist() )
-      return;
+  if ( !_handler ) {
+    ZYPP_THROW(MediaNotOpenException("provideFile(" + filename.asString() + ")"));
   }
 
-  if(checkonly)
-    ZYPP_THROW(MediaFileNotFoundException(url(), filename));
+  _handler->provideFile( filename, expectedFileSize );
+}
 
+void
+MediaAccess::setDeltafile( const Pathname & filename ) const
+{
   if ( !_handler ) {
-    ZYPP_THROW(MediaNotOpenException("provideFile(" + filename.asString() + ")"));
+    ZYPP_THROW(MediaNotOpenException("setDeltafile(" + filename.asString() + ")"));
   }
 
-  _handler->provideFile( filename );
+  _handler->setDeltafile( filename );
 }
 
 void
@@ -300,7 +408,7 @@ MediaAccess::releasePath( const Pathname & pathname ) const
 
 // Return content of directory on media
 void
-MediaAccess::dirInfo( list<string> & retlist, const Pathname & dirname, bool dots ) const
+MediaAccess::dirInfo( std::list<std::string> & retlist, const Pathname & dirname, bool dots ) const
 {
   retlist.clear();
 
@@ -324,6 +432,17 @@ MediaAccess::dirInfo( filesystem::DirContent & retlist, const Pathname & dirname
   _handler->dirInfo( retlist, dirname, dots );
 }
 
+// return if a file exists
+bool
+MediaAccess::doesFileExist( const Pathname & filename ) const
+{
+  if ( !_handler ) {
+    ZYPP_THROW(MediaNotOpenException("doesFileExist(" + filename.asString() + ")"));
+  }
+
+  return _handler->doesFileExist( filename );
+}
+
 std::ostream &
 MediaAccess::dumpOn( std::ostream & str ) const
 {
@@ -350,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)
@@ -358,6 +477,7 @@ void MediaAccess::getFile( const Url &from, const Pathname &to )
     ZYPP_RETHROW(excpt_r);
   }
 }
+
     std::ostream & operator<<( std::ostream & str, const MediaAccess & obj )
     { return obj.dumpOn( str ); }