- Added toString(ViewOptions)
[platform/upstream/libzypp.git] / zypp / Url.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /**
10  * \file zypp/Url.cc
11  */
12 #include <zypp/Url.h>
13 #include <zypp/base/String.h>
14
15 #include <stdexcept>
16 // FIXME:
17 #if defined(WITH_URL_PARSE_DEBUG)
18 #include <iostream>
19 #endif
20
21 //////////////////////////////////////////////////////////////////////
22 namespace zypp
23 { ////////////////////////////////////////////////////////////////////
24
25
26   using namespace zypp::url;
27
28
29   // -----------------------------------------------------------------
30   /**
31    * url       = [scheme:] [//authority] /path [?query] [#fragment]
32    */
33   #define RX_SPLIT_URL                       "^(([^:/?#]+):)?" \
34                                              "(//([^/?#]*))?"  \
35                                              "([^?#]*)"        \
36                                              "([?]([^#]*))?"   \
37                                              "(#(.*))?"
38
39
40   // -----------------------------------------------------------------
41   // FIXME:
42   class LDAPUrl: public UrlBase
43   {
44   public:
45     LDAPUrl(): UrlBase()
46     {
47       configure();
48     }
49
50     LDAPUrl(const LDAPUrl &url): UrlBase(url)
51    {}
52
53     virtual UrlBase *
54     clone() const
55     {
56       return new LDAPUrl(*this);
57     }
58
59     virtual UrlBase::Schemes
60     getKnownSchemes() const
61     {
62       UrlBase::Schemes schemes(2);
63       schemes[0] = "ldap";
64       schemes[1] = "ldaps";
65       return schemes;
66     }
67
68     virtual void
69     configure()
70     {
71       // => put base-dn to path params :-)
72       // ahm... will this work propelly?
73       //config("sep_pathparams", "/");
74
75       config("psep_querystr",  "?");
76       config("vsep_querystr",  "");
77
78       config("safe_pathname",  "/=,");
79       config("safe_querystr",  "(),=");
80
81       // not allowed here
82       config("rx_username",     "");
83       config("rx_password",     "");
84       config("rx_fragment",     "");
85     }
86   };
87
88
89   // -----------------------------------------------------------------
90   // FIXME:
91   class UrlByScheme
92   {
93   private:
94     typedef std::map<std::string,UrlRef> UrlBySchemeMap;
95     UrlBySchemeMap urlByScheme;
96
97   public:
98     UrlByScheme()
99     {
100       UrlRef ref;
101
102       ref.reset( new LDAPUrl());
103       addUrlByScheme("ldap", ref);
104       addUrlByScheme("ldaps", ref);
105
106       // FIXME: ok?
107       ref.reset( new UrlBase());
108       ref->setViewOptions( ref->getViewOptions() -
109                            zypp::url::ViewOption::EMPTY_AUTHORITY);
110       ref->config("rx_username",      "");
111       ref->config("rx_password",      "");
112       addUrlByScheme("nfs",    ref);
113
114       ref->config("safe_pathname",    "@");
115       ref->config("rx_hostname",      "");
116       ref->config("rx_port",          "");
117       addUrlByScheme("mailto", ref);
118     }
119
120     bool
121     addUrlByScheme(const std::string &scheme,
122                    UrlRef            urlImpl)
123     {
124       if( !scheme.empty() && urlImpl &&
125           urlImpl->isValidScheme(scheme))
126       {
127         UrlRef ref(urlImpl);
128         ref->clear();
129         urlByScheme[scheme] = ref;
130         return true;
131       }
132       return false;
133     }
134
135     UrlRef
136     getUrlByScheme(const std::string &scheme) const
137     {
138       UrlBySchemeMap::const_iterator i(urlByScheme.find(scheme));
139       if( i != urlByScheme.end())
140       {
141         return i->second;
142       }
143       return UrlRef();
144     }
145
146     UrlBase::Schemes
147     getKnownSchemes() const
148     {
149       UrlBySchemeMap::const_iterator i(urlByScheme.begin());
150       UrlBase::Schemes               schemes;
151
152       schemes.reserve(urlByScheme.size());
153       for( ; i != urlByScheme.begin(); ++i)
154       {
155         schemes.push_back(i->first);
156       }
157       return schemes;
158     }
159   };
160
161
162   // -----------------------------------------------------------------
163   UrlByScheme g_urlSchemeRepository;
164
165
166   // -----------------------------------------------------------------
167   Url::~Url()
168   {
169   }
170
171
172   // -----------------------------------------------------------------
173   Url::Url()
174     : m_impl( new UrlBase())
175   {
176   }
177
178
179   // -----------------------------------------------------------------
180   Url::Url(const Url &url)
181     : m_impl( url.m_impl)
182   {
183     if( !m_impl)
184     {
185       throw std::invalid_argument(
186         "Unable to clone Url object"
187       );
188     }
189   }
190
191
192   // -----------------------------------------------------------------
193   Url::Url(const std::string &encodedUrl)
194     : m_impl( parseUrl(encodedUrl))
195   {
196     if( !m_impl)
197     {
198       throw std::invalid_argument(
199         "Unable to parse Url components"
200       );
201     }
202   }
203
204
205   // -----------------------------------------------------------------
206   // static
207   bool
208   Url::registerScheme(const std::string &scheme,
209                       UrlRef            urlImpl)
210   {
211     return g_urlSchemeRepository.addUrlByScheme(scheme, urlImpl);
212   }
213
214
215   // -----------------------------------------------------------------
216   // static
217   UrlRef
218   Url::parseUrl(const std::string &encodedUrl)
219   {
220     UrlRef      url;
221     str::regex  rex(RX_SPLIT_URL);
222     str::smatch out;
223     bool        ret = str::regex_match(encodedUrl, out, rex);
224
225     // FIXME:
226     #if defined(WITH_URL_PARSE_DEBUG)
227     std::cerr << "Regex parsed URL components("
228               << out.size() << "):" << std::endl;
229     std::cerr << "URL " << encodedUrl << std::endl;
230     for(size_t n=0; n < out.size(); n++)
231     {
232       std::cerr << "[" << n << "] " << out[n].str() << std::endl;
233     }
234     #endif
235
236     if(ret && out.size() == 10)
237     {
238       url = g_urlSchemeRepository.getUrlByScheme(out[2].str());
239       if( !url)
240       {
241         url.reset( new UrlBase());
242       }
243       url->init(out[2].str(),
244                 out[4].str(),
245                 out[5].str(),
246                 out[7].str(),
247                 out[9].str());
248     }
249     return url;
250   }
251
252
253   // -----------------------------------------------------------------
254   // static
255   UrlBase::Schemes
256   Url::getAllKnownSchemes()
257   {
258     return g_urlSchemeRepository.getKnownSchemes();
259   }
260
261
262   // -----------------------------------------------------------------
263   UrlBase::Schemes
264   Url::getKnownSchemes() const
265   {
266     return m_impl->getKnownSchemes();
267   }
268
269
270   // -----------------------------------------------------------------
271   bool
272   Url::isValidScheme(const std::string &scheme) const
273   {
274     return m_impl->isValidScheme(scheme);
275   }
276
277
278   // -----------------------------------------------------------------
279   std::string
280   Url::toString() const
281   {
282     return m_impl->toString();
283   }
284
285
286   // -----------------------------------------------------------------
287   std::string
288   Url::toString(const ViewOptions &opts) const
289   {
290     return m_impl->toString(opts);
291   }
292
293
294   // -----------------------------------------------------------------
295   std::string
296   Url::getScheme() const
297   {
298     return m_impl->getScheme();
299   }
300
301
302   // -----------------------------------------------------------------
303   std::string
304   Url::getAuthority() const
305   {
306     return m_impl->getAuthority();
307   }
308
309   // -----------------------------------------------------------------
310   std::string
311   Url::getPathData() const
312   {
313     return m_impl->getPathData();
314   }
315
316   // -----------------------------------------------------------------
317   std::string
318   Url::getQueryString() const
319   {
320     return m_impl->getQueryString();
321   }
322
323   // -----------------------------------------------------------------
324   std::string
325   Url::getFragment(zypp::url::EEncoding eflag) const
326   {
327     return m_impl->getFragment(eflag);
328   }
329
330
331   // -----------------------------------------------------------------
332   std::string
333   Url::getUsername(EEncoding eflag) const
334   {
335     return m_impl->getUsername(eflag);
336   }
337
338   // -----------------------------------------------------------------
339   std::string
340   Url::getPassword(EEncoding eflag) const
341   {
342     return m_impl->getPassword(eflag);
343   }
344
345   // -----------------------------------------------------------------
346   std::string
347   Url::getHost(EEncoding eflag) const
348   {
349     return m_impl->getHost(eflag);
350   }
351
352   // -----------------------------------------------------------------
353   std::string
354   Url::getPort() const
355   {
356     return m_impl->getPort();
357   }
358
359   // -----------------------------------------------------------------
360   std::string
361   Url::getPathName(EEncoding eflag) const
362   {
363     return m_impl->getPathName(eflag);
364   }
365
366   // -----------------------------------------------------------------
367   std::string
368   Url::getPathParams() const
369   {
370     return m_impl->getPathParams();
371   }
372
373
374   // -----------------------------------------------------------------
375   zypp::url::ParamVec
376   Url::getPathParamsVec() const
377   {
378     return m_impl->getPathParamsVec();
379   }
380
381
382   // -----------------------------------------------------------------
383   zypp::url::ParamMap
384   Url::getPathParamsMap(EEncoding eflag) const
385   {
386     return m_impl->getPathParamsMap(eflag);
387   }
388
389
390   // -----------------------------------------------------------------
391   zypp::url::ParamVec
392   Url::getQueryStringVec() const
393   {
394     return m_impl->getQueryStringVec();
395   }
396
397
398   // -----------------------------------------------------------------
399   zypp::url::ParamMap
400   Url::getQueryStringMap(EEncoding eflag) const
401   {
402     return m_impl->getQueryStringMap(eflag);
403   }
404
405
406   // -----------------------------------------------------------------
407   void
408   Url::setScheme(const std::string &scheme)
409   {
410     if(scheme == m_impl->getScheme())
411     {
412       return;
413     }
414     if( m_impl->isKnownScheme(scheme))
415     {
416       m_impl->setScheme(scheme);
417       return;
418     }
419
420     UrlRef url = g_urlSchemeRepository.getUrlByScheme(scheme);
421     if( !url)
422     {
423       url.reset( new UrlBase());
424     }
425     url->init(
426       scheme,
427       m_impl->getAuthority(),
428       m_impl->getPathData(),
429       m_impl->getQueryString(),
430       m_impl->getFragment(zypp::url::E_ENCODED)
431     );
432     m_impl = url;
433   }
434
435
436   // -----------------------------------------------------------------
437   void
438   Url::setAuthority(const std::string &authority)
439   {
440     m_impl->setAuthority(authority);
441   }
442
443
444   // -----------------------------------------------------------------
445   void
446   Url::setPathData(const std::string &pathdata)
447   {
448     m_impl->setPathData(pathdata);
449   }
450
451
452   // -----------------------------------------------------------------
453   void
454   Url::setQueryString(const std::string &querystr)
455   {
456     m_impl->setQueryString(querystr);
457   }
458
459
460   // -----------------------------------------------------------------
461   void
462   Url::setFragment(const std::string &fragment)
463   {
464     m_impl->setFragment(fragment);
465   }
466
467
468   // -----------------------------------------------------------------
469   void
470   Url::setUsername(const std::string &user)
471   {
472     m_impl->setUsername(user);
473   }
474
475
476   // -----------------------------------------------------------------
477   void
478   Url::setPassword(const std::string &pass)
479   {
480     m_impl->setPassword(pass);
481   }
482
483
484   // -----------------------------------------------------------------
485   void
486   Url::setHost(const std::string &host)
487   {
488     m_impl->setHost(host);
489   }
490
491
492   // -----------------------------------------------------------------
493   void
494   Url::setPort(const std::string &port)
495   {
496     m_impl->setPort(port);
497   }
498
499
500   // -----------------------------------------------------------------
501   void
502   Url::setPathName(const std::string &path)
503   {
504     m_impl->setPathName(path);
505   }
506
507
508   // -----------------------------------------------------------------
509   void
510   Url::setPathParams(const std::string &params)
511   {
512     m_impl->setPathParams(params);
513   }
514
515
516   // -----------------------------------------------------------------
517   void
518   Url::setPathParamsVec(const zypp::url::ParamVec &pvec)
519   {
520     m_impl->setPathParamsVec(pvec);
521   }
522
523
524   // -----------------------------------------------------------------
525   void
526   Url::setPathParamsMap(const zypp::url::ParamMap &pmap)
527   {
528     m_impl->setPathParamsMap(pmap);
529   }
530
531
532   // -----------------------------------------------------------------
533   void
534   Url::setQueryStringVec(const zypp::url::ParamVec &pvec)
535   {
536     m_impl->setQueryStringVec(pvec);
537   }
538
539
540   // -----------------------------------------------------------------
541   void
542   Url::setQueryStringMap(const zypp::url::ParamMap &pmap)
543   {
544     m_impl->setQueryStringMap(pmap);
545   }
546
547   // -----------------------------------------------------------------
548   std::ostream & operator<<( std::ostream & str, const Url & url )
549   { return str << url.toString(); }
550
551
552
553   ////////////////////////////////////////////////////////////////////
554 } // namespace zypp
555 //////////////////////////////////////////////////////////////////////
556 /*
557 ** vim: set ts=2 sts=2 sw=2 ai et:
558 */