From ea3d03583c4cd2443220eddfedefcea51b7121c5 Mon Sep 17 00:00:00 2001 From: Richard Walters Date: Wed, 4 Jul 2018 19:21:55 -0700 Subject: Fix requirements Query and fragment may be empty but present in a URI. Handle this in the same way that port is handled: include a flag for each of query and fragment, to allow an empty but present query/fragment. --- src/Uri.cpp | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Uri.cpp b/src/Uri.cpp index eee40ad..4e3cba0 100644 --- a/src/Uri.cpp +++ b/src/Uri.cpp @@ -541,12 +541,24 @@ namespace Uri { */ std::vector< std::string > path; + /** + * This flag indicates whether or not the + * URI includes a query. + */ + bool hasQuery = false; + /** * This is the "query" element of the URI, * if it has one. */ std::string query; + /** + * This flag indicates whether or not the + * URI includes a fragment. + */ + bool hasFragment = false; + /** * This is the "fragment" element of the URI, * if it has one. @@ -910,10 +922,11 @@ namespace Uri { * is returned. */ bool ParseQuery(const std::string& queryWithDelimiter) { - if (queryWithDelimiter.empty()) { - query.clear(); - } else { + hasQuery = !queryWithDelimiter.empty(); + if (hasQuery) { query = queryWithDelimiter.substr(1); + } else { + query.clear(); } return DecodeQueryOrFragment(query); } @@ -943,9 +956,11 @@ namespace Uri { ) { const auto fragmentDelimiter = queryAndOrFragment.find('#'); if (fragmentDelimiter == std::string::npos) { + hasFragment = false; fragment.clear(); rest = queryAndOrFragment; } else { + hasFragment = true; fragment = queryAndOrFragment.substr(fragmentDelimiter + 1); rest = queryAndOrFragment.substr(0, fragmentDelimiter); } @@ -1199,10 +1214,18 @@ namespace Uri { return !impl_->IsPathAbsolute(); } + bool Uri::HasQuery() const { + return impl_->hasQuery; + } + std::string Uri::GetQuery() const { return impl_->query; } + bool Uri::HasFragment() const { + return impl_->hasFragment; + } + std::string Uri::GetFragment() const { return impl_->fragment; } @@ -1288,12 +1311,22 @@ namespace Uri { impl_->path = path; } + void Uri::ClearQuery() { + impl_->hasQuery = false; + } + void Uri::SetQuery(const std::string& query) { impl_->query = query; + impl_->hasQuery = true; + } + + void Uri::ClearFragment() { + impl_->hasFragment = false; } void Uri::SetFragment(const std::string& fragment) { impl_->fragment = fragment; + impl_->hasFragment = true; } std::string Uri::GenerateString() const { @@ -1332,10 +1365,10 @@ namespace Uri { } ++i; } - if (!impl_->query.empty()) { + if (impl_->hasQuery) { buffer << '?' << impl_->query; } - if (!impl_->fragment.empty()) { + if (impl_->hasFragment) { buffer << '#' << impl_->fragment; } return buffer.str(); -- cgit v1.2.3