1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
14 #include "zypp/Pathname.h"
15 #include "zypp/base/Gettext.h"
16 #include "zypp/base/String.h"
17 #include "zypp/base/Regex.h"
22 //////////////////////////////////////////////////////////////////////
24 { ////////////////////////////////////////////////////////////////////
27 using namespace zypp::url;
30 // -----------------------------------------------------------------
32 * url = [scheme:] [//authority] /path [?query] [#fragment]
34 #define RX_SPLIT_URL "^([^:/?#]+:|)" \
41 ////////////////////////////////////////////////////////////////////
43 { //////////////////////////////////////////////////////////////////
46 // ---------------------------------------------------------------
47 class LDAPUrl: public UrlBase
55 LDAPUrl(const LDAPUrl &url): UrlBase(url)
61 return new LDAPUrl(*this);
65 getKnownSchemes() const
67 UrlSchemes schemes(2);
76 config("sep_pathparams", "");
78 config("psep_querystr", "?");
79 config("vsep_querystr", "");
81 // host is required (isValid=>false)
82 // but not mandatory (see RFC 2255),
83 // that is, accept empty host.
84 config("require_host", "y");
87 config("rx_username", "");
88 config("rx_password", "");
89 config("rx_fragment", "");
90 config("rx_pathparams", "");
93 virtual zypp::url::ParamMap
94 getQueryStringMap(zypp::url::EEncoding eflag) const
96 static const char * const keys[] = {
97 "attrs", "scope", "filter", "exts", NULL
99 zypp::url::ParamMap pmap;
100 zypp::url::ParamVec pvec( getQueryStringVec());
101 if( pvec.size() <= 4)
103 for(size_t i=0; i<pvec.size(); i++)
105 if(eflag == zypp::url::E_ENCODED)
106 pmap[keys[i]] = pvec[i];
108 pmap[keys[i]] = zypp::url::decode( pvec[i]);
113 ZYPP_THROW(url::UrlNotSupportedException(
114 _("Invalid LDAP URL query string")
121 setQueryStringMap(const zypp::url::ParamMap &pmap)
123 static const char * const keys[] = {
124 "attrs", "scope", "filter", "exts", NULL
127 // remove psep ("?") from safe chars
128 std::string join_safe;
129 std::string safe(config("safe_querystr"));
130 std::string psep(config("psep_querystr"));
131 for(std::string::size_type i=0; i<safe.size(); i++)
133 if( psep.find(safe[i]) == std::string::npos)
134 join_safe.append(1, safe[i]);
137 zypp::url::ParamVec pvec(4);
138 zypp::url::ParamMap::const_iterator p;
139 for(p=pmap.begin(); p!=pmap.end(); ++p)
142 for(size_t i=0; i<4; i++)
144 if(p->first == keys[i])
147 pvec[i] = zypp::url::encode(p->second, join_safe);
152 ZYPP_THROW(url::UrlNotSupportedException(
153 str::form(_("Invalid LDAP URL query parameter '%s'"),
158 setQueryStringVec(pvec);
163 // ---------------------------------------------------------------
168 typedef std::map<std::string,UrlRef> UrlBySchemeMap;
169 UrlBySchemeMap urlByScheme;
176 // =====================================
177 ref.reset( new LDAPUrl());
178 addUrlByScheme("ldap", ref);
179 addUrlByScheme("ldaps", ref);
182 // =====================================
183 ref.reset( new UrlBase());
184 ref->config("with_authority", "n"); // disallow host,...
185 ref->config("require_pathname", "m"); // path is mandatory
186 addUrlByScheme("hd", ref);
187 addUrlByScheme("cd", ref);
188 addUrlByScheme("dvd", ref);
189 addUrlByScheme("dir", ref);
190 addUrlByScheme("iso", ref);
192 // don't show empty authority
193 ref->setViewOptions( zypp::url::ViewOption::DEFAULTS -
194 zypp::url::ViewOption::EMPTY_AUTHORITY);
195 addUrlByScheme("mailto", ref);
196 addUrlByScheme("urn", ref);
197 addUrlByScheme("plugin", ref); // zypp plugable media handler:
199 // RFC1738, 3.10: may contain a host
200 ref->config("with_authority", "y"); // allow host,
201 ref->config("with_port", "n"); // but no port,
202 ref->config("rx_username", ""); // username or
203 ref->config("rx_password", ""); // password ...
204 addUrlByScheme("file", ref);
206 // =====================================
207 ref.reset( new UrlBase());
208 ref->config("require_host", "m"); // host is mandatory
209 addUrlByScheme("nfs", ref);
210 addUrlByScheme("nfs4", ref);
211 addUrlByScheme("smb", ref);
212 addUrlByScheme("cifs", ref);
213 addUrlByScheme("http", ref);
214 addUrlByScheme("https", ref);
215 ref->config("path_encode_slash2", "y"); // always encode 2. slash
216 addUrlByScheme("ftp", ref);
217 addUrlByScheme("sftp", ref);
218 addUrlByScheme("tftp", ref);
222 addUrlByScheme(const std::string &scheme,
225 if( urlImpl && urlImpl->isValidScheme(scheme))
229 urlByScheme[str::toLower(scheme)] = ref;
236 getUrlByScheme(const std::string &scheme) const
238 UrlBySchemeMap::const_iterator i(urlByScheme.find(str::toLower(scheme)));
239 if( i != urlByScheme.end())
247 isRegisteredScheme(const std::string &scheme) const
249 return urlByScheme.find(str::toLower(scheme)) != urlByScheme.end();
253 getRegisteredSchemes() const
255 UrlBySchemeMap::const_iterator i(urlByScheme.begin());
258 schemes.reserve(urlByScheme.size());
259 for( ; i != urlByScheme.end(); ++i)
261 schemes.push_back(i->first);
268 // ---------------------------------------------------------------
269 UrlByScheme & g_urlSchemeRepository()
271 static UrlByScheme _v;
275 //////////////////////////////////////////////////////////////////
276 } // anonymous namespace
277 ////////////////////////////////////////////////////////////////////
280 // -----------------------------------------------------------------
286 // -----------------------------------------------------------------
288 : m_impl( new UrlBase())
293 // -----------------------------------------------------------------
294 Url::Url(const Url &url)
295 : m_impl( url.m_impl)
299 ZYPP_THROW(url::UrlException(
300 _("Unable to clone Url object")
306 // -----------------------------------------------------------------
307 Url::Url(const zypp::url::UrlRef &url)
312 ZYPP_THROW(url::UrlException(
313 _("Invalid empty Url object reference")
319 // -----------------------------------------------------------------
320 Url::Url(const std::string &encodedUrl)
321 : m_impl( parseUrl(encodedUrl))
325 ZYPP_THROW(url::UrlParsingException(
326 _("Unable to parse Url components")
332 // -----------------------------------------------------------------
334 Url::operator = (const std::string &encodedUrl)
336 UrlRef url( parseUrl(encodedUrl));
339 ZYPP_THROW(url::UrlParsingException(
340 _("Unable to parse Url components")
348 // -----------------------------------------------------------------
350 Url::operator = (const Url &url)
357 // -----------------------------------------------------------------
360 Url::registerScheme(const std::string &scheme,
363 return g_urlSchemeRepository().addUrlByScheme(scheme, urlImpl);
367 // -----------------------------------------------------------------
370 Url::parseUrl(const std::string &encodedUrl)
378 str::regex rex(RX_SPLIT_URL);
379 ret = str::regex_match(encodedUrl, out, rex);
384 if(ret && out.size() == 6)
386 std::string scheme = out[1];
387 if (scheme.size() > 1)
388 scheme = scheme.substr(0, scheme.size()-1);
389 std::string authority = out[2];
390 if (authority.size() >= 2)
391 authority = authority.substr(2);
392 std::string query = out[4];
393 if (query.size() > 1)
394 query = query.substr(1);
395 std::string fragment = out[5];
396 if (fragment.size() > 1)
397 fragment = fragment.substr(1);
399 url = g_urlSchemeRepository().getUrlByScheme(scheme);
402 url.reset( new UrlBase());
404 url->init(scheme, authority, out[3],
411 // -----------------------------------------------------------------
413 zypp::url::UrlSchemes
414 Url::getRegisteredSchemes()
416 return g_urlSchemeRepository().getRegisteredSchemes();
420 // -----------------------------------------------------------------
423 Url::isRegisteredScheme(const std::string &scheme)
425 return g_urlSchemeRepository().isRegisteredScheme(scheme);
429 // -----------------------------------------------------------------
430 zypp::url::UrlSchemes
431 Url::getKnownSchemes() const
433 return m_impl->getKnownSchemes();
437 // -----------------------------------------------------------------
439 Url::isValidScheme(const std::string &scheme) const
441 return m_impl->isValidScheme(scheme);
445 ///////////////////////////////////////////////////////////////////
448 inline bool isInList( const char ** begin_r, const char ** end_r, const std::string & scheme_r )
450 for ( ; begin_r != end_r; ++begin_r )
451 if ( scheme_r == *begin_r )
456 bool Url::schemeIsLocal( const std::string & scheme_r )
458 static const char * val[] = { "cd", "dvd", "dir", "hd", "iso", "file" };
459 return isInList( arrayBegin(val), arrayEnd(val), scheme_r );
462 bool Url::schemeIsRemote( const std::string & scheme_r )
464 static const char * val[] = { "http", "https", "nfs", "nfs4", "smb", "cifs", "ftp", "sftp", "tftp" };
465 return isInList( arrayBegin(val), arrayEnd(val), scheme_r );
468 bool Url::schemeIsVolatile( const std::string & scheme_r )
470 static const char * val[] = { "cd", "dvd" };
471 return isInList( arrayBegin(val), arrayEnd(val), scheme_r );
474 bool Url::schemeIsDownloading( const std::string & scheme_r )
476 static const char * val[] = { "http", "https", "ftp", "sftp", "tftp" };
477 return isInList( arrayBegin(val), arrayEnd(val), scheme_r );
479 ///////////////////////////////////////////////////////////////////
481 // -----------------------------------------------------------------
485 return m_impl->isValid();
489 // -----------------------------------------------------------------
491 Url::asString() const
493 return m_impl->asString();
497 // -----------------------------------------------------------------
499 Url::asCompleteString() const
501 // make sure, all url components are included;
502 // regardless of the current configuration...
503 ViewOptions opts(getViewOptions() +
504 ViewOption::WITH_SCHEME +
505 ViewOption::WITH_USERNAME +
506 ViewOption::WITH_PASSWORD +
507 ViewOption::WITH_HOST +
508 ViewOption::WITH_PORT +
509 ViewOption::WITH_PATH_NAME +
510 ViewOption::WITH_PATH_PARAMS +
511 ViewOption::WITH_QUERY_STR +
512 ViewOption::WITH_FRAGMENT);
513 return m_impl->asString(opts);
517 // -----------------------------------------------------------------
519 Url::asString(const ViewOptions &opts) const
521 return m_impl->asString(opts);
525 // -----------------------------------------------------------------
527 Url::getScheme() const
529 return m_impl->getScheme();
533 // -----------------------------------------------------------------
535 Url::getAuthority() const
537 return m_impl->getAuthority();
540 // -----------------------------------------------------------------
542 Url::getPathData() const
544 return m_impl->getPathData();
548 // -----------------------------------------------------------------
550 Url::getQueryString() const
552 return m_impl->getQueryString();
556 // -----------------------------------------------------------------
558 Url::getFragment(zypp::url::EEncoding eflag) const
560 return m_impl->getFragment(eflag);
564 // -----------------------------------------------------------------
566 Url::getUsername(EEncoding eflag) const
568 return m_impl->getUsername(eflag);
572 // -----------------------------------------------------------------
574 Url::getPassword(EEncoding eflag) const
576 return m_impl->getPassword(eflag);
580 // -----------------------------------------------------------------
582 Url::getHost(EEncoding eflag) const
584 return m_impl->getHost(eflag);
588 // -----------------------------------------------------------------
592 return m_impl->getPort();
596 // -----------------------------------------------------------------
598 Url::getPathName(EEncoding eflag) const
600 return m_impl->getPathName(eflag);
604 // -----------------------------------------------------------------
606 Url::getPathParams() const
608 return m_impl->getPathParams();
612 // -----------------------------------------------------------------
614 Url::getPathParamsVec() const
616 return m_impl->getPathParamsVec();
620 // -----------------------------------------------------------------
622 Url::getPathParamsMap(EEncoding eflag) const
624 return m_impl->getPathParamsMap(eflag);
628 // -----------------------------------------------------------------
630 Url::getPathParam(const std::string ¶m, EEncoding eflag) const
632 return m_impl->getPathParam(param, eflag);
636 // -----------------------------------------------------------------
638 Url::getQueryStringVec() const
640 return m_impl->getQueryStringVec();
644 // -----------------------------------------------------------------
646 Url::getQueryStringMap(EEncoding eflag) const
648 return m_impl->getQueryStringMap(eflag);
652 // -----------------------------------------------------------------
654 Url::getQueryParam(const std::string ¶m, EEncoding eflag) const
656 return m_impl->getQueryParam(param, eflag);
660 // -----------------------------------------------------------------
662 Url::setScheme(const std::string &scheme)
664 if(scheme == m_impl->getScheme())
668 if( m_impl->isKnownScheme(scheme))
670 m_impl->setScheme(scheme);
674 UrlRef url = g_urlSchemeRepository().getUrlByScheme(scheme);
677 url.reset( new UrlBase());
681 m_impl->getAuthority(),
682 m_impl->getPathData(),
683 m_impl->getQueryString(),
684 m_impl->getFragment(zypp::url::E_ENCODED)
690 // -----------------------------------------------------------------
692 Url::setAuthority(const std::string &authority)
694 m_impl->setAuthority(authority);
698 // -----------------------------------------------------------------
700 Url::setPathData(const std::string &pathdata)
702 m_impl->setPathData(pathdata);
706 // -----------------------------------------------------------------
708 Url::setQueryString(const std::string &querystr)
710 m_impl->setQueryString(querystr);
714 // -----------------------------------------------------------------
716 Url::setFragment(const std::string &fragment, EEncoding eflag)
718 m_impl->setFragment(fragment, eflag);
722 // -----------------------------------------------------------------
724 Url::setUsername(const std::string &user,
727 m_impl->setUsername(user, eflag);
731 // -----------------------------------------------------------------
733 Url::setPassword(const std::string &pass,
736 m_impl->setPassword(pass, eflag);
740 // -----------------------------------------------------------------
742 Url::setHost(const std::string &host)
744 m_impl->setHost(host);
748 // -----------------------------------------------------------------
750 Url::setPort(const std::string &port)
752 m_impl->setPort(port);
756 // -----------------------------------------------------------------
758 Url::setPathName(const std::string &path,
761 m_impl->setPathName(path, eflag);
765 Url::setPathName(const Pathname &path,
768 m_impl->setPathName(path.asString(), eflag);
772 Url::setPathName(const char *path,
775 m_impl->setPathName(path, eflag);
778 // -----------------------------------------------------------------
780 Url::setPathParams(const std::string ¶ms)
782 m_impl->setPathParams(params);
786 // -----------------------------------------------------------------
788 Url::setPathParamsVec(const zypp::url::ParamVec &pvec)
790 m_impl->setPathParamsVec(pvec);
794 // -----------------------------------------------------------------
796 Url::setPathParamsMap(const zypp::url::ParamMap &pmap)
798 m_impl->setPathParamsMap(pmap);
802 // -----------------------------------------------------------------
804 Url::setPathParam(const std::string ¶m, const std::string &value)
806 m_impl->setPathParam(param, value);
810 // -----------------------------------------------------------------
812 Url::setQueryStringVec(const zypp::url::ParamVec &pvec)
814 m_impl->setQueryStringVec(pvec);
818 // -----------------------------------------------------------------
820 Url::setQueryStringMap(const zypp::url::ParamMap &pmap)
822 m_impl->setQueryStringMap(pmap);
825 // -----------------------------------------------------------------
827 Url::setQueryParam(const std::string ¶m, const std::string &value)
829 m_impl->setQueryParam(param, value);
832 // -----------------------------------------------------------------
834 Url::delQueryParam(const std::string ¶m)
836 m_impl->delQueryParam(param);
839 // -----------------------------------------------------------------
841 Url::getViewOptions() const
843 return m_impl->getViewOptions();
846 // -----------------------------------------------------------------
848 Url::setViewOptions(const ViewOptions &vopts)
850 m_impl->setViewOptions(vopts);
853 // -----------------------------------------------------------------
854 std::ostream & operator<<( std::ostream & str, const Url & url )
856 return str << url.asString();
859 bool operator<( const Url &lhs, const Url &rhs )
861 return (lhs.asCompleteString() < rhs.asCompleteString());
864 bool operator==( const Url &lhs, const Url &rhs )
866 return (lhs.asCompleteString() == rhs.asCompleteString());
869 bool operator!=( const Url &lhs, const Url &rhs )
871 return (lhs.asCompleteString() != rhs.asCompleteString());
874 ////////////////////////////////////////////////////////////////////
876 //////////////////////////////////////////////////////////////////////
878 ** vim: set ts=2 sts=2 sw=2 ai et: