mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-29 21:30:04 +01:00
improved URI documentation regarding setQuery()/getQuery(); added getQueryParameters()/setQueryParameters()
This commit is contained in:
parent
4b53f137de
commit
a417d49d5d
@ -22,6 +22,7 @@
|
||||
|
||||
#include "Poco/Foundation.h"
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -40,11 +41,13 @@ class Foundation_API URI
|
||||
///
|
||||
/// The class automatically performs a few normalizations on
|
||||
/// all URIs and URI parts passed to it:
|
||||
/// * scheme identifiers are converted to lower case.
|
||||
/// * scheme identifiers are converted to lower case
|
||||
/// * percent-encoded characters are decoded
|
||||
/// * optionally, dot segments are removed from paths (see normalize())
|
||||
{
|
||||
public:
|
||||
typedef std::vector<std::pair<std::string, std::string> > QueryParameters;
|
||||
|
||||
URI();
|
||||
/// Creates an empty URI.
|
||||
|
||||
@ -159,10 +162,30 @@ public:
|
||||
/// Sets the path part of the URI.
|
||||
|
||||
std::string getQuery() const;
|
||||
/// Returns the query part of the URI.
|
||||
/// Returns the decoded query part of the URI.
|
||||
///
|
||||
/// Note that encoded ampersand characters ('&', "%26")
|
||||
/// will be decoded, which could cause ambiguities if the query
|
||||
/// string contains multiple parameters and a parameter name
|
||||
/// or value contains an ampersand as well.
|
||||
/// In such a case it's better to use getRawQuery() or
|
||||
/// getQueryParameters().
|
||||
|
||||
void setQuery(const std::string& query);
|
||||
/// Sets the query part of the URI.
|
||||
///
|
||||
/// The query string will be percent-encoded. If the query
|
||||
/// already contains percent-encoded characters, these
|
||||
/// will be double-encoded, which is probably not what's
|
||||
/// intended by the caller. Furthermore, ampersand ('&')
|
||||
/// characters in the query will not be encoded. This could
|
||||
/// lead to ambiguity issues if the query string contains multiple
|
||||
/// name-value parameters separated by ampersand, and if any
|
||||
/// name or value also contains an ampersand. In such a
|
||||
/// case, it's better to use setRawQuery() with a properly
|
||||
/// percent-encoded query string, or use addQueryParameter()
|
||||
/// or setQueryParameters(), which take care of appropriate
|
||||
/// percent encoding of parameter names and values.
|
||||
|
||||
void addQueryParameter(const std::string& param, const std::string& val = "");
|
||||
/// Adds "param=val" to the query; "param" may not be empty.
|
||||
@ -172,11 +195,24 @@ public:
|
||||
/// if found in param or val.
|
||||
|
||||
const std::string& getRawQuery() const;
|
||||
/// Returns the unencoded query part of the URI.
|
||||
/// Returns the query string in raw form, which usually
|
||||
/// means percent encoded.
|
||||
|
||||
void setRawQuery(const std::string& query);
|
||||
/// Sets the query part of the URI.
|
||||
///
|
||||
/// The given query string must be properly percent-encoded.
|
||||
|
||||
QueryParameters getQueryParameters() const;
|
||||
/// Returns the decoded query string parameters as a vector
|
||||
/// of name-value pairs.
|
||||
|
||||
void setQueryParameters(const QueryParameters& params);
|
||||
/// Sets the query part of the URI from a vector
|
||||
/// of query parameters.
|
||||
///
|
||||
/// Calls addQueryParameter() for each parameter name and value.
|
||||
|
||||
const std::string& getFragment() const;
|
||||
/// Returns the fragment part of the URI.
|
||||
|
||||
@ -246,6 +282,7 @@ public:
|
||||
/// URI-decodes the given string by replacing percent-encoded
|
||||
/// characters with the actual character. The decoded string
|
||||
/// is appended to decodedStr.
|
||||
///
|
||||
/// When plusAsSpace is true, non-encoded plus signs in the query are decoded as spaces.
|
||||
/// (http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1)
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace Poco {
|
||||
|
||||
|
||||
const std::string URI::RESERVED_PATH = "?#";
|
||||
const std::string URI::RESERVED_QUERY = "#/";
|
||||
const std::string URI::RESERVED_QUERY = "?#/";
|
||||
const std::string URI::RESERVED_FRAGMENT = "";
|
||||
const std::string URI::ILLEGAL = "%<>{}|\\\"^`";
|
||||
|
||||
@ -335,9 +335,9 @@ void URI::addQueryParameter(const std::string& param, const std::string& val)
|
||||
{
|
||||
std::string reserved(RESERVED_QUERY);
|
||||
reserved += "=&";
|
||||
if (!_query.empty()) _query.append(1, '&');
|
||||
if (!_query.empty()) _query += '&';
|
||||
encode(param, reserved, _query);
|
||||
_query.append(1, '=');
|
||||
_query += '=';
|
||||
encode(val, reserved, _query);
|
||||
}
|
||||
|
||||
@ -350,6 +350,56 @@ std::string URI::getQuery() const
|
||||
}
|
||||
|
||||
|
||||
URI::QueryParameters URI::getQueryParameters() const
|
||||
{
|
||||
QueryParameters result;
|
||||
std::string::const_iterator it(_query.begin());
|
||||
std::string::const_iterator end(_query.end());
|
||||
while (it != end)
|
||||
{
|
||||
std::string name;
|
||||
std::string value;
|
||||
while (it != end && *it != '=' && *it != '&')
|
||||
{
|
||||
if (*it == '+')
|
||||
name += ' ';
|
||||
else
|
||||
name += *it;
|
||||
++it;
|
||||
}
|
||||
if (it != end && *it == '=')
|
||||
{
|
||||
++it;
|
||||
while (it != end && *it != '&')
|
||||
{
|
||||
if (*it == '+')
|
||||
value += ' ';
|
||||
else
|
||||
value += *it;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
std::string decodedName;
|
||||
std::string decodedValue;
|
||||
URI::decode(name, decodedName);
|
||||
URI::decode(value, decodedValue);
|
||||
result.push_back(std::make_pair(decodedName, decodedValue));
|
||||
if (it != end && *it == '&') ++it;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void URI::setQueryParameters(const QueryParameters& params)
|
||||
{
|
||||
_query.clear();
|
||||
for (QueryParameters::const_iterator it = params.begin(); it != params.end(); ++it)
|
||||
{
|
||||
addQueryParameter(it->first, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void URI::setFragment(const std::string& fragment)
|
||||
{
|
||||
_fragment.clear();
|
||||
|
@ -720,6 +720,7 @@ void URITest::testSwap()
|
||||
assert (uri2.toString() == "http://www.appinf.com/search.cgi?keyword=test%20encoded&scope=all#result");
|
||||
}
|
||||
|
||||
|
||||
void URITest::testOther()
|
||||
{
|
||||
// The search string is "hello%world"; google happens to ignore the '%'
|
||||
@ -735,6 +736,18 @@ void URITest::testOther()
|
||||
assert(uri.toString() == "http://google.com/search?q=hello%25world#frag%20ment");
|
||||
assert(uri.getPathEtc() == "/search?q=hello%25world#frag%20ment");
|
||||
|
||||
uri.setQuery("q=foo&bar");
|
||||
assert(uri.getQuery() == "q=foo&bar");
|
||||
assert(uri.getRawQuery() == "q=foo&bar");
|
||||
assert(uri.toString() == "http://google.com/search?q=foo&bar#frag%20ment");
|
||||
assert(uri.getPathEtc() == "/search?q=foo&bar#frag%20ment");
|
||||
|
||||
uri.setQuery("q=foo/bar");
|
||||
assert(uri.getQuery() == "q=foo/bar");
|
||||
assert(uri.getRawQuery() == "q=foo%2Fbar");
|
||||
assert(uri.toString() == "http://google.com/search?q=foo%2Fbar#frag%20ment");
|
||||
assert(uri.getPathEtc() == "/search?q=foo%2Fbar#frag%20ment");
|
||||
|
||||
uri.setQuery("q=goodbye cruel world");
|
||||
assert(uri.getQuery() == "q=goodbye cruel world");
|
||||
assert(uri.getRawQuery() == "q=goodbye%20cruel%20world");
|
||||
@ -753,6 +766,15 @@ void URITest::testOther()
|
||||
uri.addQueryParameter("pa=ra&m2", "val&ue");
|
||||
assert(uri.getRawQuery() == "q=pony%7eride&pa%3Dra%26m1=&pa%3Dra%26m2=val%26ue");
|
||||
assert(uri.getQuery() == "q=pony~ride&pa=ra&m1=&pa=ra&m2=val&ue");
|
||||
|
||||
uri = "http://google.com/search?q=hello+world#frag%20ment";
|
||||
assert(uri.getHost() == "google.com");
|
||||
assert(uri.getPath() == "/search");
|
||||
assert(uri.getQuery() == "q=hello+world");
|
||||
assert(uri.getRawQuery() == "q=hello+world");
|
||||
assert(uri.getFragment() == "frag ment");
|
||||
assert(uri.toString() == "http://google.com/search?q=hello+world#frag%20ment");
|
||||
assert(uri.getPathEtc() == "/search?q=hello+world#frag%20ment");
|
||||
}
|
||||
|
||||
|
||||
@ -792,6 +814,40 @@ void URITest::testFromPath()
|
||||
}
|
||||
|
||||
|
||||
void URITest::testQueryParameters()
|
||||
{
|
||||
Poco::URI uri("http://google.com/search?q=hello+world&client=safari");
|
||||
URI::QueryParameters params = uri.getQueryParameters();
|
||||
assert (params.size() == 2);
|
||||
assert (params[0].first == "q");
|
||||
assert (params[0].second == "hello world");
|
||||
assert (params[1].first == "client");
|
||||
assert (params[1].second == "safari");
|
||||
|
||||
uri.setQueryParameters(params);
|
||||
assert (uri.toString() == "http://google.com/search?q=hello%20world&client=safari");
|
||||
|
||||
uri = "http://google.com/search?q=&client&";
|
||||
params = uri.getQueryParameters();
|
||||
assert (params.size() == 2);
|
||||
assert (params[0].first == "q");
|
||||
assert (params[0].second == "");
|
||||
assert (params[1].first == "client");
|
||||
assert (params[1].second == "");
|
||||
|
||||
uri.setQueryParameters(params);
|
||||
assert (uri.toString() == "http://google.com/search?q=&client=");
|
||||
|
||||
params[0].second = "foo/bar?";
|
||||
uri.setQueryParameters(params);
|
||||
assert (uri.toString() == "http://google.com/search?q=foo%2Fbar%3F&client=");
|
||||
|
||||
params[0].second = "foo&bar";
|
||||
uri.setQueryParameters(params);
|
||||
assert (uri.toString() == "http://google.com/search?q=foo%26bar&client=");
|
||||
}
|
||||
|
||||
|
||||
void URITest::setUp()
|
||||
{
|
||||
}
|
||||
@ -816,6 +872,7 @@ CppUnit::Test* URITest::suite()
|
||||
CppUnit_addTest(pSuite, URITest, testEncodeDecode);
|
||||
CppUnit_addTest(pSuite, URITest, testOther);
|
||||
CppUnit_addTest(pSuite, URITest, testFromPath);
|
||||
CppUnit_addTest(pSuite, URITest, testQueryParameters);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
void testEncodeDecode();
|
||||
void testOther();
|
||||
void testFromPath();
|
||||
void testQueryParameters();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
Loading…
x
Reference in New Issue
Block a user