aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2005-04-28 16:35:37 +0000
committerVincent Richard <[email protected]>2005-04-28 16:35:37 +0000
commit4bf0542857f16b20beb21a718905c1f216561f8a (patch)
tree9ebc32226cb128c107cbf78c10a3ce3d4fd71613
parentSendmail implementation + filtered streams. (diff)
downloadvmime-4bf0542857f16b20beb21a718905c1f216561f8a.tar.gz
vmime-4bf0542857f16b20beb21a718905c1f216561f8a.zip
Added parameter support to 'utility::url'.
-rw-r--r--src/utility/url.cpp88
-rw-r--r--src/utility/urlUtils.cpp3
-rw-r--r--tests/utility/urlTest.cpp47
-rw-r--r--vmime/utility/url.hpp14
4 files changed, 150 insertions, 2 deletions
diff --git a/src/utility/url.cpp b/src/utility/url.cpp
index 919a3610..cf991b86 100644
--- a/src/utility/url.cpp
+++ b/src/utility/url.cpp
@@ -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
diff --git a/src/utility/urlUtils.cpp b/src/utility/urlUtils.cpp
index 70a988cf..c22fc2a7 100644
--- a/src/utility/urlUtils.cpp
+++ b/src/utility/urlUtils.cpp
@@ -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;
}
diff --git a/tests/utility/urlTest.cpp b/tests/utility/urlTest.cpp
index cb139987..963febda 100644
--- a/tests/utility/urlTest.cpp
+++ b/tests/utility/urlTest.cpp
@@ -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));
diff --git a/vmime/utility/url.hpp b/vmime/utility/url.hpp
index 89f63c7b..1bb207a0 100644
--- a/vmime/utility/url.hpp
+++ b/vmime/utility/url.hpp
@@ -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;
};