#include <zypp/base/String.h>
#include <stdexcept>
-// FIXME:
-#if defined(WITH_URL_PARSE_DEBUG)
-#include <iostream>
-#endif
+#include <climits>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+
+// ---------------------------------------------------------------
+/*
+** authority = //[user [:password] @ ] host [:port]
+**
+** host = hostname | IPv4 | "[" IPv6-IP "]" | "[v...]"
+*/
+#define RX_SPLIT_AUTHORITY \
+ "^(([^:@]*)([:]([^@]*))?@)?(\\[[^]]+\\]|[^:]+)?([:](.*))?"
+
+#define RX_VALID_SCHEME "^[a-zA-Z][a-zA-Z0-9\\.+-]*$"
+
+#define RX_VALID_PORT "^[0-9]{1,5}$"
+
+#define RX_VALID_HOSTNAME "^[[:alnum:]]+([\\.-][[:alnum:]]+)*$"
+
+#define RX_VALID_HOSTIPV4 \
+ "^([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})$"
+
+#define RX_VALID_HOSTIPV6 \
+ "^\\[[:a-fA-F0-9]+(:[0-9]{1,3}(\\.[0-9]{1,3}){3})?\\]$"
+
//////////////////////////////////////////////////////////////////////
namespace zypp
// ---------------------------------------------------------------
+ /*
+ ** URL toString() view option constants:
+ */
const ViewOptions ViewOptions::WITH_SCHEME = 0x0001;
const ViewOptions ViewOptions::WITH_USERNAME = 0x0002;
const ViewOptions ViewOptions::WITH_PASSWORD = 0x0004;
// ---------------------------------------------------------------
+ /*
+ ** Behaviour configuration variables.
+ */
+ typedef std::map< std::string, std::string > UrlConfig;
+
+
+ // ---------------------------------------------------------------
/**
- * authority = //[user [:password] @ ] host [:port]
- *
- * host = hostname | IPv4 | "[" IPv6-IP "]" | "[v...]"
+ * \brief Internal data used by UrlBase.
*/
- #define RX_SPLIT_AUTHORITY \
- "^(([^:@]*)" "([:]([^@]*))?" "@)?" "(\\[[^]]+\\]|[^:]+)?" "([:](.*))?"
+ class UrlBaseData
+ {
+ public:
+ UrlBaseData()
+ {}
+
+ UrlBaseData(const UrlConfig &conf)
+ : config(conf)
+ {}
+
+ UrlConfig config;
+ ViewOptions vopts;
+
+ std::string scheme;
+ std::string user;
+ std::string pass;
+ std::string host;
+ std::string port;
+ std::string pathname;
+ std::string pathparams;
+ std::string querystr;
+ std::string fragment;
+ };
// ---------------------------------------------------------------
+ /*
+ ** Anonymous/internal utility namespace:
+ */
namespace // anonymous
{
// -------------------------------------------------------------
inline void
checkUrlData(const std::string &data,
- const std::string &name,
- const std::string ®x)
+ const std::string &name,
+ const std::string ®x)
{
if( regx.empty() || regx == "^$")
{
// ---------------------------------------------------------------
UrlBase::UrlBase()
- : m_data( new UrlData())
+ : m_data( new UrlBaseData())
{
configure();
}
// ---------------------------------------------------------------
UrlBase::UrlBase(const UrlBase &url)
- : m_data( new UrlData( *(url.m_data)))
+ : m_data( new UrlBaseData( *(url.m_data)))
{
}
const std::string &pathdata,
const std::string &querystr,
const std::string &fragment)
- : m_data( new UrlData())
+ : m_data( new UrlBaseData())
{
configure();
init(scheme, authority, pathdata, querystr, fragment);
setAuthority(authority);
setPathData(pathdata);
setQueryString(querystr);
- setFragment(fragment);
+ setFragment(fragment, zypp::url::E_ENCODED);
}
config("psep_querystr", "&");
config("vsep_querystr", "=");
- config("safe_username", "");
- config("safe_password", "");
+ config("safe_username", "~!$&'()*+=,;");
+ config("safe_password", "~!$&'()*+=,:;");
config("safe_hostname", "[:]");
- config("safe_pathname", "/");
- config("safe_pathparams", "");
- config("safe_querystr", "");
- config("safe_fragment", "");
+ config("safe_pathname", "~!$&'()*+=,:@/");
+ config("safe_pathparams", "~!$&'()*+=,:;@/");
+ config("safe_querystr", "~!$&'()*+=,:;@/?");
+ config("safe_fragment", "~!$&'()*+=,:;@/?");
+
+ config("with_authority", "y");
- config("rx_scheme", "^[a-zA-Z][a-zA-Z0-9\\._-]*$");
- config("rx_username", ".*");
- config("rx_password", ".*");
- config("rx_hostname", ".*"); // FIXME
- config("rx_port", "^[0-9]{1,5}$");
- config("rx_pathname", ".*");
- config("rx_pathparams", ".*");
- config("rx_querystr", ".*");
- config("rx_fragment", ".*");
+ config("rx_username", "^([a-zA-Z0-9!$&'\\(\\)*+=,;~\\._-]|%[a-fA-F0-9]{2})+$");
+ config("rx_password", "^([a-zA-Z0-9!$&'\\(\\)*+=,:;~\\._-]|%[a-fA-F0-9]{2})+$");
+
+ config("rx_pathname", "^([a-zA-Z0-9!$&'\\(\\)*+=,:@/~\\._-]|%[a-fA-F0-9]{2})+$");
+ config("rx_pathparams", "^([a-zA-Z0-9!$&'\\(\\)*+=,:;@/~\\._-]|%[a-fA-F0-9]{2})+$");
+
+ config("rx_querystr", "^([a-zA-Z0-9!$&'\\(\\)*+=,:;@/?~\\._-]|%[a-fA-F0-9]{2})+$");
+ config("rx_fragment", "^([a-zA-Z0-9!$&'\\(\\)*+=,:;@/?~\\._-]|%[a-fA-F0-9]{2})+$");
}
{
zypp::url::UrlConfig config(m_data->config);
zypp::url::ViewOptions vopts(m_data->vopts);
- *m_data = UrlData();
+ *m_data = UrlBaseData();
m_data->config = config;
m_data->vopts = vopts;
}
// ---------------------------------------------------------------
- std::string
- UrlBase::cleanupPathName(const std::string &path)
- {
- size_t pos = 0;
-
- while( pos < path.length() && path.at(pos) == '/')
- pos++;
-
- if( pos > 1)
- {
- // make sure, there is not more than
- // _one_ leading "/" in the path name.
- return path.substr(pos - 1);
- }
-
- return std::string(path);
- }
-
-
- // ---------------------------------------------------------------
zypp::url::UrlSchemes
UrlBase::getKnownSchemes() const
{
UrlBase::isValidScheme(const std::string &scheme) const
{
if(scheme.empty() ||
- str::regex_match(scheme, str::regex(config("rx_scheme"))))
+ str::regex_match(scheme, str::regex(RX_VALID_SCHEME)))
{
std::string lscheme( str::toLower(scheme));
UrlSchemes schemes( getKnownSchemes());
std::string
UrlBase::toString(const zypp::url::ViewOptions &opts) const
{
- std::string url;
- UrlData tmp;
+ std::string url;
+ UrlBaseData tmp;
if( opts.has(ViewOptions::WITH_SCHEME))
{
str::smatch out;
bool ret = str::regex_match(authority, out, rex);
- // FIXME:
- #if defined(WITH_URL_PARSE_DEBUG)
- std::cerr << "Regex parsed URL authority("
- << out.size() << "):" << std::endl;
- std::cerr << "==> " << authority << std::endl;
- for(size_t n=0; n < out.size(); n++)
- {
- std::cerr << "[" << n << "] " << out[n].str() << std::endl;
- }
- #endif
-
if( ret && out.size() == 8)
{
- setUsername(out[2].str());
- setPassword(out[4].str());
+ setUsername(out[2].str(), zypp::url::E_ENCODED);
+ setPassword(out[4].str(), zypp::url::E_ENCODED);
setHost(out[5].str());
setPort(out[7].str());
}
}
}
-
// ---------------------------------------------------------------
void
UrlBase::setPathData(const std::string &pathdata)
{
- size_t pos;
- pos = pathdata.find(config("sep_pathparams"));
+ size_t pos = std::string::npos;
+ std::string sep(config("sep_pathparams"));
+
+ if( !sep.empty())
+ pos = pathdata.find(sep);
+
if( pos != std::string::npos)
{
- setPathName(pathdata.substr(0, pos));
+ setPathName(pathdata.substr(0, pos),
+ zypp::url::E_ENCODED);
setPathParams(pathdata.substr(pos + 1));
}
else
{
- setPathName(pathdata);
+ setPathName(pathdata,
+ zypp::url::E_ENCODED);
setPathParams("");
}
}
{
checkUrlData(querystr, "query string", config("rx_querystr"));
- // FIXME: split & recode?
m_data->querystr = querystr;
}
}
// ---------------------------------------------------------------
void
- UrlBase::setFragment(const std::string &fragment)
+ UrlBase::setFragment(const std::string &fragment,
+ EEncoding eflag)
{
if( fragment.empty())
{
}
else
{
- std::string data( zypp::url::decode(fragment));
-
- checkUrlData(data, "fragment", config("rx_fragment"));
+ if(eflag == zypp::url::E_ENCODED)
+ {
+ checkUrlData(fragment, "fragment", config("rx_fragment"));
- m_data->fragment = zypp::url::encode(
- data, config("safe_fragment")
- );
+ m_data->fragment = fragment;
+ }
+ else
+ {
+ m_data->fragment = zypp::url::encode(
+ fragment, config("safe_password")
+ );
+ }
}
}
// ---------------------------------------------------------------
void
- UrlBase::setUsername(const std::string &user)
+ UrlBase::setUsername(const std::string &user,
+ EEncoding eflag)
{
if( user.empty())
{
}
else
{
- std::string data( zypp::url::decode(user));
+ if( config("with_authority") != "y")
+ {
+ throw std::invalid_argument(
+ std::string("Url scheme does not allow a username")
+ );
+ }
- checkUrlData(data, "username", config("rx_username"));
+ if(eflag == zypp::url::E_ENCODED)
+ {
+ checkUrlData(user, "username", config("rx_username"));
- m_data->user = zypp::url::encode(
- data, config("safe_username")
- );
+ m_data->user = user;
+ }
+ else
+ {
+ m_data->user = zypp::url::encode(
+ user, config("safe_username")
+ );
+ }
}
}
// ---------------------------------------------------------------
void
- UrlBase::setPassword(const std::string &pass)
+ UrlBase::setPassword(const std::string &pass,
+ EEncoding eflag)
{
if( pass.empty())
{
}
else
{
- std::string data( zypp::url::decode(pass));
+ if( config("with_authority") != "y")
+ {
+ throw std::invalid_argument(
+ std::string("Url scheme does not allow a password")
+ );
+ }
- checkUrlData(data, "password", config("rx_password"));
+ if(eflag == zypp::url::E_ENCODED)
+ {
+ checkUrlData(pass, "password", config("rx_password"));
- m_data->pass = zypp::url::encode(
- data, config("safe_password")
- );
+ m_data->pass = pass;
+ }
+ else
+ {
+ m_data->pass = zypp::url::encode(
+ pass, config("safe_password")
+ );
+ }
}
}
}
else
{
- std::string data( zypp::url::decode(host));
+ if( config("with_authority") != "y")
+ {
+ throw std::invalid_argument(
+ std::string("Url scheme does not allow a host")
+ );
+ }
- checkUrlData(data, "hostname", config("rx_hostname"));
+ if( isValidHost(host))
+ {
+ std::string temp;
+ if( host.at(0) == '[')
+ {
+ temp = str::toUpper(zypp::url::decode(host));
+ }
+ else
+ {
+ temp = str::toLower(zypp::url::decode(host));
+ }
- m_data->host = zypp::url::encode(
- data, config("safe_hostname")
- );
+ m_data->host = zypp::url::encode(
+ temp, config("safe_hostname")
+ );
+ }
+ else
+ {
+ throw std::invalid_argument(
+ std::string("Invalid host argument '" + host + "'")
+ );
+ }
}
}
}
else
{
- std::string data( zypp::url::decode(port));
-
- checkUrlData(data, "port", config("rx_port"));
+ if( config("with_authority") != "y")
+ {
+ throw std::invalid_argument(
+ std::string("Url scheme does not allow a port")
+ );
+ }
- m_data->port = data;
+ if( isValidPort(port))
+ {
+ m_data->port = port;
+ }
+ else
+ {
+ throw std::invalid_argument(
+ std::string("Invalid host argument '" + port + "'")
+ );
+ }
}
}
// ---------------------------------------------------------------
void
- UrlBase::setPathName(const std::string &path)
+ UrlBase::setPathName(const std::string &path,
+ EEncoding eflag)
{
if( path.empty())
{
}
else
{
- std::string data( cleanupPathName(zypp::url::decode(path)));
-
- checkUrlData(data, "path", config("rx_pathname"));
+ std::string data;
+ if(eflag == zypp::url::E_ENCODED)
+ {
+ data = cleanupPathName(zypp::url::decode(path));
+ }
+ else
+ {
+ data = cleanupPathName(path);
+ }
m_data->pathname = zypp::url::encode(
data, config("safe_pathname")
{
checkUrlData(params, "path parameters", config("rx_pathparams"));
- // FIXME: split & recode?
m_data->pathparams = params;
}
}
void
UrlBase::setPathParam(const std::string ¶m, const std::string &value)
{
- std::string raw_param( zypp::url::decode(param));
- std::string raw_value( zypp::url::decode(value));
-
zypp::url::ParamMap pmap( getPathParamsMap(zypp::url::E_DECODED));
- pmap[raw_param] = raw_value;
-
+ pmap[param] = value;
setPathParamsMap(pmap);
}
void
UrlBase::setQueryParam(const std::string ¶m, const std::string &value)
{
- std::string raw_param( zypp::url::decode(param));
- std::string raw_value( zypp::url::decode(value));
-
zypp::url::ParamMap pmap( getQueryStringMap(zypp::url::E_DECODED));
- pmap[raw_param] = raw_value;
-
+ pmap[param] = value;
setQueryStringMap(pmap);
}
+ // ---------------------------------------------------------------
+ std::string
+ UrlBase::cleanupPathName(const std::string &path)
+ {
+ size_t pos = 0;
+
+ while( pos < path.length() && path.at(pos) == '/')
+ pos++;
+
+ if( pos > 1)
+ {
+ // make sure, there is not more than
+ // _one_ leading "/" in the path name.
+ return path.substr(pos - 1);
+ }
+
+ return std::string(path);
+ }
+
+
+ // ---------------------------------------------------------------
+ bool
+ UrlBase::isValidHost(const std::string &host)
+ {
+ if( str::regex_match(host, str::regex(RX_VALID_HOSTIPV6)))
+ {
+ struct in6_addr ip;
+
+ if( inet_pton(AF_INET6, host.substr(1, host.size()-2).c_str(), &ip) > 0)
+ return true;
+ else
+ return false;
+ }
+ else
+ {
+ // matches also IPv4 dotted-decimal adresses...
+ std::string tmp( zypp::url::decode(host));
+ return str::regex_match(tmp, str::regex(RX_VALID_HOSTNAME));
+ }
+ }
+
+
+ // ---------------------------------------------------------------
+ bool
+ UrlBase::isValidPort(const std::string &port)
+ {
+ if( str::regex_match(port, str::regex(RX_VALID_PORT)))
+ {
+ long pnum = str::strtonum<long>(port);
+ if( pnum >= 1 && pnum <= USHRT_MAX)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
//////////////////////////////////////////////////////////////////
} // namespace url
////////////////////////////////////////////////////////////////////
// ---------------------------------------------------------------
/**
- * UrlBase behaviour configuration variables container.
- */
- typedef std::map< std::string, std::string > UrlConfig;
-
-
- // ---------------------------------------------------------------
- /**
- * Vector of URL scheme names.
- */
- typedef std::vector<std::string> UrlSchemes;
-
-
- // ---------------------------------------------------------------
- /**
* Url::toString() view options.
*
* A instance of this class represents a bit-wise combination
static const ViewOption DEFAULTS;
/** @} */
+
/**
* Create instance with default combination of view options.
*/
ViewOption(): opt(DEFAULTS.opt)
{}
+
/**
* Adds \p l and \p r to a new option combination.
*
*/
friend inline ViewOption
operator + (const ViewOption &l, const ViewOption &r)
- { return ViewOption(l.opt | r.opt); }
+ {
+ return ViewOption(l.opt | r.opt);
+ }
/**
* Substract \p r from \p l to a new option combination.
*/
friend inline ViewOption
operator - (const ViewOption &l, const ViewOption &r)
- { return ViewOption(l.opt & ~r.opt); }
+ {
+ return ViewOption(l.opt & ~r.opt);
+ }
/**
* Assign specified option combination \p o to the current object.
*/
inline ViewOption &
operator = (const ViewOption &o)
- { opt = o.opt; return *this; }
+ {
+ opt = o.opt; return *this;
+ }
/**
* Check if specified option \p o is set in the current object.
*/
inline bool
has(const ViewOption &o) const
- { return o.opt & opt; }
+ {
+ return o.opt & opt;
+ }
private:
ViewOption(int o): opt(o) {}
/**
* ViewOptions is just an alias for ViewOption.
*/
- typedef ViewOption ViewOptions;
+ typedef ViewOption ViewOptions;
// ---------------------------------------------------------------
/**
- * Internal data as used by UrlBase.
+ * Vector of URL scheme names.
*/
- class UrlData
- {
- public:
- UrlData()
- {}
+ typedef std::vector<std::string> UrlSchemes;
- UrlData(const UrlConfig &conf)
- : config(conf)
- {}
- UrlConfig config;
- ViewOptions vopts;
-
- std::string scheme;
- std::string user;
- std::string pass;
- std::string host;
- std::string port;
- std::string pathname;
- std::string pathparams;
- std::string querystr;
- std::string fragment;
- };
+ // ---------------------------------------------------------------
+ /**
+ * Forward declaration of internal UrlBase data.
+ */
+ class UrlBaseData;
// ---------------------------------------------------------------
{
public:
- virtual ~UrlBase();
+ virtual
+ ~UrlBase();
+
UrlBase();
/**
* schemes (see getKnownSchemes()) if the list is not empty (as
* in the UrlBase class).
*
+ * \param scheme The scheme name to verify.
* \return True, if generic scheme name syntax is valid and
* the scheme name is known to the current object.
*/
virtual bool
isValidScheme(const std::string &scheme) const;
-
/**
* \brief Verifies the Url.
*
/**
* \brief Set the username in the URL authority.
- * \param user The new username.
+ * \param user The new username.
+ * \param eflag If the \p username is encoded or not.
*/
virtual void
- setUsername(const std::string &user);
+ setUsername(const std::string &user,
+ EEncoding eflag);
/**
* \brief Set the password in the URL authority.
- * \param pass The new password.
+ * \param pass The new password.
+ * \param eflag If the \p password is encoded or not.
*/
virtual void
- setPassword(const std::string &pass);
+ setPassword(const std::string &pass,
+ EEncoding eflag);
/**
* \brief Set the hostname or IP in the URL authority.
+ *
+ * The \p host parameter may contain a hostname, an IPv4 address
+ * in dotted-decimal form or an IPv6 address literal encapsulated
+ * within square brackets (RFC3513, Sect. 2.2).
+ *
+ * A hostname may contain national alphanumeric UTF8 characters
+ * (letters other than ASCII a-z0-9), that will be encoded.
+ * This function allows to specify both, a encoded or decoded
+ * hostname.
+ *
+ * Other IP literals in "[v ... ]" square bracket format are not
+ * supported by the implementation in UrlBase class.
+ *
* \param host The new hostname or IP.
*/
virtual void
/**
* \brief Set the path data component in the URL.
*
- * The \p pathdata string may include path parameters
- * separated using the ";" separator character.
+ * By default, the \p pathdata string may include path
+ * parameters separated by the ";" separator character.
*
* \param pathdata The encoded path data component string.
*/
/**
* \brief Set the path name.
- * \param path The new path name.
+ * \param path The new path name.
+ * \param eflag If the \p path name is encoded or not.
*/
virtual void
- setPathName(const std::string &path);
+ setPathName(const std::string &path,
+ EEncoding eflag);
/**
* \brief Set the path parameters.
- * \param params The new path parameter string.
+ * \param params The new encoded path parameter string.
*/
virtual void
setPathParams(const std::string ¶ms);
/**
* \brief Set the path parameters.
- * \param pvec The vector with path parameters.
+ * \param pvec The vector with encoded path parameters.
*/
virtual void
setPathParamsVec(const zypp::url::ParamVec &pvec);
/**
* \brief Set the path parameters.
- * \param pmap The map with path parameters.
+ * \param pmap The map with decoded path parameters.
*/
virtual void
setPathParamsMap(const zypp::url::ParamMap &pmap);
/**
* \brief Set or add value for the specified path parameter.
- * \param param The path parameter name.
- * \param value The path parameter value.
+ * \param param The decoded path parameter name.
+ * \param value The decoded path parameter value.
*/
virtual void
setPathParam(const std::string ¶m, const std::string &value);
/**
* \brief Set the query string in the URL.
*
- * The \p querystr string will be supposed to not to
- * contain the "?" separator character.
- *
* \param querystr The new encoded query string.
*/
virtual void
/**
* \brief Set the query parameters.
- * \param qvec The vector with query parameters.
+ * \param qvec The vector with encoded query parameters.
*/
virtual void
setQueryStringVec(const zypp::url::ParamVec &qvec);
/**
* \brief Set the query parameters.
- * \param qmap The map with query parameters.
+ * \param qmap The map with decoded query parameters.
*/
virtual void
setQueryStringMap(const zypp::url::ParamMap &qmap);
/**
* \brief Set or add value for the specified query parameter.
- * \param param The query parameter name.
- * \param value The query parameter value.
+ * \param param The decoded query parameter name.
+ * \param value The decoded query parameter value.
*/
virtual void
setQueryParam(const std::string ¶m, const std::string &value);
// -----------------
/**
* \brief Set the fragment string in the URL.
- * \param fragment The new encoded fragment string.
+ * \param fragment The new fragment string.
+ * \param eflag If the \p fragment is encoded or not.
*/
virtual void
- setFragment(const std::string &fragment);
+ setFragment(const std::string &fragment,
+ EEncoding eflag);
// -----------------
*
* The UrlBase class uses following config variables:
*
- * - Path parameter separators:
+ * - Common path parameter separators:
* - \a \c sep_pathparams \c ";"
* Separator used to split path parameters from path name.
* - \a \c psep_pathparam \c ","
* .
* .
*
- * - Query string separators:
+ * - Common query string separators:
* - \a \c psep_querystr \c "&"
* Separator between query string parameters.
* - \a \c vsep_querystr \c "="
*
* - Characters in URL components, that are safe without
* URL percent-encoding (see zypp::url::encode()).
- * - \a safe_username ""
- * - \a safe_password ""
- * - \a safe_hostname "[:]"
- * - \a safe_pathname "/"
- * - \a safe_pathparams ""
- * - \a safe_querystr ""
- * - \a safe_fragment ""
+ * - \a safe_username
+ * - \a safe_password
+ * - \a safe_hostname
+ * - \a safe_pathname
+ * - \a safe_pathparams
+ * - \a safe_querystr
+ * - \a safe_fragment
* .
* .
*
- * - Regular expressions used to verify URL components
- * and their sub-components:
- * - \a rx_scheme "^[a-zA-Z][a-zA-Z0-9\\._-]*$"
- * - \a rx_username ".*"
- * - \a rx_password ".*"
- * - \a rx_hostname ".*" FIXME!
- * - \a rx_port "^[0-9]{1,5}$"
- * - \a rx_pathname ".*"
- * - \a rx_pathparams ".*"
- * - \a rx_querystr ".*"
- * - \a rx_fragment ".*"
+ * - Regular expressions used to verify encoded URL
+ * components and their sub-components:
+ * - \a rx_username
+ * - \a rx_password
+ * - \a rx_pathname
+ * - \a rx_pathparams
+ * - \a rx_querystr
+ * - \a rx_fragment
* .
* .
*/
* missinterpret multiple "/" occurences as an empty
* URL authority.
*
- * \param path A path name.
+ * \param path A path name to cleanup.
* \return A path begining with at most one "/" character.
*/
virtual std::string
cleanupPathName(const std::string &path);
+ /**
+ * \brief Verifies specified host or IP.
+ *
+ * This function does not perform any hostname lookups and
+ * supports only IPv6 addresses in "[ ... ]" notation.
+ *
+ * \param host The host name or IP to verify.
+ * \return True, if host seems to be valid.
+ */
+ virtual bool
+ isValidHost(const std::string &host);
+
+ /**
+ * \brief Verifies specified port number.
+ *
+ * \param port The port number to verify.
+ * \return True, if port number is valid.
+ */
+ virtual bool
+ isValidPort(const std::string &port);
private:
- UrlData *m_data;
+ UrlBaseData *m_data;
};