libzypp  17.36.1
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::optional<MediaHandlerFactory::MediaHandlerType> MediaHandlerFactory::handlerType(const Url &url)
28  {
29  std::string scheme = url.getScheme();
30  if (scheme == "cd" || scheme == "dvd")
31  return MediaCDType;
32  else if (scheme == "nfs" || scheme == "nfs4")
33  return MediaNFSType;
34  else if (scheme == "iso")
35  return MediaISOType;
36  else if (scheme == "file" || scheme == "dir")
37  return MediaFileType;
38  else if (scheme == "hd" )
39  return MediaDISKType;
40  else if (scheme == "cifs" || scheme == "smb")
41  return MediaCIFSType;
42  else if (scheme == "ftp" || scheme == "tftp" || scheme == "http" || scheme == "https")
43  return MediaCURLType;
44  else if (scheme == "plugin" )
45  return MediaPluginType;
46  return {};
47  }
48 
49  std::unique_ptr<MediaHandler> MediaHandlerFactory::createHandler( const Url &o_url, const Pathname &preferred_attach_point )
50  {
51  if(!o_url.isValid()) {
52  MIL << "Url is not valid" << std::endl;
54  }
55 
56  UrlResolverPlugin::HeaderList custom_headers;
57  Url url = UrlResolverPlugin::resolveUrl(o_url, custom_headers);
58  MIL << "Trying scheme '" << url.getScheme() << "'" << std::endl;
59 
60  const auto hdlType = handlerType( url );
61  if ( !hdlType ) {
63  }
64 
65  std::unique_ptr<MediaHandler> _handler;
66  switch(*hdlType) {
67  case MediaCDType: {
68  _handler = std::make_unique<MediaCD> (url,preferred_attach_point);
69  break;
70  }
71  case MediaNFSType: {
72  _handler = std::make_unique<MediaNFS> (url,preferred_attach_point);
73  break;
74  }
75  case MediaISOType: {
76  _handler = std::make_unique<MediaISO> (url,preferred_attach_point);
77  break;
78  }
79  case MediaFileType: {
80  _handler = std::make_unique<MediaDIR> (url,preferred_attach_point);
81  break;
82  }
83  case MediaDISKType: {
84  _handler = std::make_unique<MediaDISK> (url,preferred_attach_point);
85  break;
86  }
87  case MediaCIFSType: {
88  _handler = std::make_unique<MediaCIFS> (url,preferred_attach_point);
89  break;
90  }
91  case MediaCURLType: {
92  enum WhichHandler { choose, curl, multicurl };
93  WhichHandler which = choose;
94  // Leagcy: choose handler in UUrl query
95  if ( const std::string & queryparam = url.getQueryParam("mediahandler"); ! queryparam.empty() ) {
96  if ( queryparam == "network" || queryparam == "multicurl" )
97  which = multicurl;
98  else if ( queryparam == "curl" )
99  which = curl;
100  else
101  WAR << "Unknown mediahandler='" << queryparam << "' in URL; Choosing the default" << std::endl;
102  }
103  // Otherwise choose handler through ENV
104  if ( which == choose ) {
105  auto getenvIs = []( std::string_view var, std::string_view val )->bool {
106  const char * v = ::getenv( var.data() );
107  return v && v == val;
108  };
109 
110  if ( getenvIs( "ZYPP_MULTICURL", "0" ) ) {
111  WAR << "multicurl manually disabled." << std::endl;
112  which = curl;
113  }
114  else
115  which = multicurl;
116  }
117  // Finally use the default
118  std::unique_ptr<MediaNetworkCommonHandler> handler;
119  switch ( which ) {
120  default:
121  case multicurl:
122  handler = std::make_unique<MediaMultiCurl>( url, preferred_attach_point );
123  break;
124  case curl:
125  handler = std::make_unique<MediaCurl>( url, preferred_attach_point );
126  break;
127  }
128  // Set up the handler
129  for ( const auto & el : custom_headers ) {
130  std::string header { el.first };
131  header += ": ";
132  header += el.second;
133  MIL << "Added custom header -> " << header << std::endl;
134  handler->settings().addHeader( std::move(header) );
135  }
136  _handler = std::move(handler);
137  break;
138  }
139  case MediaPluginType: {
140  // bsc#1228208: MediaPluginType must be resolved to a valid schema by the
141  // above UrlResolverPlugin::resolveUrl call. MediaPlugin exists as a stub,
142  // but is not a usable handler type.
144  break;
145  }
146  }
147 
148  if ( !_handler ) {
150  }
151 
152  // check created handler
153  if ( !_handler ){
154  ERR << "Failed to create media handler" << std::endl;
155  ZYPP_THROW(MediaSystemException(url, "Failed to create media handler"));
156  }
157 
158  MIL << "Opened: " << *_handler << std::endl;
159  return _handler;
160  }
161 
162 }
std::string getScheme() const
Returns the scheme name of the URL.
Definition: Url.cc:551
#define MIL
Definition: Logger.h:100
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:424
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:102
static std::unique_ptr< MediaHandler > createHandler(const Url &o_url, const Pathname &preferred_attach_point)
std::string getQueryParam(const std::string &param, EEncoding eflag=zypp::url::E_DECODED) const
Return the value for the specified query parameter.
Definition: Url.cc:678
#define WAR
Definition: Logger.h:101
static std::optional< MediaHandlerType > handlerType(const Url &url)
bool isValid() const
Verifies the Url.
Definition: Url.cc:507
std::multimap< std::string, std::string > HeaderList
Url manipulation class.
Definition: Url.h:92