21 #include <sys/types.h> 22 #include <sys/socket.h> 23 #include <arpa/inet.h> 31 #define a_zA_Z "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 39 #define RX_VALID_SCHEME "^[" a_zA_Z "][" a_zA_Z "0-9\\.+-]*$" 41 #define RX_VALID_PORT "^[0-9]{1,5}$" 43 #define RX_VALID_HOSTNAME "^[[:alnum:]${_}]+([\\.-][[:alnum:]${_}]+)*$" 45 #define RX_VALID_HOSTIPV4 \ 46 "^([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})$" 48 #define RX_VALID_HOSTIPV6 \ 49 "^\\[[:a-fA-F0-9]+(:[0-9]{1,3}(\\.[0-9]{1,3}){3})?\\]$" 65 const ViewOption ViewOption::WITH_SCHEME = 0x0001;
66 const ViewOption ViewOption::WITH_USERNAME = 0x0002;
67 const ViewOption ViewOption::WITH_PASSWORD = 0x0004;
68 const ViewOption ViewOption::WITH_HOST = 0x0008;
69 const ViewOption ViewOption::WITH_PORT = 0x0010;
70 const ViewOption ViewOption::WITH_PATH_NAME = 0x0020;
71 const ViewOption ViewOption::WITH_PATH_PARAMS = 0x0040;
72 const ViewOption ViewOption::WITH_QUERY_STR = 0x0080;
73 const ViewOption ViewOption::WITH_FRAGMENT = 0x0100;
74 const ViewOption ViewOption::EMPTY_AUTHORITY = 0x0200;
75 const ViewOption ViewOption::EMPTY_PATH_NAME = 0x0400;
76 const ViewOption ViewOption::EMPTY_PATH_PARAMS = 0x0800;
77 const ViewOption ViewOption::EMPTY_QUERY_STR = 0x1000;
78 const ViewOption ViewOption::EMPTY_FRAGMENT = 0x2000;
79 const ViewOption ViewOption::DEFAULTS = 0x07bb;
132 {
_assign( std::move(rhs) );
return *
this; }
135 operator const std::string &()
const 138 const std::string &
str()
const 155 static constexpr std::string_view tag {
"proxypass=" };
160 if ( val.substr( 0, tag.size() ) != tag ) {
161 if ( ! safe.empty() )
213 checkUrlData(
const std::string &data,
214 const std::string &name,
215 const std::string ®x,
218 if( regx.empty() || regx ==
"^$")
221 str::form(
_(
"Url scheme does not allow a %s"), name.c_str())
241 name.c_str(), data.c_str())
247 str::form(
_(
"Invalid %s component"), name.c_str())
282 const std::string &authority,
283 const std::string &pathdata,
284 const std::string &querystr,
285 const std::string &fragment)
289 init(scheme, authority, pathdata, querystr, fragment);
296 const std::string &authority,
297 const std::string &pathdata,
298 const std::string &querystr,
299 const std::string &fragment)
301 if ( scheme.empty() && *pathdata.c_str() ==
'/' )
317 config(
"sep_pathparams",
";");
318 config(
"psep_pathparam",
",");
319 config(
"vsep_pathparam",
"=");
321 config(
"psep_querystr",
"&");
322 config(
"vsep_querystr",
"=");
324 config(
"safe_username",
"~!$&'()*+=,;");
325 config(
"safe_password",
"~!$&'()*+=,:;");
326 config(
"safe_hostname",
"[:]${_}");
327 config(
"safe_pathname",
"~!$&'()*+=,:@/");
328 config(
"safe_pathparams",
"~!$&'()*+=,:;@/");
329 config(
"safe_querystr",
"~!$&'()*+=,:;@/?");
330 config(
"safe_fragment",
"~!$&'()*+=,:;@/?");
334 config(
"with_authority",
"y");
340 config(
"require_host",
"n");
341 config(
"require_pathname",
"n");
345 config(
"path_encode_slash2",
"n");
347 config(
"rx_username",
"^([" a_zA_Z "0-9!$&'\\(\\)*+=,;~\\._-]|%[a-fA-F0-9]{2})+$");
348 config(
"rx_password",
"^([" a_zA_Z "0-9!$&'\\(\\)*+=,:;~\\._-]|%[a-fA-F0-9]{2})+$");
350 config(
"rx_pathname",
"^([" a_zA_Z "0-9!$&'\\(\\){}*+=,:@/~\\._-]|%[a-fA-F0-9]{2})+$");
351 config(
"rx_pathparams",
"^([" a_zA_Z "0-9!$&'\\(\\){}*+=,:;@/~\\._-]|%[a-fA-F0-9]{2})+$");
353 config(
"rx_querystr",
"^([" a_zA_Z "0-9!$&'\\(\\){}*+=,:;@/?~\\._-]|%[a-fA-F0-9]{2})+$");
354 config(
"rx_fragment",
"^([" a_zA_Z "0-9!$&'\\(\\){}*+=,:;@/?~\\._-]|%[a-fA-F0-9]{2})+$");
374 return std::string();
428 UrlSchemes::const_iterator s;
430 for(s=schemes.begin(); s!=schemes.end(); ++s)
460 UrlSchemes::const_iterator s;
461 for(s=schemes.begin(); s!=schemes.end(); ++s)
485 if( host.empty() &&
config(
"require_host") !=
"n")
489 if( path.empty() &&
config(
"require_pathname") !=
"n")
496 if( !host.empty() && !path.empty() && path.at(0) !=
'/')
524 if( opts.
has(ViewOptions::WITH_SCHEME))
531 if( opts.
has(ViewOptions::WITH_HOST))
534 if( !tmp.
host.empty())
538 if( opts.
has(ViewOptions::WITH_USERNAME))
541 if( !tmp.
user.empty())
545 if( opts.
has(ViewOptions::WITH_PASSWORD))
548 if( !tmp.
pass.empty())
550 url +=
":" + tmp.
pass;
559 if( opts.
has(ViewOptions::WITH_PORT))
562 if( !tmp.
port.empty())
564 url +=
":" + tmp.
port;
568 else if( opts.
has(ViewOptions::EMPTY_AUTHORITY))
573 else if( opts.
has(ViewOptions::EMPTY_AUTHORITY))
580 if( opts.
has(ViewOptions::WITH_PATH_NAME))
585 if(url.find(
'/') != std::string::npos)
597 if( opts.
has(ViewOptions::WITH_PATH_PARAMS))
604 else if( opts.
has(ViewOptions::EMPTY_PATH_PARAMS))
610 else if( opts.
has(ViewOptions::EMPTY_PATH_NAME)
611 && url.find(
'/') != std::string::npos)
614 if( opts.
has(ViewOptions::EMPTY_PATH_PARAMS))
621 if( opts.
has(ViewOptions::WITH_QUERY_STR))
624 if( !querystr.empty() )
626 url +=
"?" + querystr;
628 else if( opts.
has(ViewOptions::EMPTY_QUERY_STR))
634 if( opts.
has(ViewOptions::WITH_FRAGMENT))
641 else if( opts.
has(ViewOptions::EMPTY_FRAGMENT))
691 config(
"sep_pathparams") +
785 if(
config(
"psep_pathparam").empty())
805 if(
config(
"psep_pathparam").empty() ||
806 config(
"vsep_pathparam").empty())
809 "Path parameter parsing not supported for this URL" 829 zypp::url::ParamMap::const_iterator i( pmap.find(param));
831 return i != pmap.end() ? i->second : std::string();
840 if(
config(
"psep_querystr").empty())
860 if(
config(
"psep_querystr").empty() ||
861 config(
"vsep_querystr").empty())
864 _(
"Query string parsing not supported for this URL")
884 zypp::url::ParamMap::const_iterator i( pmap.find(param));
886 return i != pmap.end() ? i->second : std::string();
902 _(
"Url scheme is a required component")
908 str::form(
_(
"Invalid Url scheme '%s'"), scheme.c_str())
918 std::string s = authority;
921 if ((p=s.find(
'@')) != std::string::npos)
924 if (q != std::string::npos && q < p)
933 if ((p = s.rfind(
':')) != std::string::npos && ( (q = s.rfind(
']')) == std::string::npos || q < p) )
946 size_t pos = std::string::npos;
947 std::string sep(
config(
"sep_pathparams"));
950 pos = pathdata.find(sep);
952 if( pos != std::string::npos)
971 if( querystr.empty())
977 checkUrlData(querystr,
"query string",
config(
"rx_querystr"));
989 if( fragment.empty())
997 checkUrlData(fragment,
"fragment",
config(
"rx_fragment"));
1004 fragment,
config(
"safe_fragment")
1022 if(
config(
"with_authority") !=
"y")
1025 _(
"Url scheme does not allow a username")
1031 checkUrlData(user,
"username",
config(
"rx_username"));
1038 user,
config(
"safe_username")
1056 if(
config(
"with_authority") !=
"y")
1059 _(
"Url scheme does not allow a password")
1065 checkUrlData(pass,
"password",
config(
"rx_password"),
false);
1072 pass,
config(
"safe_password")
1085 if(
config(
"require_host") ==
"m")
1088 _(
"Url scheme requires a host component")
1095 if(
config(
"with_authority") !=
"y")
1098 _(
"Url scheme does not allow a host component")
1109 if( host.at(0) ==
'[')
1119 temp,
config(
"safe_hostname")
1125 str::form(
_(
"Invalid host component '%s'"), host.c_str())
1142 if(
config(
"with_authority") !=
"y" ||
1143 config(
"with_port") !=
"y")
1146 _(
"Url scheme does not allow a port")
1157 str::form(
_(
"Invalid port component '%s'"), port.c_str())
1171 if(
config(
"require_pathname") ==
"m")
1174 _(
"Url scheme requires path name")
1183 checkUrlData(path,
"path name",
config(
"rx_pathname"));
1191 if(!(path.at(0) ==
'/' || (path.size() >= 3 &&
1195 _(
"Relative path not allowed if authority exists")
1206 if(path.at(0) !=
'/')
1209 _(
"Relative path not allowed if authority exists")
1216 path,
config(
"safe_pathname")
1234 checkUrlData(params,
"path parameters",
config(
"rx_pathparams"));
1258 if(
config(
"psep_pathparam").empty() ||
1259 config(
"vsep_pathparam").empty())
1262 "Path Parameter parsing not supported for this URL" 1268 config(
"psep_pathparam"),
1269 config(
"vsep_pathparam"),
1270 config(
"safe_pathparams"),
1282 pmap[param] = value;
1304 if(
config(
"psep_querystr").empty() ||
1305 config(
"vsep_querystr").empty())
1308 _(
"Query string parsing not supported for this URL")
1342 pmap[newmap.begin()->first] = newmap.begin()->second;
1351 for (
auto it = pmap.begin(), last = pmap.end(); it != last; ) {
1353 it = pmap.erase( it );
1373 std::string
copy( path);
1376 if(
copy.size() >= 3 &&
copy.at(0) !=
'/' &&
1379 copy.replace(0, 3,
"/");
1391 if(
config(
"path_encode_slash2") ==
"y")
1394 if(
copy.size() >= 2 &&
copy.at(0) ==
'/' &&
copy.at(1) ==
'/')
1396 copy.replace(1, 1,
"%2F");
1402 if(
copy.size() >= 4 &&
copy.at(0) ==
'/' &&
1405 copy.replace(1, 4,
"/");
1412 if(
copy.size() >= 2 &&
copy.at(0) ==
'/' &&
copy.at(1) ==
'/')
1414 copy.replace(1, 1,
"%2F");
1431 std::string temp( host.substr(1, host.size()-2));
1433 return inet_pton(AF_INET6, temp.c_str(), &ip) > 0;
1459 long pnum = str::strtonum<long>(port);
1460 return ( pnum >= 1 && pnum <= USHRT_MAX);
std::string toLower(const std::string &s)
Return lowercase version of s.
virtual std::string getAuthority() const
Returns the encoded authority component of the URL.
Hide passwords embedded in a querystr,.
virtual std::string getQueryString() const
Returns the encoded query string component of the URL.
Internal data used by UrlBase.
virtual void setQueryParam(const std::string ¶m, const std::string &value)
Set or add value for the specified query parameter.
virtual zypp::url::ParamMap getQueryStringMap(EEncoding eflag) const
Returns a string map with query parameter and their values.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
virtual UrlSchemes getKnownSchemes() const
Returns scheme names known by this object.
std::string asString1050625() const
#define RX_VALID_HOSTNAME
SafeQuerystr & operator=(std::string rhs)
Flag to request encoded string(s).
std::map< std::string, std::string > ParamMap
A parameter map container.
ViewOption()
Create instance with default combination of view options.
virtual zypp::url::ParamVec getPathParamsVec() const
Returns a vector with encoded path parameter substrings.
virtual void setUsername(const std::string &user, EEncoding eflag)
Set the username in the URL authority.
virtual std::string getPathName(EEncoding eflag) const
Returns the path name from the URL.
virtual void setPathData(const std::string &pathdata)
Set the path data component in the URL.
String related utilities and Regular expression matching.
std::string _fullQuerytsr
virtual void setPort(const std::string &port)
Set the port number in the URL authority.
static const ViewOption hotfix1050625
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
std::vector< std::string > ParamVec
A parameter vector container.
Url::asString() view options.
void setViewOptions(const ViewOptions &vopts)
Change the view options of the current object.
virtual void setAuthority(const std::string &authority)
Set the authority component in the URL.
virtual void setHost(const std::string &host)
Set the hostname or IP in the URL authority.
virtual void setPathParams(const std::string ¶ms)
Set the path parameters.
virtual std::string getPassword(EEncoding eflag) const
Returns the password from the URL authority.
const std::string & safeStr() const
virtual void setPathParamsVec(const zypp::url::ParamVec &pvec)
Set the path parameters.
virtual std::string getQueryParam(const std::string ¶m, EEncoding eflag) const
Return the value for the specified query parameter.
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \, const Trim trim_r=NO_TRIM)
Split line_r into words.
virtual std::string getPathParam(const std::string ¶m, EEncoding eflag) const
Return the value for the specified path parameter.
virtual void setFragment(const std::string &fragment, EEncoding eflag)
Set the fragment string in the URL.
const std::string & str(const ViewOptions &viewopts_r) const
virtual void setPassword(const std::string &pass, EEncoding eflag)
Set the password in the URL authority.
virtual std::string getHost(EEncoding eflag) const
Returns the hostname or IP from the URL authority.
virtual std::string getPathParams() const
Returns the encoded path parameters from the URL.
virtual std::string getPort() const
Returns the port number from the URL authority.
virtual void init(const std::string &scheme, const std::string &authority, const std::string &pathdata, const std::string &querystr, const std::string &fragment)
Initializes current object with new URL components.
std::map< std::string, std::string > UrlConfig
virtual UrlBase * clone() const
Returns pointer to a copy of the current object.
std::optional< std::string > _safeQuerytsr
ViewOptions getViewOptions() const
Return the view options of the current object.
void split(ParamVec &pvec, const std::string &pstr, const std::string &psep)
Split into a parameter vector.
virtual std::string getFragment(EEncoding eflag) const
Returns the encoded fragment component of the URL.
UrlBaseData(UrlConfig conf)
virtual void setScheme(const std::string &scheme)
Set the scheme name in the URL.
std::string join(const ParamVec &pvec, const std::string &psep)
Join parameter vector to a string.
virtual void setQueryString(const std::string &querystr)
Set the query string in the URL.
std::string toUpper(const std::string &s)
Return uppercase version of s.
const std::string & fullStr() const
virtual bool isKnownScheme(const std::string &scheme) const
Returns if scheme name is known to this object.
std::vector< std::string > UrlSchemes
Vector of URL scheme names.
virtual std::string cleanupPathName(const std::string &path, bool authority) const
Utility method to cleanup an encoded path name.
std::string decode(const std::string &str, bool allowNUL)
Decodes a URL percent encoded string.
bool has(const ViewOption &o) const
Check if specified option o is set in the current object.
std::ostream & copy(std::istream &from_r, std::ostream &to_r)
Copy istream to ostream.
std::string config(const std::string &opt) const
Get the value of a UrlBase configuration variable.
virtual void clear()
Clears all data in the object.
virtual void setPathName(const std::string &path, EEncoding eflag)
Set the path name.
std::string encode(const std::string &str, const std::string &safe, EEncoding eflag)
Encodes a string using URL percent encoding.
virtual bool isValidPort(const std::string &port) const
Verifies specified port number.
const std::string & str() const
virtual void configure()
Configures behaviour of the instance.
SafeQuerystr(std::string rhs)
void _assign(std::string &&rhs)
virtual void setPathParamsMap(const zypp::url::ParamMap &pmap)
Set the path parameters.
virtual zypp::url::ParamMap getPathParamsMap(EEncoding eflag) const
Returns a string map with path parameter keys and values.
bool regex_match(const std::string &s, smatch &matches, const regex ®ex)
regex ZYPP_STR_REGEX regex ZYPP_STR_REGEX
virtual bool isValidHost(const std::string &host) const
Verifies specified host or IP.
virtual zypp::url::ParamVec getQueryStringVec() const
Returns a vector with query string parameter substrings.
#define RX_VALID_HOSTIPV6
virtual std::string getPathData() const
Returns the encoded path component of the URL.
virtual void setQueryStringMap(const zypp::url::ParamMap &qmap, EEncoding eflag)
Set the query parameters.
virtual void setPathParam(const std::string ¶m, const std::string &value)
Set or add value for the specified path parameter.
virtual bool isValidScheme(const std::string &scheme) const
Verifies specified scheme name.
virtual void setQueryStringVec(const zypp::url::ParamVec &qvec)
Set the query parameters.
Easy-to use interface to the ZYPP dependency resolver.
Thrown if a url component is invalid.
virtual bool isValid() const
Verifies the Url.
virtual std::string asString() const
Returns a default string representation of the Url object.
virtual std::string getUsername(EEncoding eflag) const
Returns the username from the URL authority.
virtual std::string getScheme() const
Returns the scheme name of the URL.
Thrown if scheme does not allow a component.
virtual void delQueryParam(const std::string ¶m)
remove the specified query parameter.
Flag to request decoded string(s).