libzypp  17.31.0
MediaHandlerFactory.cc
Go to the documentation of this file.
1 #include "MediaHandlerFactory.h"
2 
3 
4 #include <zypp/base/Logger.h>
5 
6 #include <zypp-media/MediaException>
8 
9 #include <zypp/media/MediaNFS.h>
10 #include <zypp/media/MediaCD.h>
11 #include <zypp/media/MediaDIR.h>
12 #include <zypp/media/MediaDISK.h>
13 #include <zypp/media/MediaCIFS.h>
14 #include <zypp/media/MediaCurl.h>
16 #include <zypp/media/MediaISO.h>
17 #include <zypp/media/MediaPlugin.h>
19 
20 namespace zypp::media {
21 
23  {
24 
25  }
26 
27  std::unique_ptr<MediaHandler> MediaHandlerFactory::createHandler( const Url &o_url, const Pathname &preferred_attach_point )
28  {
29  if(!o_url.isValid()) {
30  MIL << "Url is not valid" << std::endl;
31  ZYPP_THROW(MediaBadUrlException(o_url));
32  }
33 
34  std::unique_ptr<MediaHandler> _handler;
35 
36  UrlResolverPlugin::HeaderList custom_headers;
37  Url url = UrlResolverPlugin::resolveUrl(o_url, custom_headers);
38 
39  std::string scheme = url.getScheme();
40  MIL << "Trying scheme '" << scheme << "'" << std::endl;
41 
42  /*
43  ** WARNING: Don't forget to update MediaAccess::downloads(url)
44  ** if you are adding a new url scheme / handler!
45  */
46  if (scheme == "cd" || scheme == "dvd")
47  _handler = std::make_unique<MediaCD> (url,preferred_attach_point);
48  else if (scheme == "nfs" || scheme == "nfs4")
49  _handler = std::make_unique<MediaNFS> (url,preferred_attach_point);
50  else if (scheme == "iso")
51  _handler = std::make_unique<MediaISO> (url,preferred_attach_point);
52  else if (scheme == "file" || scheme == "dir")
53  _handler = std::make_unique<MediaDIR> (url,preferred_attach_point);
54  else if (scheme == "hd")
55  _handler = std::make_unique<MediaDISK> (url,preferred_attach_point);
56  else if (scheme == "cifs" || scheme == "smb")
57  _handler = std::make_unique<MediaCIFS> (url,preferred_attach_point);
58  else if (scheme == "ftp" || scheme == "tftp" || scheme == "http" || scheme == "https")
59  {
60  enum WhichHandler { choose, curl, multicurl };
61  WhichHandler which = choose;
62  // Leagcy: choose handler in UUrl query
63  if ( const std::string & queryparam = url.getQueryParam("mediahandler"); ! queryparam.empty() ) {
64  if ( queryparam == "network" )
65  which = multicurl;
66  else if ( queryparam == "multicurl" )
67  which = multicurl;
68  else if ( queryparam == "curl" )
69  which = curl;
70  else
71  WAR << "Unknown mediahandler='" << queryparam << "' in URL; Choosing the default" << std::endl;
72  }
73  // Otherwise choose handler through ENV
74  if ( which == choose ) {
75  auto getenvIs = []( std::string_view var, std::string_view val )->bool {
76  const char * v = ::getenv( var.data() );
77  return v && v == val;
78  };
79 
80  if ( getenvIs( "ZYPP_MEDIANETWORK", "1" ) ) {
81  WAR << "network backend preview was removed, defaulting to multicurl." << std::endl;
82  which = multicurl;
83  }
84  else if ( getenvIs( "ZYPP_MULTICURL", "0" ) ) {
85  WAR << "multicurl manually disabled." << std::endl;
86  which = curl;
87  }
88  else
89  which = multicurl;
90  }
91  // Finally use the default
92  std::unique_ptr<MediaNetworkCommonHandler> handler;
93  switch ( which ) {
94  default:
95  case multicurl:
96  handler = std::make_unique<MediaMultiCurl>( url, preferred_attach_point );
97  break;
98 
99  case curl:
100  handler = std::make_unique<MediaCurl>( url, preferred_attach_point );
101  break;
102  }
103  // Set up the handler
104  for ( const auto & el : custom_headers ) {
105  std::string header { el.first };
106  header += ": ";
107  header += el.second;
108  MIL << "Added custom header -> " << header << std::endl;
109  handler->settings().addHeader( std::move(header) );
110  }
111  _handler = std::move(handler);
112 
113  }
114  else if (scheme == "plugin" )
115  _handler = std::make_unique<MediaPlugin> (url,preferred_attach_point);
116  else
117  {
118  ZYPP_THROW(MediaUnsupportedUrlSchemeException(url));
119  }
120 
121  // check created handler
122  if ( !_handler ){
123  ERR << "Failed to create media handler" << std::endl;
124  ZYPP_THROW(MediaSystemException(url, "Failed to create media handler"));
125  }
126 
127  MIL << "Opened: " << *_handler << std::endl;
128  return _handler;
129  }
130 
131 }
std::string getScheme() const
Returns the scheme name of the URL.
Definition: Url.cc:533
#define MIL
Definition: Logger.h:96
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:428
static Url resolveUrl(const Url &url, HeaderList &headers)
Resolves an url using the installed plugins If no plugin is found the url is resolved as its current ...
std::unique_ptr< MediaHandler > _handler
#define ERR
Definition: Logger.h:98
static std::unique_ptr< MediaHandler > createHandler(const Url &o_url, const Pathname &preferred_attach_point)
#define WAR
Definition: Logger.h:97
bool isValid() const
Verifies the Url.
Definition: Url.cc:489
std::multimap< std::string, std::string > HeaderList
Url manipulation class.
Definition: Url.h:91