Added parameter support to 'utility::url'.
This commit is contained in:
parent
38a8632828
commit
4bf0542857
@ -69,6 +69,8 @@ url& url::operator=(const url& u)
|
||||
|
||||
m_path = u.m_path;
|
||||
|
||||
m_params = u.m_params;
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
@ -120,6 +122,29 @@ const string url::build() const
|
||||
oss << urlUtils::encode(m_path);
|
||||
}
|
||||
|
||||
const std::vector <const propertySet::property*> params
|
||||
= m_params.getPropertyList();
|
||||
|
||||
if (!params.empty())
|
||||
{
|
||||
if (m_path.empty())
|
||||
oss << "/";
|
||||
|
||||
oss << "?";
|
||||
|
||||
for (unsigned int i = 0 ; i < params.size() ; ++i)
|
||||
{
|
||||
const propertySet::property* prop = params[i];
|
||||
|
||||
if (i != 0)
|
||||
oss << "&";
|
||||
|
||||
oss << urlUtils::encode(prop->getName());
|
||||
oss << "=";
|
||||
oss << urlUtils::encode(prop->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return (oss.str());
|
||||
}
|
||||
|
||||
@ -191,6 +216,15 @@ void url::parse(const string& str)
|
||||
|
||||
// Path
|
||||
string path = utility::stringUtils::trim(string(str.begin() + slashPos, str.end()));
|
||||
string params;
|
||||
|
||||
string::size_type paramSep = path.find_first_of('?');
|
||||
|
||||
if (paramSep != string::npos)
|
||||
{
|
||||
params = string(path.begin() + paramSep + 1, path.end());
|
||||
path.erase(path.begin() + paramSep, path.end());
|
||||
}
|
||||
|
||||
if (path == "/")
|
||||
path.clear();
|
||||
@ -224,6 +258,48 @@ void url::parse(const string& str)
|
||||
if (portNum == 0)
|
||||
portNum = UNSPECIFIED_PORT;
|
||||
|
||||
// Extract parameters
|
||||
m_params.removeAllProperties();
|
||||
|
||||
if (!params.empty())
|
||||
{
|
||||
string::size_type pos = 0;
|
||||
|
||||
do
|
||||
{
|
||||
const string::size_type start = pos;
|
||||
|
||||
pos = params.find_first_of('&', pos);
|
||||
|
||||
const string::size_type equal = params.find_first_of('=', start);
|
||||
const string::size_type end =
|
||||
(pos == string::npos ? params.length() : pos);
|
||||
|
||||
string name;
|
||||
string value;
|
||||
|
||||
if (equal == string::npos || equal > pos) // no value
|
||||
{
|
||||
name = string(params.begin() + start, params.begin() + end);
|
||||
value = name;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = string(params.begin() + start, params.begin() + equal);
|
||||
value = string(params.begin() + equal + 1, params.begin() + end);
|
||||
}
|
||||
|
||||
name = urlUtils::decode(name);
|
||||
value = urlUtils::decode(value);
|
||||
|
||||
m_params.setProperty(name, value);
|
||||
|
||||
if (pos != string::npos)
|
||||
++pos;
|
||||
}
|
||||
while (pos != string::npos);
|
||||
}
|
||||
|
||||
// Now, save URL parts
|
||||
m_protocol = proto;
|
||||
|
||||
@ -309,5 +385,17 @@ void url::setPath(const string& path)
|
||||
}
|
||||
|
||||
|
||||
const propertySet& url::getParams() const
|
||||
{
|
||||
return (m_params);
|
||||
}
|
||||
|
||||
|
||||
propertySet& url::getParams()
|
||||
{
|
||||
return (m_params);
|
||||
}
|
||||
|
||||
|
||||
} // utility
|
||||
} // vmime
|
||||
|
@ -34,7 +34,8 @@ const string urlUtils::encode(const string& s)
|
||||
{
|
||||
const char_t c = *it;
|
||||
|
||||
if (parserHelpers::isPrint(c) && !parserHelpers::isSpace(c) && c != '%')
|
||||
if (parserHelpers::isPrint(c) && !parserHelpers::isSpace(c) &&
|
||||
c != '%' && c != '=' && c != '?' && c != '&')
|
||||
{
|
||||
result += c;
|
||||
}
|
||||
|
@ -149,13 +149,57 @@ namespace
|
||||
assert_eq("1.7", "/pa\xabth/", u1.getPath());
|
||||
}
|
||||
|
||||
void testParse4()
|
||||
{
|
||||
// Test parameters
|
||||
vmime::utility::url u1("", "");
|
||||
|
||||
assert_eq("1.1", true, parseHelper(u1, "proto://host/path?p1=v1&p2=v2"));
|
||||
assert_eq("1.2", "v1", u1.getParams().getProperty <vmime::string>("p1"));
|
||||
assert_eq("1.3", "v2", u1.getParams().getProperty <vmime::string>("p2"));
|
||||
assert_eq("1.4", "/path", u1.getPath());
|
||||
|
||||
vmime::utility::url u2("", "");
|
||||
|
||||
assert_eq("2.1", true, parseHelper(u2, "proto://host/path?p1=v1&p2"));
|
||||
assert_eq("2.2", "v1", u2.getParams().getProperty <vmime::string>("p1"));
|
||||
assert_eq("2.3", "p2", u2.getParams().getProperty <vmime::string>("p2"));
|
||||
assert_eq("2.4", "/path", u2.getPath());
|
||||
|
||||
vmime::utility::url u3("", "");
|
||||
|
||||
assert_eq("3.1", true, parseHelper(u3, "proto://host/?p1=v1&p2=v2"));
|
||||
assert_eq("3.2", "v1", u3.getParams().getProperty <vmime::string>("p1"));
|
||||
assert_eq("3.3", "v2", u3.getParams().getProperty <vmime::string>("p2"));
|
||||
assert_eq("3.4", "", u3.getPath());
|
||||
|
||||
vmime::utility::url u4("", "");
|
||||
|
||||
assert_eq("4.1", true, parseHelper(u4, "proto://host/path?p1=%3D&%3D=v2"));
|
||||
assert_eq("4.2", "=", u4.getParams().getProperty <vmime::string>("p1"));
|
||||
assert_eq("4.3", "v2", u4.getParams().getProperty <vmime::string>("="));
|
||||
assert_eq("4.4", "/path", u4.getPath());
|
||||
}
|
||||
|
||||
void testGenerate()
|
||||
{
|
||||
vmime::utility::url u1("proto", "host", 12345, "path", "user", "password");
|
||||
assert_eq("1", "proto://user:password@host:12345/path",
|
||||
static_cast <vmime::string>(u1));
|
||||
|
||||
// TODO: more tests
|
||||
vmime::utility::url u2("proto", "host");
|
||||
assert_eq("2", "proto://host", static_cast <vmime::string>(u2));
|
||||
|
||||
vmime::utility::url u3("proto", "host");
|
||||
u3.getParams().setProperty("p1", "v1");
|
||||
assert_eq("3.1", "proto://host/?p1=v1",
|
||||
static_cast <vmime::string>(u3));
|
||||
u3.getParams().setProperty("p2", "v2");
|
||||
assert_eq("3.2", "proto://host/?p1=v1&p2=v2",
|
||||
static_cast <vmime::string>(u3));
|
||||
u3.getParams().setProperty("&", "=");
|
||||
assert_eq("3.3", "proto://host/?p1=v1&p2=v2&%26=%3D",
|
||||
static_cast <vmime::string>(u3));
|
||||
}
|
||||
|
||||
void testUtilsEncode()
|
||||
@ -196,6 +240,7 @@ namespace
|
||||
add("Parse1", testcase(this, "Parse1", &urlTest::testParse1));
|
||||
add("Parse2", testcase(this, "Parse2", &urlTest::testParse2));
|
||||
add("Parse3", testcase(this, "Parse3", &urlTest::testParse3));
|
||||
add("Parse4", testcase(this, "Parse4", &urlTest::testParse4));
|
||||
add("Generate", testcase(this, "Generate", &urlTest::testGenerate));
|
||||
add("UtilsEncode", testcase(this, "UtilsEncode", &urlTest::testUtilsEncode));
|
||||
add("UtilsDecode", testcase(this, "UtilsDecode", &urlTest::testUtilsDecode));
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
#include "vmime/base.hpp"
|
||||
#include "vmime/propertySet.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
@ -153,6 +154,17 @@ public:
|
||||
*/
|
||||
void setPath(const string& path);
|
||||
|
||||
/** Return the parameters of the URL (read-only).
|
||||
*
|
||||
* @return parameters
|
||||
*/
|
||||
const propertySet& getParams() const;
|
||||
|
||||
/** Return the parameters of the URL.
|
||||
*
|
||||
* @return parameters
|
||||
*/
|
||||
propertySet& getParams();
|
||||
|
||||
/** Build a string URL from this object.
|
||||
*/
|
||||
@ -179,6 +191,8 @@ private:
|
||||
port_t m_port;
|
||||
|
||||
string m_path;
|
||||
|
||||
propertySet m_params;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user