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