1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
14 #include <zypp/base/Gettext.h>
15 #include <zypp/base/String.h>
16 #include <zypp/base/Regex.h>
21 //////////////////////////////////////////////////////////////////////
23 { ////////////////////////////////////////////////////////////////////
26 using namespace zypp::url;
29 // -----------------------------------------------------------------
31 * url = [scheme:] [//authority] /path [?query] [#fragment]
33 #define RX_SPLIT_URL "^([^:/?#]+:|)" \
40 ////////////////////////////////////////////////////////////////////
42 { //////////////////////////////////////////////////////////////////
45 // ---------------------------------------------------------------
46 class LDAPUrl: public UrlBase
54 LDAPUrl(const LDAPUrl &url): UrlBase(url)
60 return new LDAPUrl(*this);
64 getKnownSchemes() const
66 UrlSchemes schemes(2);
75 config("sep_pathparams", "");
77 config("psep_querystr", "?");
78 config("vsep_querystr", "");
80 // host is required (isValid=>false)
81 // but not mandatory (see RFC 2255),
82 // that is, accept empty host.
83 config("require_host", "y");
86 config("rx_username", "");
87 config("rx_password", "");
88 config("rx_fragment", "");
89 config("rx_pathparams", "");
92 virtual zypp::url::ParamMap
93 getQueryStringMap(zypp::url::EEncoding eflag) const
95 static const char * const keys[] = {
96 "attrs", "scope", "filter", "exts", NULL
98 zypp::url::ParamMap pmap;
99 zypp::url::ParamVec pvec( getQueryStringVec());
100 if( pvec.size() <= 4)
102 for(size_t i=0; i<pvec.size(); i++)
104 if(eflag == zypp::url::E_ENCODED)
105 pmap[keys[i]] = pvec[i];
107 pmap[keys[i]] = zypp::url::decode( pvec[i]);
112 ZYPP_THROW(url::UrlNotSupportedException(
113 _("Invalid LDAP URL query string")
120 setQueryStringMap(const zypp::url::ParamMap &pmap)
122 static const char * const keys[] = {
123 "attrs", "scope", "filter", "exts", NULL
126 // remove psep ("?") from safe chars
127 std::string join_safe;
128 std::string safe(config("safe_querystr"));
129 std::string psep(config("psep_querystr"));
130 for(std::string::size_type i=0; i<safe.size(); i++)
132 if( psep.find(safe[i]) == std::string::npos)
133 join_safe.append(1, safe[i]);
136 zypp::url::ParamVec pvec(4);
137 zypp::url::ParamMap::const_iterator p;
138 for(p=pmap.begin(); p!=pmap.end(); ++p)
141 for(size_t i=0; i<4; i++)
143 if(p->first == keys[i])
146 pvec[i] = zypp::url::encode(p->second, join_safe);
151 ZYPP_THROW(url::UrlNotSupportedException(
152 str::form(_("Invalid LDAP URL query parameter '%s'"),
157 setQueryStringVec(pvec);
162 // ---------------------------------------------------------------
167 typedef std::map<std::string,UrlRef> UrlBySchemeMap;
168 UrlBySchemeMap urlByScheme;
175 // =====================================
176 ref.reset( new LDAPUrl());
177 addUrlByScheme("ldap", ref);
178 addUrlByScheme("ldaps", ref);
181 // =====================================
182 ref.reset( new UrlBase());
183 ref->config("with_authority", "n"); // disallow host,...
184 ref->config("require_pathname", "m"); // path is mandatory
185 addUrlByScheme("hd", ref);
186 addUrlByScheme("cd", ref);
187 addUrlByScheme("dvd", ref);
188 addUrlByScheme("dir", ref);
189 addUrlByScheme("iso", ref);
191 // don't show empty authority
192 ref->setViewOptions( zypp::url::ViewOption::DEFAULTS -
193 zypp::url::ViewOption::EMPTY_AUTHORITY);
194 addUrlByScheme("mailto", ref);
195 addUrlByScheme("urn", ref);
197 // RFC1738, 3.10: may contain a host
198 ref->config("with_authority", "y"); // allow host,
199 ref->config("with_port", "n"); // but no port,
200 ref->config("rx_username", ""); // username or
201 ref->config("rx_password", ""); // password ...
202 addUrlByScheme("file", ref);
204 // =====================================
205 ref.reset( new UrlBase());
206 ref->config("require_host", "m"); // host is mandatory
207 addUrlByScheme("nfs", ref);
208 addUrlByScheme("nfs4", ref);
209 addUrlByScheme("smb", ref);
210 addUrlByScheme("cifs", ref);
211 addUrlByScheme("http", ref);
212 addUrlByScheme("https", ref);
213 ref->config("path_encode_slash2", "y"); // always encode 2. slash
214 addUrlByScheme("ftp", ref);
215 addUrlByScheme("sftp", ref);
219 addUrlByScheme(const std::string &scheme,
222 if( urlImpl && urlImpl->isValidScheme(scheme))
226 urlByScheme[str::toLower(scheme)] = ref;
233 getUrlByScheme(const std::string &scheme) const
235 UrlBySchemeMap::const_iterator i(urlByScheme.find(str::toLower(scheme)));
236 if( i != urlByScheme.end())
244 isRegisteredScheme(const std::string &scheme) const
246 return urlByScheme.find(str::toLower(scheme)) != urlByScheme.end();
250 getRegisteredSchemes() const
252 UrlBySchemeMap::const_iterator i(urlByScheme.begin());
255 schemes.reserve(urlByScheme.size());
256 for( ; i != urlByScheme.end(); ++i)
258 schemes.push_back(i->first);
265 // ---------------------------------------------------------------
266 UrlByScheme & g_urlSchemeRepository()
268 static UrlByScheme _v;
272 //////////////////////////////////////////////////////////////////
273 } // anonymous namespace
274 ////////////////////////////////////////////////////////////////////
277 // -----------------------------------------------------------------
283 // -----------------------------------------------------------------
285 : m_impl( new UrlBase())
290 // -----------------------------------------------------------------
291 Url::Url(const Url &url)
292 : m_impl( url.m_impl)
296 ZYPP_THROW(url::UrlException(
297 _("Unable to clone Url object")
303 // -----------------------------------------------------------------
304 Url::Url(const zypp::url::UrlRef &url)
309 ZYPP_THROW(url::UrlException(
310 _("Invalid empty Url object reference")
316 // -----------------------------------------------------------------
317 Url::Url(const std::string &encodedUrl)
318 : m_impl( parseUrl(encodedUrl))
322 ZYPP_THROW(url::UrlParsingException(
323 _("Unable to parse Url components")
329 // -----------------------------------------------------------------
331 Url::operator = (const std::string &encodedUrl)
333 UrlRef url( parseUrl(encodedUrl));
336 ZYPP_THROW(url::UrlParsingException(
337 _("Unable to parse Url components")
345 // -----------------------------------------------------------------
347 Url::operator = (const Url &url)
354 // -----------------------------------------------------------------
357 Url::registerScheme(const std::string &scheme,
360 return g_urlSchemeRepository().addUrlByScheme(scheme, urlImpl);
364 // -----------------------------------------------------------------
367 Url::parseUrl(const std::string &encodedUrl)
375 str::regex rex(RX_SPLIT_URL);
376 ret = str::regex_match(encodedUrl, out, rex);
381 if(ret && out.size() == 5)
383 std::string scheme = out[1];
384 if (scheme.size() > 1)
385 scheme = scheme.substr(0, scheme.size()-1);
386 std::string authority = out[2];
387 if (authority.size() >= 2)
388 authority = authority.substr(2);
389 std::string query = out[4];
390 if (query.size() > 1)
391 query = query.substr(1);
392 std::string fragment = out[5];
393 if (fragment.size() > 1)
394 fragment = fragment.substr(1);
396 url = g_urlSchemeRepository().getUrlByScheme(scheme);
399 url.reset( new UrlBase());
401 url->init(scheme, authority, out[3],
408 // -----------------------------------------------------------------
410 zypp::url::UrlSchemes
411 Url::getRegisteredSchemes()
413 return g_urlSchemeRepository().getRegisteredSchemes();
417 // -----------------------------------------------------------------
420 Url::isRegisteredScheme(const std::string &scheme)
422 return g_urlSchemeRepository().isRegisteredScheme(scheme);
426 // -----------------------------------------------------------------
427 zypp::url::UrlSchemes
428 Url::getKnownSchemes() const
430 return m_impl->getKnownSchemes();
434 // -----------------------------------------------------------------
436 Url::isValidScheme(const std::string &scheme) const
438 return m_impl->isValidScheme(scheme);
442 ///////////////////////////////////////////////////////////////////
445 inline bool isInList( const char ** begin_r, const char ** end_r, const std::string & scheme_r )
447 for ( ; begin_r != end_r; ++begin_r )
448 if ( scheme_r == *begin_r )
453 bool Url::schemeIsLocal( const std::string & scheme_r )
455 static const char * val[] = { "cd", "dvd", "dir", "hd", "iso", "file" };
456 return isInList( arrayBegin(val), arrayEnd(val), scheme_r );
459 bool Url::schemeIsRemote( const std::string & scheme_r )
461 static const char * val[] = { "http", "https", "nfs", "nfs4", "smb", "cifs", "ftp", "sftp" };
462 return isInList( arrayBegin(val), arrayEnd(val), scheme_r );
465 bool Url::schemeIsVolatile( const std::string & scheme_r )
467 static const char * val[] = { "cd", "dvd" };
468 return isInList( arrayBegin(val), arrayEnd(val), scheme_r );
471 bool Url::schemeIsDownloading( const std::string & scheme_r )
473 static const char * val[] = { "http", "https", "ftp", "sftp" };
474 return isInList( arrayBegin(val), arrayEnd(val), scheme_r );
476 ///////////////////////////////////////////////////////////////////
478 // -----------------------------------------------------------------
482 return m_impl->isValid();
486 // -----------------------------------------------------------------
488 Url::asString() const
490 return m_impl->asString();
494 // -----------------------------------------------------------------
496 Url::asCompleteString() const
498 // make sure, all url components are included;
499 // regardless of the current configuration...
500 ViewOptions opts(getViewOptions() +
501 ViewOption::WITH_SCHEME +
502 ViewOption::WITH_USERNAME +
503 ViewOption::WITH_PASSWORD +
504 ViewOption::WITH_HOST +
505 ViewOption::WITH_PORT +
506 ViewOption::WITH_PATH_NAME +
507 ViewOption::WITH_PATH_PARAMS +
508 ViewOption::WITH_QUERY_STR +
509 ViewOption::WITH_FRAGMENT);
510 return m_impl->asString(opts);
514 // -----------------------------------------------------------------
516 Url::asString(const ViewOptions &opts) const
518 return m_impl->asString(opts);
522 // -----------------------------------------------------------------
524 Url::getScheme() const
526 return m_impl->getScheme();
530 // -----------------------------------------------------------------
532 Url::getAuthority() const
534 return m_impl->getAuthority();
537 // -----------------------------------------------------------------
539 Url::getPathData() const
541 return m_impl->getPathData();
545 // -----------------------------------------------------------------
547 Url::getQueryString() const
549 return m_impl->getQueryString();
553 // -----------------------------------------------------------------
555 Url::getFragment(zypp::url::EEncoding eflag) const
557 return m_impl->getFragment(eflag);
561 // -----------------------------------------------------------------
563 Url::getUsername(EEncoding eflag) const
565 return m_impl->getUsername(eflag);
569 // -----------------------------------------------------------------
571 Url::getPassword(EEncoding eflag) const
573 return m_impl->getPassword(eflag);
577 // -----------------------------------------------------------------
579 Url::getHost(EEncoding eflag) const
581 return m_impl->getHost(eflag);
585 // -----------------------------------------------------------------
589 return m_impl->getPort();
593 // -----------------------------------------------------------------
595 Url::getPathName(EEncoding eflag) const
597 return m_impl->getPathName(eflag);
601 // -----------------------------------------------------------------
603 Url::getPathParams() const
605 return m_impl->getPathParams();
609 // -----------------------------------------------------------------
611 Url::getPathParamsVec() const
613 return m_impl->getPathParamsVec();
617 // -----------------------------------------------------------------
619 Url::getPathParamsMap(EEncoding eflag) const
621 return m_impl->getPathParamsMap(eflag);
625 // -----------------------------------------------------------------
627 Url::getPathParam(const std::string ¶m, EEncoding eflag) const
629 return m_impl->getPathParam(param, eflag);
633 // -----------------------------------------------------------------
635 Url::getQueryStringVec() const
637 return m_impl->getQueryStringVec();
641 // -----------------------------------------------------------------
643 Url::getQueryStringMap(EEncoding eflag) const
645 return m_impl->getQueryStringMap(eflag);
649 // -----------------------------------------------------------------
651 Url::getQueryParam(const std::string ¶m, EEncoding eflag) const
653 return m_impl->getQueryParam(param, eflag);
657 // -----------------------------------------------------------------
659 Url::setScheme(const std::string &scheme)
661 if(scheme == m_impl->getScheme())
665 if( m_impl->isKnownScheme(scheme))
667 m_impl->setScheme(scheme);
671 UrlRef url = g_urlSchemeRepository().getUrlByScheme(scheme);
674 url.reset( new UrlBase());
678 m_impl->getAuthority(),
679 m_impl->getPathData(),
680 m_impl->getQueryString(),
681 m_impl->getFragment(zypp::url::E_ENCODED)
687 // -----------------------------------------------------------------
689 Url::setAuthority(const std::string &authority)
691 m_impl->setAuthority(authority);
695 // -----------------------------------------------------------------
697 Url::setPathData(const std::string &pathdata)
699 m_impl->setPathData(pathdata);
703 // -----------------------------------------------------------------
705 Url::setQueryString(const std::string &querystr)
707 m_impl->setQueryString(querystr);
711 // -----------------------------------------------------------------
713 Url::setFragment(const std::string &fragment, EEncoding eflag)
715 m_impl->setFragment(fragment, eflag);
719 // -----------------------------------------------------------------
721 Url::setUsername(const std::string &user,
724 m_impl->setUsername(user, eflag);
728 // -----------------------------------------------------------------
730 Url::setPassword(const std::string &pass,
733 m_impl->setPassword(pass, eflag);
737 // -----------------------------------------------------------------
739 Url::setHost(const std::string &host)
741 m_impl->setHost(host);
745 // -----------------------------------------------------------------
747 Url::setPort(const std::string &port)
749 m_impl->setPort(port);
753 // -----------------------------------------------------------------
755 Url::setPathName(const std::string &path,
758 m_impl->setPathName(path, eflag);
762 // -----------------------------------------------------------------
764 Url::setPathParams(const std::string ¶ms)
766 m_impl->setPathParams(params);
770 // -----------------------------------------------------------------
772 Url::setPathParamsVec(const zypp::url::ParamVec &pvec)
774 m_impl->setPathParamsVec(pvec);
778 // -----------------------------------------------------------------
780 Url::setPathParamsMap(const zypp::url::ParamMap &pmap)
782 m_impl->setPathParamsMap(pmap);
786 // -----------------------------------------------------------------
788 Url::setPathParam(const std::string ¶m, const std::string &value)
790 m_impl->setPathParam(param, value);
794 // -----------------------------------------------------------------
796 Url::setQueryStringVec(const zypp::url::ParamVec &pvec)
798 m_impl->setQueryStringVec(pvec);
802 // -----------------------------------------------------------------
804 Url::setQueryStringMap(const zypp::url::ParamMap &pmap)
806 m_impl->setQueryStringMap(pmap);
809 // -----------------------------------------------------------------
811 Url::setQueryParam(const std::string ¶m, const std::string &value)
813 m_impl->setQueryParam(param, value);
816 // -----------------------------------------------------------------
818 Url::getViewOptions() const
820 return m_impl->getViewOptions();
823 // -----------------------------------------------------------------
825 Url::setViewOptions(const ViewOptions &vopts)
827 m_impl->setViewOptions(vopts);
830 // -----------------------------------------------------------------
831 std::ostream & operator<<( std::ostream & str, const Url & url )
833 return str << url.asString();
836 bool operator<( const Url &lhs, const Url &rhs )
838 return (lhs.asCompleteString() < rhs.asCompleteString());
841 bool operator==( const Url &lhs, const Url &rhs )
843 return (lhs.asCompleteString() == rhs.asCompleteString());
846 bool operator!=( const Url &lhs, const Url &rhs )
848 return (lhs.asCompleteString() != rhs.asCompleteString());
851 ////////////////////////////////////////////////////////////////////
853 //////////////////////////////////////////////////////////////////////
855 ** vim: set ts=2 sts=2 sw=2 ai et: