aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp
diff options
context:
space:
mode:
authornalpp <nalpp@yandex-team.ru>2022-02-10 16:46:46 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:46:46 +0300
commit30d1ef3941e0dc835be7609de5ebee66958f215a (patch)
tree49e222ea1c5804306084bb3ae065bb702625360f /contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp
parent87f3eb38999df2d3c1cb77f8ffb9c52ec9c516fb (diff)
downloadydb-30d1ef3941e0dc835be7609de5ebee66958f215a.tar.gz
Restoring authorship annotation for <nalpp@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp')
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp946
1 files changed, 473 insertions, 473 deletions
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp
index e5a8e4cade..a2239df54b 100644
--- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp
@@ -2,170 +2,170 @@
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
-
-#include <aws/core/http/URI.h>
-
-#include <aws/core/utils/StringUtils.h>
-#include <aws/core/utils/memory/stl/AWSStringStream.h>
-#include <aws/core/utils/memory/stl/AWSSet.h>
-
-#include <cstdlib>
-#include <cctype>
-#include <cassert>
-#include <algorithm>
-#include <iomanip>
-
-using namespace Aws::Http;
-using namespace Aws::Utils;
-
-namespace Aws
-{
-namespace Http
-{
-
-const char* SEPARATOR = "://";
-
-} // namespace Http
-} // namespace Aws
-
-URI::URI() : m_scheme(Scheme::HTTP), m_port(HTTP_DEFAULT_PORT)
-{
-}
-
-URI::URI(const Aws::String& uri) : m_scheme(Scheme::HTTP), m_port(HTTP_DEFAULT_PORT)
-{
- ParseURIParts(uri);
-}
-
-URI::URI(const char* uri) : m_scheme(Scheme::HTTP), m_port(HTTP_DEFAULT_PORT)
-{
- ParseURIParts(uri);
-}
-
-URI& URI::operator =(const Aws::String& uri)
-{
- this->ParseURIParts(uri);
- return *this;
-}
-
-URI& URI::operator =(const char* uri)
-{
- this->ParseURIParts(uri);
- return *this;
-}
-
-bool URI::operator ==(const URI& other) const
-{
- return CompareURIParts(other);
-}
-
-bool URI::operator ==(const Aws::String& other) const
-{
- return CompareURIParts(other);
-}
-
-bool URI::operator ==(const char* other) const
-{
- return CompareURIParts(other);
-}
-
-bool URI::operator !=(const URI& other) const
-{
- return !(*this == other);
-}
-
-bool URI::operator !=(const Aws::String& other) const
-{
- return !(*this == other);
-}
-
-bool URI::operator !=(const char* other) const
-{
- return !(*this == other);
-}
-
-void URI::SetScheme(Scheme value)
-{
- assert(value == Scheme::HTTP || value == Scheme::HTTPS);
-
- if (value == Scheme::HTTP)
- {
- m_port = m_port == HTTPS_DEFAULT_PORT || m_port == 0 ? HTTP_DEFAULT_PORT : m_port;
- m_scheme = value;
- }
- else if (value == Scheme::HTTPS)
- {
- m_port = m_port == HTTP_DEFAULT_PORT || m_port == 0 ? HTTPS_DEFAULT_PORT : m_port;
- m_scheme = value;
- }
-}
-
-Aws::String URI::URLEncodePathRFC3986(const Aws::String& path)
-{
- if(path.empty())
- {
- return path;
- }
-
- const Aws::Vector<Aws::String> pathParts = StringUtils::Split(path, '/');
- Aws::StringStream ss;
- ss << std::hex << std::uppercase;
-
- // escape characters appearing in a URL path according to RFC 3986
- for (const auto& segment : pathParts)
- {
- ss << '/';
- for(unsigned char c : segment) // alnum results in UB if the value of c is not unsigned char & is not EOF
- {
+
+#include <aws/core/http/URI.h>
+
+#include <aws/core/utils/StringUtils.h>
+#include <aws/core/utils/memory/stl/AWSStringStream.h>
+#include <aws/core/utils/memory/stl/AWSSet.h>
+
+#include <cstdlib>
+#include <cctype>
+#include <cassert>
+#include <algorithm>
+#include <iomanip>
+
+using namespace Aws::Http;
+using namespace Aws::Utils;
+
+namespace Aws
+{
+namespace Http
+{
+
+const char* SEPARATOR = "://";
+
+} // namespace Http
+} // namespace Aws
+
+URI::URI() : m_scheme(Scheme::HTTP), m_port(HTTP_DEFAULT_PORT)
+{
+}
+
+URI::URI(const Aws::String& uri) : m_scheme(Scheme::HTTP), m_port(HTTP_DEFAULT_PORT)
+{
+ ParseURIParts(uri);
+}
+
+URI::URI(const char* uri) : m_scheme(Scheme::HTTP), m_port(HTTP_DEFAULT_PORT)
+{
+ ParseURIParts(uri);
+}
+
+URI& URI::operator =(const Aws::String& uri)
+{
+ this->ParseURIParts(uri);
+ return *this;
+}
+
+URI& URI::operator =(const char* uri)
+{
+ this->ParseURIParts(uri);
+ return *this;
+}
+
+bool URI::operator ==(const URI& other) const
+{
+ return CompareURIParts(other);
+}
+
+bool URI::operator ==(const Aws::String& other) const
+{
+ return CompareURIParts(other);
+}
+
+bool URI::operator ==(const char* other) const
+{
+ return CompareURIParts(other);
+}
+
+bool URI::operator !=(const URI& other) const
+{
+ return !(*this == other);
+}
+
+bool URI::operator !=(const Aws::String& other) const
+{
+ return !(*this == other);
+}
+
+bool URI::operator !=(const char* other) const
+{
+ return !(*this == other);
+}
+
+void URI::SetScheme(Scheme value)
+{
+ assert(value == Scheme::HTTP || value == Scheme::HTTPS);
+
+ if (value == Scheme::HTTP)
+ {
+ m_port = m_port == HTTPS_DEFAULT_PORT || m_port == 0 ? HTTP_DEFAULT_PORT : m_port;
+ m_scheme = value;
+ }
+ else if (value == Scheme::HTTPS)
+ {
+ m_port = m_port == HTTP_DEFAULT_PORT || m_port == 0 ? HTTPS_DEFAULT_PORT : m_port;
+ m_scheme = value;
+ }
+}
+
+Aws::String URI::URLEncodePathRFC3986(const Aws::String& path)
+{
+ if(path.empty())
+ {
+ return path;
+ }
+
+ const Aws::Vector<Aws::String> pathParts = StringUtils::Split(path, '/');
+ Aws::StringStream ss;
+ ss << std::hex << std::uppercase;
+
+ // escape characters appearing in a URL path according to RFC 3986
+ for (const auto& segment : pathParts)
+ {
+ ss << '/';
+ for(unsigned char c : segment) // alnum results in UB if the value of c is not unsigned char & is not EOF
+ {
// §2.3 unreserved characters
if (StringUtils::IsAlnum(c))
- {
- ss << c;
- continue;
- }
- switch(c)
- {
- // §2.3 unreserved characters
- case '-': case '_': case '.': case '~':
- // The path section of the URL allow reserved characters to appear unescaped
- // RFC 3986 §2.2 Reserved characters
- // NOTE: this implementation does not accurately implement the RFC on purpose to accommodate for
- // discrepancies in the implementations of URL encoding between AWS services for legacy reasons.
+ {
+ ss << c;
+ continue;
+ }
+ switch(c)
+ {
+ // §2.3 unreserved characters
+ case '-': case '_': case '.': case '~':
+ // The path section of the URL allow reserved characters to appear unescaped
+ // RFC 3986 §2.2 Reserved characters
+ // NOTE: this implementation does not accurately implement the RFC on purpose to accommodate for
+ // discrepancies in the implementations of URL encoding between AWS services for legacy reasons.
case '$': case '&': case ',':
case ':': case '=': case '@':
- ss << c;
- break;
- default:
+ ss << c;
+ break;
+ default:
ss << '%' << std::setfill('0') << std::setw(2) << (int)((unsigned char)c) << std::setw(0);
- }
- }
- }
-
- //if the last character was also a slash, then add that back here.
- if (path.back() == '/')
- {
- ss << '/';
- }
-
- return ss.str();
-}
-
-Aws::String URI::URLEncodePath(const Aws::String& path)
-{
- Aws::Vector<Aws::String> pathParts = StringUtils::Split(path, '/');
- Aws::StringStream ss;
-
- for (Aws::Vector<Aws::String>::iterator iter = pathParts.begin(); iter != pathParts.end(); ++iter)
- {
- ss << '/' << StringUtils::URLEncode(iter->c_str());
- }
-
- //if the last character was also a slash, then add that back here.
+ }
+ }
+ }
+
+ //if the last character was also a slash, then add that back here.
+ if (path.back() == '/')
+ {
+ ss << '/';
+ }
+
+ return ss.str();
+}
+
+Aws::String URI::URLEncodePath(const Aws::String& path)
+{
+ Aws::Vector<Aws::String> pathParts = StringUtils::Split(path, '/');
+ Aws::StringStream ss;
+
+ for (Aws::Vector<Aws::String>::iterator iter = pathParts.begin(); iter != pathParts.end(); ++iter)
+ {
+ ss << '/' << StringUtils::URLEncode(iter->c_str());
+ }
+
+ //if the last character was also a slash, then add that back here.
if (path.length() > 0 && path[path.length() - 1] == '/')
- {
- ss << '/';
- }
-
+ {
+ ss << '/';
+ }
+
if (path.length() > 0 && path[0] != '/')
{
return ss.str().substr(1);
@@ -174,9 +174,9 @@ Aws::String URI::URLEncodePath(const Aws::String& path)
{
return ss.str();
}
-}
-
-void URI::SetPath(const Aws::String& value)
+}
+
+void URI::SetPath(const Aws::String& value)
{
const Aws::Vector<Aws::String> pathParts = StringUtils::Split(value, '/');
Aws::String path;
@@ -193,318 +193,318 @@ void URI::SetPath(const Aws::String& value)
path.push_back('/');
}
m_path = std::move(path);
-}
-
-//ugh, this isn't even part of the canonicalization spec. It is part of how our services have implemented their signers though....
+}
+
+//ugh, this isn't even part of the canonicalization spec. It is part of how our services have implemented their signers though....
//it doesn't really hurt anything to reorder it though, so go ahead and sort the values for parameters with the same key
-void InsertValueOrderedParameter(QueryStringParameterCollection& queryParams, const Aws::String& key, const Aws::String& value)
-{
- auto entriesAtKey = queryParams.equal_range(key);
- for (auto& entry = entriesAtKey.first; entry != entriesAtKey.second; ++entry)
- {
- if (entry->second > value)
- {
+void InsertValueOrderedParameter(QueryStringParameterCollection& queryParams, const Aws::String& key, const Aws::String& value)
+{
+ auto entriesAtKey = queryParams.equal_range(key);
+ for (auto& entry = entriesAtKey.first; entry != entriesAtKey.second; ++entry)
+ {
+ if (entry->second > value)
+ {
queryParams.emplace_hint(entry, key, value);
- return;
- }
- }
-
- queryParams.emplace(key, value);
-}
-
-QueryStringParameterCollection URI::GetQueryStringParameters(bool decode) const
-{
- Aws::String queryString = GetQueryString();
-
- QueryStringParameterCollection parameterCollection;
-
- //if we actually have a query string
- if (queryString.size() > 0)
- {
- size_t currentPos = 1, locationOfNextDelimiter = 1;
-
- //while we have params left to parse
- while (currentPos < queryString.size())
- {
- //find next key/value pair
- locationOfNextDelimiter = queryString.find('&', currentPos);
-
- Aws::String keyValuePair;
-
- //if this isn't the last parameter
- if (locationOfNextDelimiter != Aws::String::npos)
- {
- keyValuePair = queryString.substr(currentPos, locationOfNextDelimiter - currentPos);
- }
- //if it is the last parameter
- else
- {
- keyValuePair = queryString.substr(currentPos);
- }
-
- //split on =
- size_t locationOfEquals = keyValuePair.find('=');
- Aws::String key = keyValuePair.substr(0, locationOfEquals);
- Aws::String value = keyValuePair.substr(locationOfEquals + 1);
-
- if(decode)
- {
- InsertValueOrderedParameter(parameterCollection, StringUtils::URLDecode(key.c_str()), StringUtils::URLDecode(value.c_str()));
- }
- else
- {
- InsertValueOrderedParameter(parameterCollection, key, value);
- }
-
- currentPos += keyValuePair.size() + 1;
- }
- }
-
- return parameterCollection;
-}
-
-void URI::CanonicalizeQueryString()
-{
- QueryStringParameterCollection sortedParameters = GetQueryStringParameters(false);
- Aws::StringStream queryStringStream;
-
- bool first = true;
-
- if(sortedParameters.size() > 0)
- {
- queryStringStream << "?";
- }
-
+ return;
+ }
+ }
+
+ queryParams.emplace(key, value);
+}
+
+QueryStringParameterCollection URI::GetQueryStringParameters(bool decode) const
+{
+ Aws::String queryString = GetQueryString();
+
+ QueryStringParameterCollection parameterCollection;
+
+ //if we actually have a query string
+ if (queryString.size() > 0)
+ {
+ size_t currentPos = 1, locationOfNextDelimiter = 1;
+
+ //while we have params left to parse
+ while (currentPos < queryString.size())
+ {
+ //find next key/value pair
+ locationOfNextDelimiter = queryString.find('&', currentPos);
+
+ Aws::String keyValuePair;
+
+ //if this isn't the last parameter
+ if (locationOfNextDelimiter != Aws::String::npos)
+ {
+ keyValuePair = queryString.substr(currentPos, locationOfNextDelimiter - currentPos);
+ }
+ //if it is the last parameter
+ else
+ {
+ keyValuePair = queryString.substr(currentPos);
+ }
+
+ //split on =
+ size_t locationOfEquals = keyValuePair.find('=');
+ Aws::String key = keyValuePair.substr(0, locationOfEquals);
+ Aws::String value = keyValuePair.substr(locationOfEquals + 1);
+
+ if(decode)
+ {
+ InsertValueOrderedParameter(parameterCollection, StringUtils::URLDecode(key.c_str()), StringUtils::URLDecode(value.c_str()));
+ }
+ else
+ {
+ InsertValueOrderedParameter(parameterCollection, key, value);
+ }
+
+ currentPos += keyValuePair.size() + 1;
+ }
+ }
+
+ return parameterCollection;
+}
+
+void URI::CanonicalizeQueryString()
+{
+ QueryStringParameterCollection sortedParameters = GetQueryStringParameters(false);
+ Aws::StringStream queryStringStream;
+
+ bool first = true;
+
+ if(sortedParameters.size() > 0)
+ {
+ queryStringStream << "?";
+ }
+
if(m_queryString.find('=') != std::string::npos)
- {
- for (QueryStringParameterCollection::iterator iter = sortedParameters.begin();
- iter != sortedParameters.end(); ++iter)
- {
- if (!first)
- {
- queryStringStream << "&";
- }
-
- first = false;
- queryStringStream << iter->first.c_str() << "=" << iter->second.c_str();
- }
-
- m_queryString = queryStringStream.str();
- }
-}
-
-void URI::AddQueryStringParameter(const char* key, const Aws::String& value)
-{
- if (m_queryString.size() <= 0)
- {
- m_queryString.append("?");
- }
- else
- {
- m_queryString.append("&");
- }
-
- m_queryString.append(StringUtils::URLEncode(key) + "=" + StringUtils::URLEncode(value.c_str()));
-}
-
-void URI::AddQueryStringParameter(const Aws::Map<Aws::String, Aws::String>& queryStringPairs)
-{
- for(const auto& entry: queryStringPairs)
- {
- AddQueryStringParameter(entry.first.c_str(), entry.second);
- }
-}
-
-void URI::SetQueryString(const Aws::String& str)
-{
- m_queryString = "";
-
- if (str.empty()) return;
-
- if (str.front() != '?')
- {
- m_queryString.append("?").append(str);
- }
- else
- {
- m_queryString = str;
- }
-}
-
-Aws::String URI::GetURIString(bool includeQueryString) const
-{
- assert(m_authority.size() > 0);
-
- Aws::StringStream ss;
- ss << SchemeMapper::ToString(m_scheme) << SEPARATOR << m_authority;
-
- if (m_scheme == Scheme::HTTP && m_port != HTTP_DEFAULT_PORT)
- {
- ss << ":" << m_port;
- }
- else if (m_scheme == Scheme::HTTPS && m_port != HTTPS_DEFAULT_PORT)
- {
- ss << ":" << m_port;
- }
-
- if(m_path != "/")
- {
- ss << URLEncodePathRFC3986(m_path);
- }
-
- if(includeQueryString)
- {
- ss << m_queryString;
- }
-
- return ss.str();
-}
-
-void URI::ParseURIParts(const Aws::String& uri)
-{
- ExtractAndSetScheme(uri);
- ExtractAndSetAuthority(uri);
- ExtractAndSetPort(uri);
- ExtractAndSetPath(uri);
- ExtractAndSetQueryString(uri);
-}
-
-void URI::ExtractAndSetScheme(const Aws::String& uri)
-{
- size_t posOfSeparator = uri.find(SEPARATOR);
-
- if (posOfSeparator != Aws::String::npos)
- {
- Aws::String schemePortion = uri.substr(0, posOfSeparator);
- SetScheme(SchemeMapper::FromString(schemePortion.c_str()));
- }
- else
- {
- SetScheme(Scheme::HTTP);
- }
-}
-
-void URI::ExtractAndSetAuthority(const Aws::String& uri)
-{
- size_t authorityStart = uri.find(SEPARATOR);
-
- if (authorityStart == Aws::String::npos)
- {
- authorityStart = 0;
- }
- else
- {
- authorityStart += 3;
- }
-
- size_t posOfEndOfAuthorityPort = uri.find(':', authorityStart);
- size_t posOfEndOfAuthoritySlash = uri.find('/', authorityStart);
- size_t posOfEndOfAuthorityQuery = uri.find('?', authorityStart);
- size_t posEndOfAuthority = (std::min)({posOfEndOfAuthorityPort, posOfEndOfAuthoritySlash, posOfEndOfAuthorityQuery});
- if (posEndOfAuthority == Aws::String::npos)
- {
- posEndOfAuthority = uri.length();
- }
-
- SetAuthority(uri.substr(authorityStart, posEndOfAuthority - authorityStart));
-}
-
-void URI::ExtractAndSetPort(const Aws::String& uri)
-{
- size_t authorityStart = uri.find(SEPARATOR);
-
- if(authorityStart == Aws::String::npos)
- {
- authorityStart = 0;
- }
- else
- {
- authorityStart += 3;
- }
-
- size_t positionOfPortDelimiter = uri.find(':', authorityStart);
-
- bool hasPort = positionOfPortDelimiter != Aws::String::npos;
-
- if ((uri.find('/', authorityStart) < positionOfPortDelimiter) || (uri.find('?', authorityStart) < positionOfPortDelimiter))
- {
- hasPort = false;
- }
-
- if (hasPort)
- {
- Aws::String strPort;
-
- size_t i = positionOfPortDelimiter + 1;
- char currentDigit = uri[i];
-
- while (std::isdigit(currentDigit))
- {
- strPort += currentDigit;
- currentDigit = uri[++i];
- }
-
- SetPort(static_cast<uint16_t>(atoi(strPort.c_str())));
- }
-}
-
-void URI::ExtractAndSetPath(const Aws::String& uri)
-{
- size_t authorityStart = uri.find(SEPARATOR);
-
- if (authorityStart == Aws::String::npos)
- {
- authorityStart = 0;
- }
- else
- {
- authorityStart += 3;
- }
-
- size_t pathEnd = uri.find('?');
-
- if (pathEnd == Aws::String::npos)
- {
- pathEnd = uri.length();
- }
-
- Aws::String authorityAndPath = uri.substr(authorityStart, pathEnd - authorityStart);
-
- size_t pathStart = authorityAndPath.find('/');
-
- if (pathStart != Aws::String::npos)
- {
- SetPath(authorityAndPath.substr(pathStart, pathEnd - pathStart));
- }
- else
- {
- SetPath("/");
- }
-}
-
-void URI::ExtractAndSetQueryString(const Aws::String& uri)
-{
- size_t queryStart = uri.find('?');
-
- if (queryStart != Aws::String::npos)
- {
- m_queryString = uri.substr(queryStart);
- }
-}
-
-Aws::String URI::GetFormParameters() const
-{
- if(m_queryString.length() == 0)
- {
- return "";
- }
- else
- {
- return m_queryString.substr(1);
- }
-}
-
-bool URI::CompareURIParts(const URI& other) const
-{
- return m_scheme == other.m_scheme && m_authority == other.m_authority && m_path == other.m_path && m_queryString == other.m_queryString;
-}
+ {
+ for (QueryStringParameterCollection::iterator iter = sortedParameters.begin();
+ iter != sortedParameters.end(); ++iter)
+ {
+ if (!first)
+ {
+ queryStringStream << "&";
+ }
+
+ first = false;
+ queryStringStream << iter->first.c_str() << "=" << iter->second.c_str();
+ }
+
+ m_queryString = queryStringStream.str();
+ }
+}
+
+void URI::AddQueryStringParameter(const char* key, const Aws::String& value)
+{
+ if (m_queryString.size() <= 0)
+ {
+ m_queryString.append("?");
+ }
+ else
+ {
+ m_queryString.append("&");
+ }
+
+ m_queryString.append(StringUtils::URLEncode(key) + "=" + StringUtils::URLEncode(value.c_str()));
+}
+
+void URI::AddQueryStringParameter(const Aws::Map<Aws::String, Aws::String>& queryStringPairs)
+{
+ for(const auto& entry: queryStringPairs)
+ {
+ AddQueryStringParameter(entry.first.c_str(), entry.second);
+ }
+}
+
+void URI::SetQueryString(const Aws::String& str)
+{
+ m_queryString = "";
+
+ if (str.empty()) return;
+
+ if (str.front() != '?')
+ {
+ m_queryString.append("?").append(str);
+ }
+ else
+ {
+ m_queryString = str;
+ }
+}
+
+Aws::String URI::GetURIString(bool includeQueryString) const
+{
+ assert(m_authority.size() > 0);
+
+ Aws::StringStream ss;
+ ss << SchemeMapper::ToString(m_scheme) << SEPARATOR << m_authority;
+
+ if (m_scheme == Scheme::HTTP && m_port != HTTP_DEFAULT_PORT)
+ {
+ ss << ":" << m_port;
+ }
+ else if (m_scheme == Scheme::HTTPS && m_port != HTTPS_DEFAULT_PORT)
+ {
+ ss << ":" << m_port;
+ }
+
+ if(m_path != "/")
+ {
+ ss << URLEncodePathRFC3986(m_path);
+ }
+
+ if(includeQueryString)
+ {
+ ss << m_queryString;
+ }
+
+ return ss.str();
+}
+
+void URI::ParseURIParts(const Aws::String& uri)
+{
+ ExtractAndSetScheme(uri);
+ ExtractAndSetAuthority(uri);
+ ExtractAndSetPort(uri);
+ ExtractAndSetPath(uri);
+ ExtractAndSetQueryString(uri);
+}
+
+void URI::ExtractAndSetScheme(const Aws::String& uri)
+{
+ size_t posOfSeparator = uri.find(SEPARATOR);
+
+ if (posOfSeparator != Aws::String::npos)
+ {
+ Aws::String schemePortion = uri.substr(0, posOfSeparator);
+ SetScheme(SchemeMapper::FromString(schemePortion.c_str()));
+ }
+ else
+ {
+ SetScheme(Scheme::HTTP);
+ }
+}
+
+void URI::ExtractAndSetAuthority(const Aws::String& uri)
+{
+ size_t authorityStart = uri.find(SEPARATOR);
+
+ if (authorityStart == Aws::String::npos)
+ {
+ authorityStart = 0;
+ }
+ else
+ {
+ authorityStart += 3;
+ }
+
+ size_t posOfEndOfAuthorityPort = uri.find(':', authorityStart);
+ size_t posOfEndOfAuthoritySlash = uri.find('/', authorityStart);
+ size_t posOfEndOfAuthorityQuery = uri.find('?', authorityStart);
+ size_t posEndOfAuthority = (std::min)({posOfEndOfAuthorityPort, posOfEndOfAuthoritySlash, posOfEndOfAuthorityQuery});
+ if (posEndOfAuthority == Aws::String::npos)
+ {
+ posEndOfAuthority = uri.length();
+ }
+
+ SetAuthority(uri.substr(authorityStart, posEndOfAuthority - authorityStart));
+}
+
+void URI::ExtractAndSetPort(const Aws::String& uri)
+{
+ size_t authorityStart = uri.find(SEPARATOR);
+
+ if(authorityStart == Aws::String::npos)
+ {
+ authorityStart = 0;
+ }
+ else
+ {
+ authorityStart += 3;
+ }
+
+ size_t positionOfPortDelimiter = uri.find(':', authorityStart);
+
+ bool hasPort = positionOfPortDelimiter != Aws::String::npos;
+
+ if ((uri.find('/', authorityStart) < positionOfPortDelimiter) || (uri.find('?', authorityStart) < positionOfPortDelimiter))
+ {
+ hasPort = false;
+ }
+
+ if (hasPort)
+ {
+ Aws::String strPort;
+
+ size_t i = positionOfPortDelimiter + 1;
+ char currentDigit = uri[i];
+
+ while (std::isdigit(currentDigit))
+ {
+ strPort += currentDigit;
+ currentDigit = uri[++i];
+ }
+
+ SetPort(static_cast<uint16_t>(atoi(strPort.c_str())));
+ }
+}
+
+void URI::ExtractAndSetPath(const Aws::String& uri)
+{
+ size_t authorityStart = uri.find(SEPARATOR);
+
+ if (authorityStart == Aws::String::npos)
+ {
+ authorityStart = 0;
+ }
+ else
+ {
+ authorityStart += 3;
+ }
+
+ size_t pathEnd = uri.find('?');
+
+ if (pathEnd == Aws::String::npos)
+ {
+ pathEnd = uri.length();
+ }
+
+ Aws::String authorityAndPath = uri.substr(authorityStart, pathEnd - authorityStart);
+
+ size_t pathStart = authorityAndPath.find('/');
+
+ if (pathStart != Aws::String::npos)
+ {
+ SetPath(authorityAndPath.substr(pathStart, pathEnd - pathStart));
+ }
+ else
+ {
+ SetPath("/");
+ }
+}
+
+void URI::ExtractAndSetQueryString(const Aws::String& uri)
+{
+ size_t queryStart = uri.find('?');
+
+ if (queryStart != Aws::String::npos)
+ {
+ m_queryString = uri.substr(queryStart);
+ }
+}
+
+Aws::String URI::GetFormParameters() const
+{
+ if(m_queryString.length() == 0)
+ {
+ return "";
+ }
+ else
+ {
+ return m_queryString.substr(1);
+ }
+}
+
+bool URI::CompareURIParts(const URI& other) const
+{
+ return m_scheme == other.m_scheme && m_authority == other.m_authority && m_path == other.m_path && m_queryString == other.m_queryString;
+}