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 // don't show empty authority
185 ref->setViewOptions( zypp::url::ViewOption::DEFAULTS -
186 zypp::url::ViewOption::EMPTY_AUTHORITY);
188 ref->config("with_authority", "n"); // disallow host,...
189 ref->config("require_pathname", "m"); // path is mandatory
190 addUrlByScheme("hd", ref);
191 addUrlByScheme("cd", ref);
192 addUrlByScheme("dvd", ref);
193 addUrlByScheme("dir", ref);
194 addUrlByScheme("iso", ref);
196 addUrlByScheme("mailto", ref);
197 addUrlByScheme("urn", ref);
198 addUrlByScheme("plugin", ref); // zypp plugable media handler:
200 // RFC1738, 3.10: may contain a host
201 ref->config("with_authority", "y"); // allow host,
202 ref->config("with_port", "n"); // but no port,
203 ref->config("rx_username", ""); // username or
204 ref->config("rx_password", ""); // password ...
205 addUrlByScheme("file", ref);
207 // =====================================
208 ref.reset( new UrlBase());
209 ref->config("require_host", "m"); // host is mandatory
210 addUrlByScheme("nfs", ref);
211 addUrlByScheme("nfs4", ref);
212 addUrlByScheme("smb", ref);
213 addUrlByScheme("cifs", ref);
214 addUrlByScheme("http", ref);
215 addUrlByScheme("https", ref);
216 ref->config("path_encode_slash2", "y"); // always encode 2. slash
217 addUrlByScheme("ftp", ref);
218 addUrlByScheme("sftp", ref);
219 addUrlByScheme("tftp", ref);
223 addUrlByScheme(const std::string &scheme,
226 if( urlImpl && urlImpl->isValidScheme(scheme))
230 urlByScheme[str::toLower(scheme)] = ref;
237 getUrlByScheme(const std::string &scheme) const
239 UrlBySchemeMap::const_iterator i(urlByScheme.find(str::toLower(scheme)));
240 if( i != urlByScheme.end())
248 isRegisteredScheme(const std::string &scheme) const
250 return urlByScheme.find(str::toLower(scheme)) != urlByScheme.end();
254 getRegisteredSchemes() const
256 UrlBySchemeMap::const_iterator i(urlByScheme.begin());
259 schemes.reserve(urlByScheme.size());
260 for( ; i != urlByScheme.end(); ++i)
262 schemes.push_back(i->first);
269 // ---------------------------------------------------------------
270 UrlByScheme & g_urlSchemeRepository()
272 static UrlByScheme _v;
276 //////////////////////////////////////////////////////////////////
277 } // anonymous namespace
278 ////////////////////////////////////////////////////////////////////
281 // -----------------------------------------------------------------
287 // -----------------------------------------------------------------
289 : m_impl( new UrlBase())
294 // -----------------------------------------------------------------
295 Url::Url(const Url &url)
296 : m_impl( url.m_impl)
300 ZYPP_THROW(url::UrlException(
301 _("Unable to clone Url object")
307 // -----------------------------------------------------------------
308 Url::Url(const zypp::url::UrlRef &url)
313 ZYPP_THROW(url::UrlException(
314 _("Invalid empty Url object reference")
320 // -----------------------------------------------------------------
321 Url::Url(const std::string &encodedUrl)
322 : m_impl( parseUrl(encodedUrl))
326 ZYPP_THROW(url::UrlParsingException(
327 _("Unable to parse Url components")
333 // -----------------------------------------------------------------
335 Url::operator = (const std::string &encodedUrl)
337 UrlRef url( parseUrl(encodedUrl));
340 ZYPP_THROW(url::UrlParsingException(
341 _("Unable to parse Url components")
349 // -----------------------------------------------------------------
351 Url::operator = (const Url &url)
358 // -----------------------------------------------------------------
361 Url::registerScheme(const std::string &scheme,
364 return g_urlSchemeRepository().addUrlByScheme(scheme, urlImpl);
368 // -----------------------------------------------------------------
371 Url::parseUrl(const std::string &encodedUrl)
379 str::regex rex(RX_SPLIT_URL);
380 ret = str::regex_match(encodedUrl, out, rex);
385 if(ret && out.size() == 6)
387 std::string scheme = out[1];
388 if (scheme.size() > 1)
389 scheme = scheme.substr(0, scheme.size()-1);
390 std::string authority = out[2];
391 if (authority.size() >= 2)
392 authority = authority.substr(2);
393 std::string query = out[4];
394 if (query.size() > 1)
395 query = query.substr(1);
396 std::string fragment = out[5];
397 if (fragment.size() > 1)
398 fragment = fragment.substr(1);
400 url = g_urlSchemeRepository().getUrlByScheme(scheme);
403 url.reset( new UrlBase());
405 url->init(scheme, authority, out[3],
412 // -----------------------------------------------------------------
414 zypp::url::UrlSchemes
415 Url::getRegisteredSchemes()
417 return g_urlSchemeRepository().getRegisteredSchemes();
421 // -----------------------------------------------------------------
424 Url::isRegisteredScheme(const std::string &scheme)
426 return g_urlSchemeRepository().isRegisteredScheme(scheme);
430 // -----------------------------------------------------------------
431 zypp::url::UrlSchemes
432 Url::getKnownSchemes() const
434 return m_impl->getKnownSchemes();
438 // -----------------------------------------------------------------
440 Url::isValidScheme(const std::string &scheme) const
442 return m_impl->isValidScheme(scheme);
446 ///////////////////////////////////////////////////////////////////
449 inline bool isInList( const char ** begin_r, const char ** end_r, const std::string & scheme_r )
451 for ( ; begin_r != end_r; ++begin_r )
452 if ( scheme_r == *begin_r )
457 bool Url::schemeIsLocal( const std::string & scheme_r )
459 static const char * val[] = { "cd", "dvd", "dir", "hd", "iso", "file" };
460 return isInList( arrayBegin(val), arrayEnd(val), scheme_r );
463 bool Url::schemeIsRemote( const std::string & scheme_r )
465 static const char * val[] = { "http", "https", "nfs", "nfs4", "smb", "cifs", "ftp", "sftp", "tftp" };
466 return isInList( arrayBegin(val), arrayEnd(val), scheme_r );
469 bool Url::schemeIsVolatile( const std::string & scheme_r )
471 static const char * val[] = { "cd", "dvd" };
472 return isInList( arrayBegin(val), arrayEnd(val), scheme_r );
475 bool Url::schemeIsDownloading( const std::string & scheme_r )
477 static const char * val[] = { "http", "https", "ftp", "sftp", "tftp" };
478 return isInList( arrayBegin(val), arrayEnd(val), scheme_r );
480 ///////////////////////////////////////////////////////////////////
482 // -----------------------------------------------------------------
486 return m_impl->isValid();
490 // -----------------------------------------------------------------
492 Url::asString() const
494 return m_impl->asString();
498 // -----------------------------------------------------------------
500 Url::asCompleteString() const
502 // make sure, all url components are included;
503 // regardless of the current configuration...
504 ViewOptions opts(getViewOptions() +
505 ViewOption::WITH_SCHEME +
506 ViewOption::WITH_USERNAME +
507 ViewOption::WITH_PASSWORD +
508 ViewOption::WITH_HOST +
509 ViewOption::WITH_PORT +
510 ViewOption::WITH_PATH_NAME +
511 ViewOption::WITH_PATH_PARAMS +
512 ViewOption::WITH_QUERY_STR +
513 ViewOption::WITH_FRAGMENT);
514 return m_impl->asString(opts);
518 // -----------------------------------------------------------------
520 Url::asString(const ViewOptions &opts) const
522 return m_impl->asString(opts);
526 // -----------------------------------------------------------------
528 Url::getScheme() const
530 return m_impl->getScheme();
534 // -----------------------------------------------------------------
536 Url::getAuthority() const
538 return m_impl->getAuthority();
541 // -----------------------------------------------------------------
543 Url::getPathData() const
545 return m_impl->getPathData();
549 // -----------------------------------------------------------------
551 Url::getQueryString() const
553 return m_impl->getQueryString();
557 // -----------------------------------------------------------------
559 Url::getFragment(zypp::url::EEncoding eflag) const
561 return m_impl->getFragment(eflag);
565 // -----------------------------------------------------------------
567 Url::getUsername(EEncoding eflag) const
569 return m_impl->getUsername(eflag);
573 // -----------------------------------------------------------------
575 Url::getPassword(EEncoding eflag) const
577 return m_impl->getPassword(eflag);
581 // -----------------------------------------------------------------
583 Url::getHost(EEncoding eflag) const
585 return m_impl->getHost(eflag);
589 // -----------------------------------------------------------------
593 return m_impl->getPort();
597 // -----------------------------------------------------------------
599 Url::getPathName(EEncoding eflag) const
601 return m_impl->getPathName(eflag);
605 // -----------------------------------------------------------------
607 Url::getPathParams() const
609 return m_impl->getPathParams();
613 // -----------------------------------------------------------------
615 Url::getPathParamsVec() const
617 return m_impl->getPathParamsVec();
621 // -----------------------------------------------------------------
623 Url::getPathParamsMap(EEncoding eflag) const
625 return m_impl->getPathParamsMap(eflag);
629 // -----------------------------------------------------------------
631 Url::getPathParam(const std::string ¶m, EEncoding eflag) const
633 return m_impl->getPathParam(param, eflag);
637 // -----------------------------------------------------------------
639 Url::getQueryStringVec() const
641 return m_impl->getQueryStringVec();
645 // -----------------------------------------------------------------
647 Url::getQueryStringMap(EEncoding eflag) const
649 return m_impl->getQueryStringMap(eflag);
653 // -----------------------------------------------------------------
655 Url::getQueryParam(const std::string ¶m, EEncoding eflag) const
657 return m_impl->getQueryParam(param, eflag);
661 // -----------------------------------------------------------------
663 Url::setScheme(const std::string &scheme)
665 if(scheme == m_impl->getScheme())
669 if( m_impl->isKnownScheme(scheme))
671 m_impl->setScheme(scheme);
675 UrlRef url = g_urlSchemeRepository().getUrlByScheme(scheme);
678 url.reset( new UrlBase());
682 m_impl->getAuthority(),
683 m_impl->getPathData(),
684 m_impl->getQueryString(),
685 m_impl->getFragment(zypp::url::E_ENCODED)
691 // -----------------------------------------------------------------
693 Url::setAuthority(const std::string &authority)
695 m_impl->setAuthority(authority);
699 // -----------------------------------------------------------------
701 Url::setPathData(const std::string &pathdata)
703 m_impl->setPathData(pathdata);
707 // -----------------------------------------------------------------
709 Url::setQueryString(const std::string &querystr)
711 m_impl->setQueryString(querystr);
715 // -----------------------------------------------------------------
717 Url::setFragment(const std::string &fragment, EEncoding eflag)
719 m_impl->setFragment(fragment, eflag);
723 // -----------------------------------------------------------------
725 Url::setUsername(const std::string &user,
728 m_impl->setUsername(user, eflag);
732 // -----------------------------------------------------------------
734 Url::setPassword(const std::string &pass,
737 m_impl->setPassword(pass, eflag);
741 // -----------------------------------------------------------------
743 Url::setHost(const std::string &host)
745 m_impl->setHost(host);
749 // -----------------------------------------------------------------
751 Url::setPort(const std::string &port)
753 m_impl->setPort(port);
757 // -----------------------------------------------------------------
759 Url::setPathName(const std::string &path,
762 m_impl->setPathName(path, eflag);
766 Url::setPathName(const Pathname &path,
769 m_impl->setPathName(path.asString(), eflag);
773 Url::setPathName(const char *path,
776 m_impl->setPathName(path, eflag);
779 // -----------------------------------------------------------------
781 void Url::appendPathName( const Pathname & path_r, EEncoding eflag_r )
782 { if ( ! path_r.emptyOrRoot() ) setPathName( Pathname(getPathName( eflag_r )) / path_r, eflag_r ); }
784 // -----------------------------------------------------------------
786 Url::setPathParams(const std::string ¶ms)
788 m_impl->setPathParams(params);
792 // -----------------------------------------------------------------
794 Url::setPathParamsVec(const zypp::url::ParamVec &pvec)
796 m_impl->setPathParamsVec(pvec);
800 // -----------------------------------------------------------------
802 Url::setPathParamsMap(const zypp::url::ParamMap &pmap)
804 m_impl->setPathParamsMap(pmap);
808 // -----------------------------------------------------------------
810 Url::setPathParam(const std::string ¶m, const std::string &value)
812 m_impl->setPathParam(param, value);
816 // -----------------------------------------------------------------
818 Url::setQueryStringVec(const zypp::url::ParamVec &pvec)
820 m_impl->setQueryStringVec(pvec);
824 // -----------------------------------------------------------------
826 Url::setQueryStringMap(const zypp::url::ParamMap &pmap)
828 m_impl->setQueryStringMap(pmap);
831 // -----------------------------------------------------------------
833 Url::setQueryParam(const std::string ¶m, const std::string &value)
835 m_impl->setQueryParam(param, value);
838 // -----------------------------------------------------------------
840 Url::delQueryParam(const std::string ¶m)
842 m_impl->delQueryParam(param);
845 // -----------------------------------------------------------------
847 Url::getViewOptions() const
849 return m_impl->getViewOptions();
852 // -----------------------------------------------------------------
854 Url::setViewOptions(const ViewOptions &vopts)
856 m_impl->setViewOptions(vopts);
859 // -----------------------------------------------------------------
860 std::ostream & operator<<( std::ostream & str, const Url & url )
862 return str << url.asString();
865 bool operator<( const Url &lhs, const Url &rhs )
867 return (lhs.asCompleteString() < rhs.asCompleteString());
870 bool operator==( const Url &lhs, const Url &rhs )
872 return (lhs.asCompleteString() == rhs.asCompleteString());
875 bool operator!=( const Url &lhs, const Url &rhs )
877 return (lhs.asCompleteString() != rhs.asCompleteString());
880 ////////////////////////////////////////////////////////////////////
882 //////////////////////////////////////////////////////////////////////
884 ** vim: set ts=2 sts=2 sw=2 ai et: