Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / zypp / media / MediaAccess.cc
index 6c2ac2f..f119b00 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;
 
@@ -95,26 +101,28 @@ 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;
-    SEC << "URL " << url << 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);
@@ -122,12 +130,59 @@ MediaAccess::open (const Url& url, const Pathname & preferred_attach_point)
         _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);
+
+        UrlResolverPlugin::HeaderList::const_iterator it;
+        for (it = custom_headers.begin();
+             it != custom_headers.end();
+             ++it) {
+            std::string header = it->first + ": " + it->second;
+            MIL << "Added custom header -> " << header << endl;
+            curl->settings().addHeader(header);
+        }
+        _handler = curl;
+    }
+    else if (scheme == "plugin" )
+       _handler = new MediaPlugin (url,preferred_attach_point);
     else
     {
        ZYPP_THROW(MediaUnsupportedUrlSchemeException(url));
@@ -142,22 +197,6 @@ MediaAccess::open (const Url& url, const Pathname & preferred_attach_point)
     MIL << "Opened: " << *this << endl;
 }
 
-// STATIC
-bool
-MediaAccess::downloads(const Url &url)
-{
-    std::string scheme( url.getScheme());
-    return (scheme == "ftp" || scheme == "http" || scheme == "https");
-}
-
-// STATIC
-bool
-MediaAccess::canBeVolatile(const Url &url)
-{
-    std::string scheme( url.getScheme());
-    return ! (scheme == "cd" || scheme == "dvd");
-}
-
 // Type of media if open, otherwise NONE.
 std::string
 MediaAccess::protocol() const
@@ -229,6 +268,29 @@ 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.
 Pathname
@@ -260,38 +322,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
 {
-  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 );
+}
 
+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
@@ -416,6 +478,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 ); }