Url use url encoded queries (#730)

* keep url-encoded queries
This commit is contained in:
Victor Vazquez 2020-10-12 09:39:46 -07:00 committed by GitHub
parent 966b7892b2
commit 9eb132249b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 1159 additions and 823 deletions

View File

@ -31,16 +31,6 @@ namespace Azure { namespace Core { namespace Test {
namespace Azure { namespace Core { namespace Http {
namespace Details {
// returns left map plus all items in right
// when duplicates, left items are preferred
static std::map<std::string, std::string> MergeMaps(
std::map<std::string, std::string> left,
std::map<std::string, std::string> const& right)
{
left.insert(right.begin(), right.end());
return left;
}
/**
* @brief Insert a header into \p headers checking that \p headerName does not contain invalid
* characters.
@ -197,52 +187,49 @@ namespace Azure { namespace Core { namespace Http {
Stream, ///< Stream.
};
// Url represent the location where a request will be performed. It can be parsed and init from
// a string that contains all Url parts (scheme, host, path, etc).
// Authority is not currently supported.
/**
* @brief URL.
* @brief Url represents the location where a request will be performed.
* It can be parsed and initialized from a string that contains all URL components (scheme, host,
* path, etc.). Authority is not currently supported.
*/
class Url {
// Let Request class to be able to set retry enabled ON
friend class Request;
private:
std::string m_scheme;
std::string m_host;
int m_port{-1};
std::string m_encodedPath;
std::string m_fragment;
// query parameters are all decoded
std::map<std::string, std::string> m_queryParameters;
std::map<std::string, std::string> m_retryQueryParameters;
bool m_retryModeEnabled{false};
// query parameters are all encoded
std::map<std::string, std::string> m_encodedQueryParameters;
/********* private static methods for all instances *******/
static std::string Decode(const std::string& value);
static std::string EncodeHost(const std::string& host);
static std::string EncodePath(const std::string& path);
static std::string EncodeQuery(const std::string& query);
static std::string EncodeFragment(const std::string& fragment);
static std::string EncodeImpl(
const std::string& source,
const std::function<bool(int)>& should_encode);
void StartRetry()
{
m_retryModeEnabled = true;
m_retryQueryParameters.clear();
}
void StopRetry()
{
m_retryModeEnabled = false;
m_retryQueryParameters.clear();
}
// List of default non-URL-encode chars. While URL encoding a string, do not escape any chars in
// this set.
static std::unordered_set<unsigned char> defaultNonUrlEncodeChars;
public:
/**
* @brief Construct an empty URL.
* @brief Decodes \p value by transforming all escaped characters to it's non-encoded value.
*
* @param value URL-encoded string.
* @return std::string with non-URL encoded values.
*/
static std::string Decode(const std::string& value);
/**
* @brief Encodes \p value by escaping characters to the form of %HH where HH are hex digits.
*
* @remark \p doNotEncodeSymbols arg can be used to explicitly ask this function to skip
* characters from encoding. For instance, using this `= -` input would prevent encoding `=`, `
* ` and `-`.
*
* @param value Non URL-encoded string.
* @param doNotEncodeSymbols
* @return std::string
*/
static std::string Encode(const std::string& value, const std::string& doNotEncodeSymbols = "");
/**
* @brief Constructs a new, empty URL object.
*
*/
Url() {}
@ -267,12 +254,8 @@ namespace Azure { namespace Core { namespace Http {
* @brief Set URL host.
*
* @param host URL host.
* @param isHostEncoded `true` if \p host is URL-encoded, `false` otherwise.
*/
void SetHost(const std::string& host, bool isHostEncoded = false)
{
m_host = isHostEncoded ? host : EncodeHost(host);
}
void SetHost(const std::string& encodedHost) { m_host = encodedHost; }
/**
* @brief Set URL port.
@ -285,22 +268,20 @@ namespace Azure { namespace Core { namespace Http {
* @brief Set URL path.
*
* @param path URL path.
* @param isPathEncoded `true` if \p fragment is URL-encoded, `false` otherwise.
*/
void SetPath(const std::string& path, bool isPathEncoded = false)
{
m_encodedPath = isPathEncoded ? path : EncodePath(path);
}
void SetPath(const std::string& encodedPath) { m_encodedPath = encodedPath; }
/**
* @brief Set URL fragment.
* @brief Set the query parameters from an existing query parameter map.
*
* @param fragment URL fragment.
* @param isFragmentEncoded `true` if \p fragment is URL-encoded, `false` otherwise.
* @remark Keys and values in \p queryParameters are expected to be URL-encoded.
*
* @param queryParameters
*/
void SetFragment(const std::string& fragment, bool isFragmentEncoded = false)
void SetQueryParameters(std::map<std::string, std::string> queryParameters)
{
m_fragment = isFragmentEncoded ? fragment : EncodeFragment(fragment);
// creates a copy and discard previous
m_encodedQueryParameters = std::move(queryParameters);
}
// ===== APIs for mutating URL state: ======
@ -309,93 +290,85 @@ namespace Azure { namespace Core { namespace Http {
* @brief Append an element of URL path.
*
* @param path URL path element to append.
* @param isPathEncoded `true` if \p path is URL-encoded, `false` otherwise.
*/
void AppendPath(const std::string& path, bool isPathEncoded = false)
void AppendPath(const std::string& encodedPath)
{
if (!m_encodedPath.empty() && m_encodedPath.back() != '/')
{
m_encodedPath += '/';
}
m_encodedPath += isPathEncoded ? path : EncodePath(path);
m_encodedPath += encodedPath;
}
/**
* @brief Append an HTTP query parameter.
* @brief The value of a query parameter is expected to be non-URL-encoded and, by default, it
* will be encoded before adding to the URL. Use \p isValueEncoded = true when the
* value is already encoded.
*
* @note Overrides previous query parameters.
* @remark A query key can't contain any characters that need to be URL-encoded (per RFC 7230).
* @remark This function overrides the value of existing query parameters.
*
* @param key HTTP query parameter.
* @param value HTTP query parameter value.
* @param isValueEncoded `true` if \p value is URL-encoded, `false` otherwise.
* @param encodedKey Name of the query parameter, already encoded.
* @param encodedValue Value of the query parameter, already encoded.
*/
void AppendQuery(const std::string& key, const std::string& value, bool isValueEncoded = false)
void AppendQueryParameter(const std::string& encodedKey, const std::string& encodedValue)
{
std::string encoded_value = isValueEncoded ? Decode(value) : value;
if (m_retryModeEnabled)
{
m_retryQueryParameters[key] = encoded_value;
}
else
{
m_queryParameters[key] = encoded_value;
}
m_encodedQueryParameters[encodedKey] = encodedValue;
}
/**
* @brief Append a HTTP query.
* @brief Finds the first '?' symbol and parses everything after it as query parameters.
* separated by '&'.
*
* @note All the required HTTP query parts should be URL-encoded.
*
* @param encodedQueries HTTP query.
* @param encodedQueryParameters String containing one or more query parameters.
*/
void AppendQueries(const std::string& encodedQueries);
void AppendQueryParameters(const std::string& encodedQueryParameters);
/**
* @brief Removes a HTTP query parameter.
* @brief Removes an existing query parameter.
*
* @param key HTTP query parameter to remove.
* @param encodedKey The name of the query parameter to be removed.
*/
void RemoveQuery(const std::string& key)
void RemoveQueryParameter(const std::string& encodedKey)
{
m_queryParameters.erase(key);
m_retryQueryParameters.erase(key);
m_encodedQueryParameters.erase(encodedKey);
}
/************** API to read values from Url ***************/
/**
* @brief Get URL host.
*/
std::string GetHost() const { return m_host; }
const std::string& GetHost() const { return m_host; }
/**
* @brief Get URL path.
* @brief Gets the URL path.
*
* @return const std::string&
*/
const std::string& GetPath() const { return m_encodedPath; }
/**
* @brief Get all the query parameters in the URL.
* @brief Provides a copy to the list of query parameters from the URL.
*
* @note Retry parameters have preference and will override any value from the initial query
* parameters.
* @note All the values are URL-encoded.
* @remark The query parameters are URL-encoded.
*
* @return URL query parameters.
* @return const std::map<std::string, std::string>&
*/
const std::map<std::string, std::string> GetQuery() const
std::map<std::string, std::string> GetQueryParameters() const
{
return Details::MergeMaps(m_retryQueryParameters, m_queryParameters);
return m_encodedQueryParameters;
}
/**
* @brief Get relative URL.
* @brief Gets the path and query parameters.
*
* @return std::string The string is URL encoded.
*/
std::string GetRelativeUrl() const;
/**
* @brief Get relative URL.
* @remark All the query parameters are URL-encoded.
* @brief Gets Scheme, host, path and query parameters.
*
* @return std::string The string is URL encoded.
*/
std::string GetAbsoluteUrl() const;
};
@ -428,9 +401,6 @@ namespace Azure { namespace Core { namespace Http {
// adapter will decide chunk size.
int64_t m_uploadChunkSize = 0;
void StartRetry(); // only called by retry policy
void StopRetry(); // only called by retry policy
public:
/**
* @brief Construct an HTTP @request.
@ -549,6 +519,9 @@ namespace Azure { namespace Core { namespace Http {
* @brief Get URL.
*/
Url const& GetUrl() const { return this->m_url; }
// Expected to be called by a Retry policy to reset all headers set after this function was
// previously called
void StartTry();
};
/*

View File

@ -10,6 +10,18 @@
using namespace Azure::Core::Http;
namespace {
// returns left map plus all items in right
// when duplicates, left items are preferred
static std::map<std::string, std::string> MergeMaps(
std::map<std::string, std::string> left,
std::map<std::string, std::string> const& right)
{
left.insert(right.begin(), right.end());
return left;
}
} // namespace
void Request::AddHeader(std::string const& name, std::string const& value)
{
auto headerNameLowerCase = Azure::Core::Details::ToLower(name);
@ -26,18 +38,10 @@ void Request::RemoveHeader(std::string const& name)
this->m_retryHeaders.erase(name);
}
void Request::StartRetry()
void Request::StartTry()
{
this->m_retryModeEnabled = true;
this->m_retryHeaders.clear();
this->m_url.StartRetry();
}
void Request::StopRetry()
{
this->m_retryModeEnabled = false;
this->m_retryHeaders.clear();
this->m_url.StopRetry();
}
HttpMethod Request::GetMethod() const { return this->m_method; }
@ -46,7 +50,7 @@ std::map<std::string, std::string> Request::GetHeaders() const
{
// create map with retry headers which are the most important and we don't want
// to override them with any duplicate header
return Details::MergeMaps(this->m_retryHeaders, this->m_headers);
return MergeMaps(this->m_retryHeaders, this->m_headers);
}
// Writes an HTTP request with RFC 7230 without the body (head line and headers)

View File

@ -134,6 +134,9 @@ std::unique_ptr<RawResponse> Azure::Core::Http::RetryPolicy::Send(
for (RetryNumber attempt = 1;; ++attempt)
{
Delay retryAfter{};
request.StartTry();
// creates a copy of original query parameters from request
auto originalQueryParameters = request.GetUrl().GetQueryParameters();
try
{
auto response = nextHttpPolicy.Send(ctx, request);
@ -142,9 +145,8 @@ std::unique_ptr<RawResponse> Azure::Core::Http::RetryPolicy::Send(
// doesn't need to be retried), then ShouldRetry returns false.
if (!ShouldRetryOnResponse(*response.get(), m_retryOptions, attempt, retryAfter))
{
// If this is the second attempt and StartRetry was called, we need to stop it. Otherwise
// If this is the second attempt and StartTry was called, we need to stop it. Otherwise
// trying to perform same request would use last retry query/headers
request.StopRetry();
return response;
}
}
@ -163,7 +165,6 @@ std::unique_ptr<RawResponse> Azure::Core::Http::RetryPolicy::Send(
}
}
request.StartRetry();
if (auto bodyStream = request.GetBodyStream())
{
bodyStream->Rewind();
@ -186,6 +187,9 @@ std::unique_ptr<RawResponse> Azure::Core::Http::RetryPolicy::Send(
std::this_thread::sleep_for(retryAfter);
}
// Restore the original query parameters before next retry
request.GetUrl().SetQueryParameters(std::move(originalQueryParameters));
ctx.ThrowIfCanceled();
}
}

View File

@ -49,14 +49,9 @@ Url::Url(const std::string& url)
if (pos != url.end() && *pos == '?')
{
auto queryIter = std::find(pos + 1, url.end(), '#');
AppendQueries(std::string(pos + 1, queryIter));
AppendQueryParameters(std::string(pos + 1, queryIter));
pos = queryIter;
}
if (pos != url.end() && *pos == '#')
{
m_fragment = std::string(pos + 1, url.end());
}
}
std::string Url::Decode(const std::string& value)
@ -103,86 +98,20 @@ std::string Url::Decode(const std::string& value)
return decodedValue;
}
static const char* unreserved
= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~";
static const char* subdelimiters = "!$&'()*+,;=";
std::string Url::EncodeHost(const std::string& host)
{
return EncodeImpl(host, [](int c) { return c > 127; });
}
std::string Url::EncodePath(const std::string& path)
{
const static std::vector<bool> shouldEncodeTable = []() {
const std::string pathCharacters
= std::string(unreserved) + std::string(subdelimiters) + "%/:@";
std::vector<bool> ret(256, true);
for (char c : pathCharacters)
{
ret[c] = false;
}
// we also encode % and +
ret['%'] = true;
ret['+'] = true;
return ret;
}();
return EncodeImpl(path, [](int c) { return shouldEncodeTable[c]; });
}
std::string Url::EncodeQuery(const std::string& query)
{
const static std::vector<bool> shouldEncodeTable = []() {
std::string queryCharacters = std::string(unreserved) + std::string(subdelimiters) + "%/:@?";
std::vector<bool> ret(256, true);
for (char c : queryCharacters)
{
ret[c] = false;
}
// we also encode % and +
ret['%'] = true;
ret['+'] = true;
// Surprisingly, '=' also needs to be encoded because Azure Storage server side is so strict.
// We are applying this function to query key and value respectively, so this won't affect
// that = used to separate key and query.
ret['='] = true;
return ret;
}();
return EncodeImpl(query, [](int c) { return shouldEncodeTable[c]; });
}
std::string Url::EncodeFragment(const std::string& fragment)
{
const static std::vector<bool> shouldEncodeTable = []() {
std::string queryCharacters = std::string(unreserved) + std::string(subdelimiters) + "%/:@?";
std::vector<bool> ret(256, true);
for (char c : queryCharacters)
{
ret[c] = false;
}
// we also encode % and +
ret['%'] = true;
ret['+'] = true;
return ret;
}();
return EncodeImpl(fragment, [](int c) { return shouldEncodeTable[c]; });
}
std::string Url::EncodeImpl(const std::string& source, const std::function<bool(int)>& shouldEncode)
std::string Url::Encode(const std::string& value, const std::string& doNotEncodeSymbols)
{
const char* hex = "0123456789ABCDEF";
std::unordered_set<unsigned char> noEncodingSymbolsSet(
doNotEncodeSymbols.begin(), doNotEncodeSymbols.end());
std::string encoded;
for (char c : source)
for (char c : value)
{
unsigned char uc = c;
if (shouldEncode(uc))
// encode if char is not in the default non-encoding set AND if it is NOT in chars to ignore
// from user input
if (defaultNonUrlEncodeChars.find(uc) == defaultNonUrlEncodeChars.end()
&& noEncodingSymbolsSet.find(uc) == noEncodingSymbolsSet.end())
{
encoded += '%';
encoded += hex[(uc >> 4) & 0x0f];
@ -196,7 +125,7 @@ std::string Url::EncodeImpl(const std::string& source, const std::function<bool(
return encoded;
}
void Url::AppendQueries(const std::string& query)
void Url::AppendQueryParameters(const std::string& query)
{
std::string::const_iterator cur = query.begin();
if (cur != query.end() && *cur == '?')
@ -216,14 +145,14 @@ void Url::AppendQueries(const std::string& query)
}
auto value_end = std::find(cur, query.end(), '&');
std::string query_value = Decode(std::string(cur, value_end));
std::string query_value = std::string(cur, value_end);
cur = value_end;
if (cur != query.end())
{
++cur;
}
m_queryParameters[std::move(query_key)] = std::move(query_value);
m_encodedQueryParameters[std::move(query_key)] = std::move(query_value);
}
}
@ -235,20 +164,14 @@ std::string Url::GetRelativeUrl() const
relative_url += m_encodedPath;
}
{
auto queryParameters = m_retryModeEnabled
? Details::MergeMaps(m_retryQueryParameters, m_queryParameters)
: m_queryParameters;
relative_url += '?';
for (const auto& q : queryParameters)
for (const auto& q : m_encodedQueryParameters)
{
relative_url += q.first + '=' + EncodeQuery(q.second) + '&';
relative_url += q.first + '=' + q.second + '&';
}
relative_url.pop_back();
}
if (!m_fragment.empty())
{
relative_url += "#" + m_fragment;
}
return relative_url;
}
@ -271,3 +194,9 @@ std::string Url::GetAbsoluteUrl() const
full_url += GetRelativeUrl();
return full_url;
}
std::unordered_set<unsigned char> Url::defaultNonUrlEncodeChars
= {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '.', '_', '~'};

View File

@ -34,15 +34,15 @@ add_executable (
azure_core_storage_list_containers_sample
)
add_executable (
${TARGET_NAME_STORAGE_REUSE_CONNECTION}
azure_hang
)
#add_executable (
# ${TARGET_NAME_STORAGE_REUSE_CONNECTION}
# azure_hang
#)
target_link_libraries(${TARGET_NAME} PRIVATE azure-core)
target_link_libraries(${TARGET_NAME_STREAM} PRIVATE azure-core)
target_link_libraries(${TARGET_NAME_STORAGE_ISSUE_249} PRIVATE azure-core)
target_link_libraries(${TARGET_NAME_STORAGE_ISSUE_248} PRIVATE azure-core)
target_link_libraries(${TARGET_NAME_STORAGE_REUSE_CONNECTION} PRIVATE azure-core azure::storage::files::datalake azure-storage-common)
#target_link_libraries(${TARGET_NAME_STORAGE_REUSE_CONNECTION} PRIVATE azure-core azure::storage::files::datalake azure-storage-common)
endif()

View File

@ -98,8 +98,8 @@ void doGetRequest(Context const& context, HttpPipeline& pipeline)
request.AddHeader("Host", "httpbin.org");
request.GetUrl().AppendQuery("dynamicArg", "3");
request.GetUrl().AppendQuery("dynamicArg2", "4");
request.GetUrl().AppendQueryParameter("dynamicArg", "3");
request.GetUrl().AppendQueryParameter("dynamicArg2", "4");
auto response = pipeline.Send(context, request);
printStream(context, std::move(response));
@ -155,9 +155,9 @@ void doPutStreamRequest(Context const& context, HttpPipeline& pipeline)
request.AddHeader("Content-Length", std::to_string(StreamSize));
request.GetUrl().AppendQuery("dynamicArg", "1");
request.GetUrl().AppendQuery("dynamicArg2", "1");
request.GetUrl().AppendQuery("dynamicArg3", "1");
request.GetUrl().AppendQueryParameter("dynamicArg", "1");
request.GetUrl().AppendQueryParameter("dynamicArg2", "1");
request.GetUrl().AppendQueryParameter("dynamicArg3", "1");
printStream(context, pipeline.Send(context, request));
}

View File

@ -43,7 +43,7 @@ namespace Azure { namespace Core { namespace Test {
EXPECT_PRED2([](std::string a, std::string b) { return a == b; }, value2->second, "value2");
// now add to retry headers
req.StartRetry();
req.StartTry();
// same headers first, then one new
EXPECT_NO_THROW(req.AddHeader("namE", "retryValue"));
@ -87,7 +87,7 @@ namespace Azure { namespace Core { namespace Test {
{
Http::HttpMethod httpMethod = Http::HttpMethod::Put;
Http::Url url("http://test.com");
EXPECT_NO_THROW(url.AppendQuery("query", "value"));
EXPECT_NO_THROW(url.AppendQueryParameter("query", "value"));
Http::Request req(httpMethod, url);
@ -100,16 +100,16 @@ namespace Azure { namespace Core { namespace Test {
Http::Request req_with_query(httpMethod, url_with_query);
// override if adding same query parameter key that is already in url
EXPECT_NO_THROW(req_with_query.GetUrl().AppendQuery("query", "value"));
EXPECT_NO_THROW(req_with_query.GetUrl().AppendQueryParameter("query", "value"));
EXPECT_PRED2(
[](std::string a, std::string b) { return a == b; },
req_with_query.GetUrl().GetAbsoluteUrl(),
"http://test.com?query=value");
// retry query params testing
req_with_query.StartRetry();
req_with_query.StartTry();
// same query parameter should override previous
EXPECT_NO_THROW(req_with_query.GetUrl().AppendQuery("query", "retryValue"));
EXPECT_NO_THROW(req_with_query.GetUrl().AppendQueryParameter("query", "retryValue"));
EXPECT_TRUE(req_with_query.m_retryModeEnabled);
@ -117,15 +117,40 @@ namespace Azure { namespace Core { namespace Test {
[](std::string a, std::string b) { return a == b; },
req_with_query.GetUrl().GetAbsoluteUrl(),
"http://test.com?query=retryValue");
}
// Stop retry. Request should return original query
req_with_query.StopRetry();
EXPECT_FALSE(req_with_query.m_retryModeEnabled);
TEST(TestHttp, query_parameter_encode_decode)
{
Http::HttpMethod httpMethod = Http::HttpMethod::Put;
Http::Url url("http://test.com");
EXPECT_NO_THROW(url.AppendQueryParameter("query", Http::Url::Encode("va=lue")));
// Default encoder from URL won't encode an equal symbol
EXPECT_PRED2(
[](std::string a, std::string b) { return a == b; },
req_with_query.GetUrl().GetAbsoluteUrl(),
"http://test.com?query=value");
url.GetAbsoluteUrl(),
"http://test.com?query=va%3Dlue");
// Provide symbol to do not encode
EXPECT_NO_THROW(url.AppendQueryParameter("query", Http::Url::Encode("va=lue", "=")));
EXPECT_PRED2(
[](std::string a, std::string b) { return a == b; },
url.GetAbsoluteUrl(),
"http://test.com?query=va=lue");
// Provide more than one extra symbol to be encoded
EXPECT_NO_THROW(url.AppendQueryParameter("query", Http::Url::Encode("va=l u?e", " ?")));
EXPECT_PRED2(
[](std::string a, std::string b) { return a == b; },
url.GetAbsoluteUrl(),
"http://test.com?query=va%3Dl u?e");
// default, encode it all
EXPECT_NO_THROW(url.AppendQueryParameter("query", Http::Url::Encode("va=l u?e")));
EXPECT_PRED2(
[](std::string a, std::string b) { return a == b; },
url.GetAbsoluteUrl(),
"http://test.com?query=va%3Dl%20u%3Fe");
}
TEST(TestHttp, add_path)
@ -140,7 +165,7 @@ namespace Azure { namespace Core { namespace Test {
req.GetUrl().GetAbsoluteUrl(),
"http://test.com/path");
EXPECT_NO_THROW(req.GetUrl().AppendQuery("query", "value"));
EXPECT_NO_THROW(req.GetUrl().AppendQueryParameter("query", "value"));
EXPECT_PRED2(
[](std::string a, std::string b) { return a == b; },
req.GetUrl().GetAbsoluteUrl(),

View File

@ -121,6 +121,8 @@ namespace Azure { namespace Core { namespace Test {
auto expectedResponseBodySize = std::stoull(response->GetHeaders().at("content-length"));
CheckBodyFromBuffer(*response, expectedResponseBodySize);
// Need to init request again, since retry would be on after it is sent
request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Get, host);
// Add a header and send again. RawResponse should return that header in the body
request.AddHeader("123", "456");
response = pipeline.Send(context, request);
@ -268,6 +270,7 @@ namespace Azure { namespace Core { namespace Test {
auto expectedResponseBodySize = std::stoull(response->GetHeaders().at("content-length"));
CheckBodyFromStream(*response, expectedResponseBodySize);
request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Get, host, true);
// Add a header and send again. Response should return that header in the body
request.AddHeader("123", "456");
response = pipeline.Send(context, request);

View File

@ -8,6 +8,7 @@
#include "azure/core/http/pipeline.hpp"
#include "azure/core/nullable.hpp"
#include "azure/core/response.hpp"
#include "azure/storage/common/crypt.hpp"
#include "azure/storage/common/storage_common.hpp"
#include "azure/storage/common/storage_error.hpp"
#include "azure/storage/common/xml_wrapper.hpp"
@ -1707,26 +1708,31 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("comp", "list");
request.GetUrl().AppendQueryParameter("comp", "list");
if (options.Prefix.HasValue())
{
request.GetUrl().AppendQuery("prefix", options.Prefix.GetValue());
request.GetUrl().AppendQueryParameter(
"prefix", Details::UrlEncodeQueryParameter(options.Prefix.GetValue()));
}
if (options.Marker.HasValue())
{
request.GetUrl().AppendQuery("marker", options.Marker.GetValue());
request.GetUrl().AppendQueryParameter(
"marker", Details::UrlEncodeQueryParameter(options.Marker.GetValue()));
}
if (options.MaxResults.HasValue())
{
request.GetUrl().AppendQuery("maxresults", std::to_string(options.MaxResults.GetValue()));
request.GetUrl().AppendQueryParameter(
"maxresults", std::to_string(options.MaxResults.GetValue()));
}
std::string list_blob_containers_include_item
= ListBlobContainersIncludeItemToString(options.Include);
if (!list_blob_containers_include_item.empty())
{
request.GetUrl().AppendQuery("include", list_blob_containers_include_item);
request.GetUrl().AppendQueryParameter(
"include", Details::UrlEncodeQueryParameter(list_blob_containers_include_item));
}
auto pHttpResponse = pipeline.Send(context, request);
Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse;
@ -1774,12 +1780,13 @@ namespace Azure { namespace Storage { namespace Blobs {
auto request = Azure::Core::Http::Request(
Azure::Core::Http::HttpMethod::Post, url, &xml_body_stream);
request.AddHeader("Content-Length", std::to_string(xml_body_stream.Length()));
request.GetUrl().AppendQuery("restype", "service");
request.GetUrl().AppendQuery("comp", "userdelegationkey");
request.GetUrl().AppendQueryParameter("restype", "service");
request.GetUrl().AppendQueryParameter("comp", "userdelegationkey");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
auto pHttpResponse = pipeline.Send(context, request);
Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse;
@ -1814,12 +1821,13 @@ namespace Azure { namespace Storage { namespace Blobs {
{
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Get, url);
request.GetUrl().AppendQuery("restype", "service");
request.GetUrl().AppendQuery("comp", "properties");
request.GetUrl().AppendQueryParameter("restype", "service");
request.GetUrl().AppendQueryParameter("comp", "properties");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
auto pHttpResponse = pipeline.Send(context, request);
Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse;
@ -1866,12 +1874,13 @@ namespace Azure { namespace Storage { namespace Blobs {
auto request
= Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url, &xml_body_stream);
request.AddHeader("Content-Length", std::to_string(xml_body_stream.Length()));
request.GetUrl().AppendQuery("restype", "service");
request.GetUrl().AppendQuery("comp", "properties");
request.GetUrl().AppendQueryParameter("restype", "service");
request.GetUrl().AppendQueryParameter("comp", "properties");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
auto pHttpResponse = pipeline.Send(context, request);
Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse;
@ -1900,12 +1909,13 @@ namespace Azure { namespace Storage { namespace Blobs {
{
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Head, url);
request.GetUrl().AppendQuery("restype", "account");
request.GetUrl().AppendQuery("comp", "properties");
request.GetUrl().AppendQueryParameter("restype", "account");
request.GetUrl().AppendQueryParameter("comp", "properties");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
auto pHttpResponse = pipeline.Send(context, request);
Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse;
@ -1937,12 +1947,13 @@ namespace Azure { namespace Storage { namespace Blobs {
{
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Get, url);
request.GetUrl().AppendQuery("restype", "service");
request.GetUrl().AppendQuery("comp", "stats");
request.GetUrl().AppendQueryParameter("restype", "service");
request.GetUrl().AppendQueryParameter("comp", "stats");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
auto pHttpResponse = pipeline.Send(context, request);
Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse;
@ -1983,17 +1994,21 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("comp", "blobs");
request.GetUrl().AppendQuery("where", options.Where);
request.GetUrl().AppendQueryParameter("comp", "blobs");
request.GetUrl().AppendQueryParameter(
"where", Details::UrlEncodeQueryParameter(options.Where));
if (options.Marker.HasValue())
{
request.GetUrl().AppendQuery("marker", options.Marker.GetValue());
request.GetUrl().AppendQueryParameter(
"marker", Details::UrlEncodeQueryParameter(options.Marker.GetValue()));
}
if (options.MaxResults.HasValue())
{
request.GetUrl().AppendQuery("maxresults", std::to_string(options.MaxResults.GetValue()));
request.GetUrl().AppendQueryParameter(
"maxresults", std::to_string(options.MaxResults.GetValue()));
}
auto pHttpResponse = pipeline.Send(context, request);
Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse;
@ -3448,11 +3463,12 @@ namespace Azure { namespace Storage { namespace Blobs {
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader("Content-Length", "0");
request.GetUrl().AppendQuery("restype", "container");
request.GetUrl().AppendQueryParameter("restype", "container");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
std::set<std::string> metadataKeys;
for (const auto& pair : options.Metadata)
@ -3516,11 +3532,12 @@ namespace Azure { namespace Storage { namespace Blobs {
{
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Delete, url);
request.GetUrl().AppendQuery("restype", "container");
request.GetUrl().AppendQueryParameter("restype", "container");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
if (options.LeaseId.HasValue())
{
@ -3564,12 +3581,13 @@ namespace Azure { namespace Storage { namespace Blobs {
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader("Content-Length", "0");
request.GetUrl().AppendQuery("restype", "container");
request.GetUrl().AppendQuery("comp", "undelete");
request.GetUrl().AppendQueryParameter("restype", "container");
request.GetUrl().AppendQueryParameter("comp", "undelete");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.AddHeader("x-ms-deleted-container-name", options.DeletedContainerName);
request.AddHeader("x-ms-deleted-container-version", options.DeletedContainerVersion);
@ -3601,11 +3619,12 @@ namespace Azure { namespace Storage { namespace Blobs {
{
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Head, url);
request.GetUrl().AppendQuery("restype", "container");
request.GetUrl().AppendQueryParameter("restype", "container");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
if (options.LeaseId.HasValue())
{
@ -3673,12 +3692,13 @@ namespace Azure { namespace Storage { namespace Blobs {
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader("Content-Length", "0");
request.GetUrl().AppendQuery("restype", "container");
request.GetUrl().AppendQuery("comp", "metadata");
request.GetUrl().AppendQueryParameter("restype", "container");
request.GetUrl().AppendQueryParameter("comp", "metadata");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
std::set<std::string> metadataKeys;
for (const auto& pair : options.Metadata)
@ -3738,26 +3758,31 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("restype", "container");
request.GetUrl().AppendQuery("comp", "list");
request.GetUrl().AppendQueryParameter("restype", "container");
request.GetUrl().AppendQueryParameter("comp", "list");
if (options.Prefix.HasValue())
{
request.GetUrl().AppendQuery("prefix", options.Prefix.GetValue());
request.GetUrl().AppendQueryParameter(
"prefix", Details::UrlEncodeQueryParameter(options.Prefix.GetValue()));
}
if (options.Marker.HasValue())
{
request.GetUrl().AppendQuery("marker", options.Marker.GetValue());
request.GetUrl().AppendQueryParameter(
"marker", Details::UrlEncodeQueryParameter(options.Marker.GetValue()));
}
if (options.MaxResults.HasValue())
{
request.GetUrl().AppendQuery("maxresults", std::to_string(options.MaxResults.GetValue()));
request.GetUrl().AppendQueryParameter(
"maxresults", std::to_string(options.MaxResults.GetValue()));
}
std::string list_blobs_include_item = ListBlobsIncludeItemToString(options.Include);
if (!list_blobs_include_item.empty())
{
request.GetUrl().AppendQuery("include", list_blobs_include_item);
request.GetUrl().AppendQueryParameter(
"include", Details::UrlEncodeQueryParameter(list_blobs_include_item));
}
auto pHttpResponse = pipeline.Send(context, request);
Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse;
@ -3800,30 +3825,36 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("restype", "container");
request.GetUrl().AppendQuery("comp", "list");
request.GetUrl().AppendQueryParameter("restype", "container");
request.GetUrl().AppendQueryParameter("comp", "list");
if (options.Prefix.HasValue())
{
request.GetUrl().AppendQuery("prefix", options.Prefix.GetValue());
request.GetUrl().AppendQueryParameter(
"prefix", Details::UrlEncodeQueryParameter(options.Prefix.GetValue()));
}
if (options.Delimiter.HasValue())
{
request.GetUrl().AppendQuery("delimiter", options.Delimiter.GetValue());
request.GetUrl().AppendQueryParameter(
"delimiter", Details::UrlEncodeQueryParameter(options.Delimiter.GetValue()));
}
if (options.Marker.HasValue())
{
request.GetUrl().AppendQuery("marker", options.Marker.GetValue());
request.GetUrl().AppendQueryParameter(
"marker", Details::UrlEncodeQueryParameter(options.Marker.GetValue()));
}
if (options.MaxResults.HasValue())
{
request.GetUrl().AppendQuery("maxresults", std::to_string(options.MaxResults.GetValue()));
request.GetUrl().AppendQueryParameter(
"maxresults", std::to_string(options.MaxResults.GetValue()));
}
std::string list_blobs_include_item = ListBlobsIncludeItemToString(options.Include);
if (!list_blobs_include_item.empty())
{
request.GetUrl().AppendQuery("include", list_blobs_include_item);
request.GetUrl().AppendQueryParameter(
"include", Details::UrlEncodeQueryParameter(list_blobs_include_item));
}
auto pHttpResponse = pipeline.Send(context, request);
Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse;
@ -3862,10 +3893,11 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("restype", "container");
request.GetUrl().AppendQuery("comp", "acl");
request.GetUrl().AppendQueryParameter("restype", "container");
request.GetUrl().AppendQueryParameter("comp", "acl");
auto pHttpResponse = pipeline.Send(context, request);
Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse;
GetContainerAccessPolicyResult response;
@ -3922,10 +3954,11 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("restype", "container");
request.GetUrl().AppendQuery("comp", "acl");
request.GetUrl().AppendQueryParameter("restype", "container");
request.GetUrl().AppendQueryParameter("comp", "acl");
if (options.AccessType.HasValue())
{
request.AddHeader(
@ -3980,10 +4013,11 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("restype", "container");
request.GetUrl().AppendQuery("comp", "lease");
request.GetUrl().AppendQueryParameter("restype", "container");
request.GetUrl().AppendQueryParameter("comp", "lease");
request.AddHeader("x-ms-lease-action", "acquire");
request.AddHeader("x-ms-lease-duration", std::to_string(options.LeaseDuration));
if (options.ProposedLeaseId.HasValue())
@ -4035,10 +4069,11 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("restype", "container");
request.GetUrl().AppendQuery("comp", "lease");
request.GetUrl().AppendQueryParameter("restype", "container");
request.GetUrl().AppendQueryParameter("comp", "lease");
request.AddHeader("x-ms-lease-action", "renew");
request.AddHeader("x-ms-lease-id", options.LeaseId);
if (options.IfModifiedSince.HasValue())
@ -4087,10 +4122,11 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("restype", "container");
request.GetUrl().AppendQuery("comp", "lease");
request.GetUrl().AppendQueryParameter("restype", "container");
request.GetUrl().AppendQueryParameter("comp", "lease");
request.AddHeader("x-ms-lease-action", "change");
request.AddHeader("x-ms-lease-id", options.LeaseId);
request.AddHeader("x-ms-proposed-lease-id", options.ProposedLeaseId);
@ -4139,10 +4175,11 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("restype", "container");
request.GetUrl().AppendQuery("comp", "lease");
request.GetUrl().AppendQueryParameter("restype", "container");
request.GetUrl().AppendQueryParameter("comp", "lease");
request.AddHeader("x-ms-lease-action", "release");
request.AddHeader("x-ms-lease-id", options.LeaseId);
if (options.IfModifiedSince.HasValue())
@ -4189,10 +4226,11 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("restype", "container");
request.GetUrl().AppendQuery("comp", "lease");
request.GetUrl().AppendQueryParameter("restype", "container");
request.GetUrl().AppendQueryParameter("comp", "lease");
request.AddHeader("x-ms-lease-action", "break");
if (options.BreakPeriod.HasValue())
{
@ -5156,7 +5194,8 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
if (options.Range.HasValue())
{
@ -5424,7 +5463,8 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
if (options.DeleteSnapshots.HasValue())
{
@ -5507,9 +5547,10 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("comp", "expiry");
request.GetUrl().AppendQueryParameter("comp", "expiry");
request.AddHeader(
"x-ms-expiry-option", ScheduleBlobExpiryOriginTypeToString(options.ExpiryOrigin));
if (options.ExpiryTime.HasValue())
@ -5547,9 +5588,10 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("comp", "undelete");
request.GetUrl().AppendQueryParameter("comp", "undelete");
auto pHttpResponse = pipeline.Send(context, request);
Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse;
UndeleteBlobResult response;
@ -5589,7 +5631,8 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
if (options.EncryptionKey.HasValue())
{
@ -5873,11 +5916,12 @@ namespace Azure { namespace Storage { namespace Blobs {
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader("Content-Length", "0");
request.GetUrl().AppendQuery("comp", "properties");
request.GetUrl().AppendQueryParameter("comp", "properties");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
if (!options.HttpHeaders.ContentType.empty())
{
@ -5975,11 +6019,12 @@ namespace Azure { namespace Storage { namespace Blobs {
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader("Content-Length", "0");
request.GetUrl().AppendQuery("comp", "metadata");
request.GetUrl().AppendQueryParameter("comp", "metadata");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
std::set<std::string> metadataKeys;
for (const auto& pair : options.Metadata)
@ -6068,11 +6113,12 @@ namespace Azure { namespace Storage { namespace Blobs {
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader("Content-Length", "0");
request.GetUrl().AppendQuery("comp", "tier");
request.GetUrl().AppendQueryParameter("comp", "tier");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.AddHeader("x-ms-access-tier", AccessTierToString(options.Tier));
if (options.RehydratePriority.HasValue())
@ -6151,7 +6197,8 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
std::set<std::string> metadataKeys;
for (const auto& pair : options.Metadata)
@ -6276,10 +6323,12 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("comp", "copy");
request.GetUrl().AppendQuery("copyid", options.CopyId);
request.GetUrl().AppendQueryParameter("comp", "copy");
request.GetUrl().AppendQueryParameter(
"copyid", Details::UrlEncodeQueryParameter(options.CopyId));
request.AddHeader("x-ms-copy-action", "abort");
if (options.LeaseId.HasValue())
{
@ -6324,11 +6373,12 @@ namespace Azure { namespace Storage { namespace Blobs {
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader("Content-Length", "0");
request.GetUrl().AppendQuery("comp", "snapshot");
request.GetUrl().AppendQueryParameter("comp", "snapshot");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
if (options.EncryptionKey.HasValue())
{
@ -6443,9 +6493,10 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("comp", "tags");
request.GetUrl().AppendQueryParameter("comp", "tags");
if (options.IfTags.HasValue())
{
request.AddHeader("x-ms-if-tags", options.IfTags.GetValue());
@ -6499,9 +6550,10 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("comp", "tags");
request.GetUrl().AppendQueryParameter("comp", "tags");
request.AddHeader("Content-Type", "application/xml; charset=UTF-8");
if (options.IfTags.HasValue())
{
@ -6545,9 +6597,10 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("comp", "lease");
request.GetUrl().AppendQueryParameter("comp", "lease");
request.AddHeader("x-ms-lease-action", "acquire");
request.AddHeader("x-ms-lease-duration", std::to_string(options.LeaseDuration));
if (options.ProposedLeaseId.HasValue())
@ -6614,9 +6667,10 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("comp", "lease");
request.GetUrl().AppendQueryParameter("comp", "lease");
request.AddHeader("x-ms-lease-action", "renew");
request.AddHeader("x-ms-lease-id", options.LeaseId);
if (options.IfModifiedSince.HasValue())
@ -6680,9 +6734,10 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("comp", "lease");
request.GetUrl().AppendQueryParameter("comp", "lease");
request.AddHeader("x-ms-lease-action", "change");
request.AddHeader("x-ms-lease-id", options.LeaseId);
request.AddHeader("x-ms-proposed-lease-id", options.ProposedLeaseId);
@ -6746,9 +6801,10 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("comp", "lease");
request.GetUrl().AppendQueryParameter("comp", "lease");
request.AddHeader("x-ms-lease-action", "release");
request.AddHeader("x-ms-lease-id", options.LeaseId);
if (options.IfModifiedSince.HasValue())
@ -6816,9 +6872,10 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.GetUrl().AppendQuery("comp", "lease");
request.GetUrl().AppendQueryParameter("comp", "lease");
request.AddHeader("x-ms-lease-action", "break");
if (options.BreakPeriod.HasValue())
{
@ -7026,7 +7083,8 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
if (options.EncryptionKey.HasValue())
{
@ -7198,12 +7256,14 @@ namespace Azure { namespace Storage { namespace Blobs {
auto request
= Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url, requestBody);
request.AddHeader("Content-Length", std::to_string(requestBody->Length()));
request.GetUrl().AppendQuery("comp", "block");
request.GetUrl().AppendQuery("blockid", options.BlockId);
request.GetUrl().AppendQueryParameter("comp", "block");
request.GetUrl().AppendQueryParameter(
"blockid", Details::UrlEncodeQueryParameter(options.BlockId));
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
if (options.TransactionalContentMd5.HasValue())
{
@ -7308,12 +7368,14 @@ namespace Azure { namespace Storage { namespace Blobs {
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader("Content-Length", "0");
request.GetUrl().AppendQuery("comp", "block");
request.GetUrl().AppendQuery("blockid", options.BlockId);
request.GetUrl().AppendQueryParameter("comp", "block");
request.GetUrl().AppendQueryParameter(
"blockid", Details::UrlEncodeQueryParameter(options.BlockId));
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.AddHeader("x-ms-copy-source", options.SourceUri);
if (options.SourceRange.HasValue())
@ -7463,11 +7525,12 @@ namespace Azure { namespace Storage { namespace Blobs {
auto request
= Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url, &xml_body_stream);
request.AddHeader("Content-Length", std::to_string(xml_body_stream.Length()));
request.GetUrl().AppendQuery("comp", "blocklist");
request.GetUrl().AppendQueryParameter("comp", "blocklist");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
if (!options.HttpHeaders.ContentType.empty())
{
@ -7609,17 +7672,19 @@ namespace Azure { namespace Storage { namespace Blobs {
{
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Get, url);
request.GetUrl().AppendQuery("comp", "blocklist");
request.GetUrl().AppendQueryParameter("comp", "blocklist");
if (options.ListType.HasValue())
{
std::string block_list_type_option
= BlockListTypeOptionToString(options.ListType.GetValue());
request.GetUrl().AppendQuery("blocklisttype", block_list_type_option);
request.GetUrl().AppendQueryParameter(
"blocklisttype", Details::UrlEncodeQueryParameter(block_list_type_option));
}
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
if (options.LeaseId.HasValue())
{
@ -7835,7 +7900,8 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
if (!options.HttpHeaders.ContentType.empty())
{
@ -8000,11 +8066,12 @@ namespace Azure { namespace Storage { namespace Blobs {
auto request
= Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url, requestBody);
request.AddHeader("Content-Length", std::to_string(requestBody->Length()));
request.GetUrl().AppendQuery("comp", "page");
request.GetUrl().AppendQueryParameter("comp", "page");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.AddHeader(
"x-ms-range",
@ -8160,11 +8227,12 @@ namespace Azure { namespace Storage { namespace Blobs {
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader("Content-Length", "0");
request.GetUrl().AppendQuery("comp", "page");
request.GetUrl().AppendQueryParameter("comp", "page");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.AddHeader(
"x-ms-range",
@ -8322,11 +8390,12 @@ namespace Azure { namespace Storage { namespace Blobs {
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader("Content-Length", "0");
request.GetUrl().AppendQuery("comp", "page");
request.GetUrl().AppendQueryParameter("comp", "page");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.AddHeader(
"x-ms-range",
@ -8457,11 +8526,12 @@ namespace Azure { namespace Storage { namespace Blobs {
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader("Content-Length", "0");
request.GetUrl().AppendQuery("comp", "properties");
request.GetUrl().AppendQueryParameter("comp", "properties");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.AddHeader("x-ms-blob-content-length", std::to_string(options.BlobContentLength));
if (options.LeaseId.HasValue())
@ -8564,15 +8634,18 @@ namespace Azure { namespace Storage { namespace Blobs {
{
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Get, url);
request.GetUrl().AppendQuery("comp", "pagelist");
request.GetUrl().AppendQueryParameter("comp", "pagelist");
if (options.PreviousSnapshot.HasValue())
{
request.GetUrl().AppendQuery("prevsnapshot", options.PreviousSnapshot.GetValue());
request.GetUrl().AppendQueryParameter(
"prevsnapshot",
Details::UrlEncodeQueryParameter(options.PreviousSnapshot.GetValue()));
}
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
if (options.Range.HasValue())
{
@ -8661,11 +8734,12 @@ namespace Azure { namespace Storage { namespace Blobs {
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader("Content-Length", "0");
request.GetUrl().AppendQuery("comp", "incrementalcopy");
request.GetUrl().AppendQueryParameter("comp", "incrementalcopy");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.AddHeader("x-ms-copy-source", options.CopySource);
if (options.IfModifiedSince.HasValue())
@ -8911,7 +8985,8 @@ namespace Azure { namespace Storage { namespace Blobs {
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
if (!options.HttpHeaders.ContentType.empty())
{
@ -9064,11 +9139,12 @@ namespace Azure { namespace Storage { namespace Blobs {
auto request
= Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url, requestBody);
request.AddHeader("Content-Length", std::to_string(requestBody->Length()));
request.GetUrl().AppendQuery("comp", "appendblock");
request.GetUrl().AppendQueryParameter("comp", "appendblock");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
if (options.TransactionalContentMd5.HasValue())
{
@ -9210,11 +9286,12 @@ namespace Azure { namespace Storage { namespace Blobs {
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader("Content-Length", "0");
request.GetUrl().AppendQuery("comp", "appendblock");
request.GetUrl().AppendQueryParameter("comp", "appendblock");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.AddHeader("x-ms-copy-source", options.SourceUri);
if (options.SourceRange.HasValue())
@ -9364,11 +9441,12 @@ namespace Azure { namespace Storage { namespace Blobs {
unused(options);
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader("Content-Length", "0");
request.GetUrl().AppendQuery("comp", "seal");
request.GetUrl().AppendQueryParameter("comp", "seal");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
if (options.LeaseId.HasValue())
{
@ -9437,11 +9515,12 @@ namespace Azure { namespace Storage { namespace Blobs {
auto request
= Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Post, url, requestBody);
request.AddHeader("Content-Length", std::to_string(requestBody->Length()));
request.GetUrl().AppendQuery("comp", "batch");
request.GetUrl().AppendQueryParameter("comp", "batch");
request.AddHeader("x-ms-version", c_ApiVersion);
if (options.Timeout.HasValue())
{
request.GetUrl().AppendQuery("timeout", std::to_string(options.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
"timeout", std::to_string(options.Timeout.GetValue()));
}
request.AddHeader("Content-Type", options.ContentType);
auto pHttpResponse = pipeline.Send(context, request);

View File

@ -49,11 +49,12 @@ namespace Azure { namespace Storage { namespace Blobs {
AppendBlobClient newClient(*this);
if (snapshot.empty())
{
newClient.m_blobUrl.RemoveQuery(Details::c_HttpQuerySnapshot);
newClient.m_blobUrl.RemoveQueryParameter(Details::c_HttpQuerySnapshot);
}
else
{
newClient.m_blobUrl.AppendQuery(Details::c_HttpQuerySnapshot, snapshot);
newClient.m_blobUrl.AppendQueryParameter(
Details::c_HttpQuerySnapshot, Details::UrlEncodeQueryParameter(snapshot));
}
return newClient;
}
@ -63,11 +64,12 @@ namespace Azure { namespace Storage { namespace Blobs {
AppendBlobClient newClient(*this);
if (versionId.empty())
{
newClient.m_blobUrl.RemoveQuery(Details::c_HttpQueryVersionId);
newClient.m_blobUrl.RemoveQueryParameter(Details::c_HttpQueryVersionId);
}
else
{
newClient.m_blobUrl.AppendQuery(Details::c_HttpQueryVersionId, versionId);
newClient.m_blobUrl.AppendQueryParameter(
Details::c_HttpQueryVersionId, Details::UrlEncodeQueryParameter(versionId));
}
return newClient;
}

View File

@ -128,11 +128,12 @@ namespace Azure { namespace Storage { namespace Blobs {
BlobClient newClient(*this);
if (snapshot.empty())
{
newClient.m_blobUrl.RemoveQuery(Details::c_HttpQuerySnapshot);
newClient.m_blobUrl.RemoveQueryParameter(Details::c_HttpQuerySnapshot);
}
else
{
newClient.m_blobUrl.AppendQuery(Details::c_HttpQuerySnapshot, snapshot);
newClient.m_blobUrl.AppendQueryParameter(
Details::c_HttpQuerySnapshot, Details::UrlEncodeQueryParameter(snapshot));
}
return newClient;
}
@ -142,11 +143,12 @@ namespace Azure { namespace Storage { namespace Blobs {
BlobClient newClient(*this);
if (versionId.empty())
{
newClient.m_blobUrl.RemoveQuery(Details::c_HttpQueryVersionId);
newClient.m_blobUrl.RemoveQueryParameter(Details::c_HttpQueryVersionId);
}
else
{
newClient.m_blobUrl.AppendQuery(Details::c_HttpQueryVersionId, versionId);
newClient.m_blobUrl.AppendQueryParameter(
Details::c_HttpQueryVersionId, Details::UrlEncodeQueryParameter(versionId));
}
return newClient;
}

View File

@ -138,49 +138,49 @@ namespace Azure { namespace Storage { namespace Blobs {
= Base64Encode(Details::HmacSha256(stringToSign, Base64Decode(credential.GetAccountKey())));
Azure::Core::Http::Url builder;
builder.AppendQuery("sv", Version);
builder.AppendQuery("spr", protocol);
builder.AppendQueryParameter("sv", Details::UrlEncodeQueryParameter(Version));
builder.AppendQueryParameter("spr", Details::UrlEncodeQueryParameter(protocol));
if (StartsOn.HasValue())
{
builder.AppendQuery("st", StartsOn.GetValue());
builder.AppendQueryParameter("st", Details::UrlEncodeQueryParameter(StartsOn.GetValue()));
}
if (!ExpiresOn.empty())
{
builder.AppendQuery("se", ExpiresOn);
builder.AppendQueryParameter("se", Details::UrlEncodeQueryParameter(ExpiresOn));
}
if (IPRange.HasValue())
{
builder.AppendQuery("sip", IPRange.GetValue());
builder.AppendQueryParameter("sip", Details::UrlEncodeQueryParameter(IPRange.GetValue()));
}
if (!Identifier.empty())
{
builder.AppendQuery("si", Identifier);
builder.AppendQueryParameter("si", Details::UrlEncodeQueryParameter(Identifier));
}
builder.AppendQuery("sr", resource);
builder.AppendQueryParameter("sr", Details::UrlEncodeQueryParameter(resource));
if (!Permissions.empty())
{
builder.AppendQuery("sp", Permissions);
builder.AppendQueryParameter("sp", Details::UrlEncodeQueryParameter(Permissions));
}
builder.AppendQuery("sig", signature);
builder.AppendQueryParameter("sig", Details::UrlEncodeQueryParameter(signature));
if (!CacheControl.empty())
{
builder.AppendQuery("rscc", CacheControl);
builder.AppendQueryParameter("rscc", Details::UrlEncodeQueryParameter(CacheControl));
}
if (!ContentDisposition.empty())
{
builder.AppendQuery("rscd", ContentDisposition);
builder.AppendQueryParameter("rscd", Details::UrlEncodeQueryParameter(ContentDisposition));
}
if (!ContentEncoding.empty())
{
builder.AppendQuery("rsce", ContentEncoding);
builder.AppendQueryParameter("rsce", Details::UrlEncodeQueryParameter(ContentEncoding));
}
if (!ContentLanguage.empty())
{
builder.AppendQuery("rscl", ContentLanguage);
builder.AppendQueryParameter("rscl", Details::UrlEncodeQueryParameter(ContentLanguage));
}
if (!ContentType.empty())
{
builder.AppendQuery("rsct", ContentType);
builder.AppendQueryParameter("rsct", Details::UrlEncodeQueryParameter(ContentType));
}
return builder.GetAbsoluteUrl();
@ -222,46 +222,52 @@ namespace Azure { namespace Storage { namespace Blobs {
= Base64Encode(Details::HmacSha256(stringToSign, Base64Decode(userDelegationKey.Value)));
Azure::Core::Http::Url builder;
builder.AppendQuery("sv", Version);
builder.AppendQuery("sr", resource);
builder.AppendQueryParameter("sv", Details::UrlEncodeQueryParameter(Version));
builder.AppendQueryParameter("sr", Details::UrlEncodeQueryParameter(resource));
if (StartsOn.HasValue())
{
builder.AppendQuery("st", StartsOn.GetValue());
builder.AppendQueryParameter("st", Details::UrlEncodeQueryParameter(StartsOn.GetValue()));
}
builder.AppendQuery("se", ExpiresOn);
builder.AppendQuery("sp", Permissions);
builder.AppendQueryParameter("se", Details::UrlEncodeQueryParameter(ExpiresOn));
builder.AppendQueryParameter("sp", Details::UrlEncodeQueryParameter(Permissions));
if (IPRange.HasValue())
{
builder.AppendQuery("sip", IPRange.GetValue());
builder.AppendQueryParameter("sip", Details::UrlEncodeQueryParameter(IPRange.GetValue()));
}
builder.AppendQuery("spr", protocol);
builder.AppendQuery("skoid", userDelegationKey.SignedObjectId);
builder.AppendQuery("sktid", userDelegationKey.SignedTenantId);
builder.AppendQuery("skt", userDelegationKey.SignedStartsOn);
builder.AppendQuery("ske", userDelegationKey.SignedExpiresOn);
builder.AppendQuery("sks", userDelegationKey.SignedService);
builder.AppendQuery("skv", userDelegationKey.SignedVersion);
builder.AppendQueryParameter("spr", Details::UrlEncodeQueryParameter(protocol));
builder.AppendQueryParameter(
"skoid", Details::UrlEncodeQueryParameter(userDelegationKey.SignedObjectId));
builder.AppendQueryParameter(
"sktid", Details::UrlEncodeQueryParameter(userDelegationKey.SignedTenantId));
builder.AppendQueryParameter(
"skt", Details::UrlEncodeQueryParameter(userDelegationKey.SignedStartsOn));
builder.AppendQueryParameter(
"ske", Details::UrlEncodeQueryParameter(userDelegationKey.SignedExpiresOn));
builder.AppendQueryParameter(
"sks", Details::UrlEncodeQueryParameter(userDelegationKey.SignedService));
builder.AppendQueryParameter(
"skv", Details::UrlEncodeQueryParameter(userDelegationKey.SignedVersion));
if (!CacheControl.empty())
{
builder.AppendQuery("rscc", CacheControl);
builder.AppendQueryParameter("rscc", Details::UrlEncodeQueryParameter(CacheControl));
}
if (!ContentDisposition.empty())
{
builder.AppendQuery("rscd", ContentDisposition);
builder.AppendQueryParameter("rscd", Details::UrlEncodeQueryParameter(ContentDisposition));
}
if (!ContentEncoding.empty())
{
builder.AppendQuery("rsce", ContentEncoding);
builder.AppendQueryParameter("rsce", Details::UrlEncodeQueryParameter(ContentEncoding));
}
if (!ContentLanguage.empty())
{
builder.AppendQuery("rscl", ContentLanguage);
builder.AppendQueryParameter("rscl", Details::UrlEncodeQueryParameter(ContentLanguage));
}
if (!ContentType.empty())
{
builder.AppendQuery("rsct", ContentType);
builder.AppendQueryParameter("rsct", Details::UrlEncodeQueryParameter(ContentType));
}
builder.AppendQuery("sig", signature);
builder.AppendQueryParameter("sig", Details::UrlEncodeQueryParameter(signature));
return builder.GetAbsoluteUrl();
}

View File

@ -52,11 +52,12 @@ namespace Azure { namespace Storage { namespace Blobs {
BlockBlobClient newClient(*this);
if (snapshot.empty())
{
newClient.m_blobUrl.RemoveQuery(Details::c_HttpQuerySnapshot);
newClient.m_blobUrl.RemoveQueryParameter(Details::c_HttpQuerySnapshot);
}
else
{
newClient.m_blobUrl.AppendQuery(Details::c_HttpQuerySnapshot, snapshot);
newClient.m_blobUrl.AppendQueryParameter(
Details::c_HttpQuerySnapshot, Details::UrlEncodeQueryParameter(snapshot));
}
return newClient;
}
@ -66,11 +67,12 @@ namespace Azure { namespace Storage { namespace Blobs {
BlockBlobClient newClient(*this);
if (versionId.empty())
{
newClient.m_blobUrl.RemoveQuery(Details::c_HttpQueryVersionId);
newClient.m_blobUrl.RemoveQueryParameter(Details::c_HttpQueryVersionId);
}
else
{
newClient.m_blobUrl.AppendQuery(Details::c_HttpQueryVersionId, versionId);
newClient.m_blobUrl.AppendQueryParameter(
Details::c_HttpQueryVersionId, Details::UrlEncodeQueryParameter(versionId));
}
return newClient;
}

View File

@ -49,11 +49,12 @@ namespace Azure { namespace Storage { namespace Blobs {
PageBlobClient newClient(*this);
if (snapshot.empty())
{
newClient.m_blobUrl.RemoveQuery(Details::c_HttpQuerySnapshot);
newClient.m_blobUrl.RemoveQueryParameter(Details::c_HttpQuerySnapshot);
}
else
{
newClient.m_blobUrl.AppendQuery(Details::c_HttpQuerySnapshot, snapshot);
newClient.m_blobUrl.AppendQueryParameter(
Details::c_HttpQuerySnapshot, Details::UrlEncodeQueryParameter(snapshot));
}
return newClient;
}
@ -63,11 +64,12 @@ namespace Azure { namespace Storage { namespace Blobs {
PageBlobClient newClient(*this);
if (versionId.empty())
{
newClient.m_blobUrl.RemoveQuery(Details::c_HttpQueryVersionId);
newClient.m_blobUrl.RemoveQueryParameter(Details::c_HttpQueryVersionId);
}
else
{
newClient.m_blobUrl.AppendQuery(Details::c_HttpQueryVersionId, versionId);
newClient.m_blobUrl.AppendQueryParameter(
Details::c_HttpQueryVersionId, Details::UrlEncodeQueryParameter(versionId));
}
return newClient;
}

View File

@ -430,7 +430,7 @@ namespace Azure { namespace Storage { namespace Test {
auto verify_blob_snapshot_read = [&](const std::string sas) {
Azure::Core::Http::Url blobSnapshotUriWithSas(blobSnapshotUri);
blobSnapshotUriWithSas.AppendQueries(sas);
blobSnapshotUriWithSas.AppendQueryParameters(sas);
auto blobSnapshotClient = Blobs::AppendBlobClient(blobSnapshotUriWithSas.GetAbsoluteUrl());
auto downloadedContent = blobSnapshotClient.Download();
EXPECT_TRUE(ReadBodyStream(downloadedContent->BodyStream).empty());
@ -438,7 +438,7 @@ namespace Azure { namespace Storage { namespace Test {
auto verify_blob_snapshot_delete = [&](const std::string sas) {
Azure::Core::Http::Url blobSnapshotUriWithSas(blobSnapshotUri);
blobSnapshotUriWithSas.AppendQueries(sas);
blobSnapshotUriWithSas.AppendQueryParameters(sas);
auto blobSnapshotClient = Blobs::AppendBlobClient(blobSnapshotUriWithSas.GetAbsoluteUrl());
EXPECT_NO_THROW(blobSnapshotClient.Delete());
};
@ -485,7 +485,7 @@ namespace Azure { namespace Storage { namespace Test {
auto verify_blob_version_read = [&](const std::string sas) {
Azure::Core::Http::Url blobVersionUriWithSas(blobVersionUri);
blobVersionUriWithSas.AppendQueries(sas);
blobVersionUriWithSas.AppendQueryParameters(sas);
auto blobVersionClient = Blobs::AppendBlobClient(blobVersionUriWithSas.GetAbsoluteUrl());
auto downloadedContent = blobVersionClient.Download();
EXPECT_TRUE(ReadBodyStream(downloadedContent->BodyStream).empty());
@ -493,7 +493,7 @@ namespace Azure { namespace Storage { namespace Test {
auto verify_blob_delete_version = [&](const std::string& sas) {
Azure::Core::Http::Url blobVersionUriWithSas(blobVersionUri);
blobVersionUriWithSas.AppendQueries(sas);
blobVersionUriWithSas.AppendQueryParameters(sas);
auto blobVersionClient = Blobs::AppendBlobClient(blobVersionUriWithSas.GetAbsoluteUrl());
blobVersionClient.Delete();
};

View File

@ -146,7 +146,7 @@ namespace Azure { namespace Storage { namespace Test {
StandardStorageConnectionString(), m_containerName, RandomString());
std::string snapshot = m_pageBlobClient->CreateSnapshot()->Snapshot;
Azure::Core::Http::Url sourceUri(m_pageBlobClient->WithSnapshot(snapshot).GetUri());
sourceUri.AppendQueries(GetSas());
sourceUri.AppendQueryParameters(GetSas());
auto copyInfo = pageBlobClient.StartCopyIncremental(sourceUri.GetAbsoluteUrl());
EXPECT_FALSE(copyInfo->ETag.empty());
EXPECT_FALSE(copyInfo->LastModified.empty());

View File

@ -63,5 +63,6 @@ namespace Azure { namespace Storage {
namespace Details {
std::string Sha256(const std::string& text);
std::string HmacSha256(const std::string& text, const std::string& key);
std::string UrlEncodeQueryParameter(const std::string& value);
} // namespace Details
}} // namespace Azure::Storage

View File

@ -105,21 +105,21 @@ namespace Azure { namespace Storage {
= Base64Encode(Details::HmacSha256(stringToSign, Base64Decode(credential.GetAccountKey())));
Azure::Core::Http::Url builder;
builder.AppendQuery("sv", Version);
builder.AppendQuery("ss", services);
builder.AppendQuery("srt", resourceTypes);
builder.AppendQuery("sp", Permissions);
builder.AppendQueryParameter("sv", Details::UrlEncodeQueryParameter(Version));
builder.AppendQueryParameter("ss", Details::UrlEncodeQueryParameter(services));
builder.AppendQueryParameter("srt", Details::UrlEncodeQueryParameter(resourceTypes));
builder.AppendQueryParameter("sp", Details::UrlEncodeQueryParameter(Permissions));
if (StartsOn.HasValue())
{
builder.AppendQuery("st", StartsOn.GetValue());
builder.AppendQueryParameter("st", Details::UrlEncodeQueryParameter(StartsOn.GetValue()));
}
builder.AppendQuery("se", ExpiresOn);
builder.AppendQueryParameter("se", Details::UrlEncodeQueryParameter(ExpiresOn));
if (IPRange.HasValue())
{
builder.AppendQuery("sip", IPRange.GetValue());
builder.AppendQueryParameter("sip", Details::UrlEncodeQueryParameter(IPRange.GetValue()));
}
builder.AppendQuery("spr", protocol);
builder.AppendQuery("sig", signature);
builder.AppendQueryParameter("spr", Details::UrlEncodeQueryParameter(protocol));
builder.AppendQueryParameter("sig", Details::UrlEncodeQueryParameter(signature));
return builder.GetAbsoluteUrl();
}

View File

@ -16,11 +16,59 @@
#endif
#include <stdexcept>
#include <vector>
#include "azure/storage/common/storage_common.hpp"
namespace Azure { namespace Storage {
namespace Details {
std::string UrlEncodeQueryParameter(const std::string& value)
{
static const char* unreserved
= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~";
static const char* subdelimiters = "!$&'()*+,;=";
const static std::vector<bool> shouldEncodeTable = []() {
std::string queryCharacters
= std::string(unreserved) + std::string(subdelimiters) + "%/:@?";
std::vector<bool> ret(256, true);
for (char c : queryCharacters)
{
ret[c] = false;
}
// we also encode % and +
ret['%'] = true;
ret['+'] = true;
// Surprisingly, '=' also needs to be encoded because Azure Storage server side is so
// strict. We are applying this function to query key and value respectively, so this won't
// affect that = used to separate key and query.
ret['='] = true;
return ret;
}();
const char* hex = "0123456789ABCDEF";
std::string encoded;
for (char c : value)
{
unsigned char uc = c;
if (shouldEncodeTable[uc])
{
encoded += '%';
encoded += hex[(uc >> 4) & 0x0f];
encoded += hex[uc & 0x0f];
}
else
{
encoded += c;
}
}
return encoded;
}
} // namespace Details
#ifdef _WIN32
namespace Details {

View File

@ -66,13 +66,14 @@ namespace Azure { namespace Storage {
// canonicalized resource
string_to_sign += "/" + m_credential->AccountName + "/" + request.GetUrl().GetPath() + "\n";
for (const auto& query : request.GetUrl().GetQuery())
for (const auto& query : request.GetUrl().GetQueryParameters())
{
std::string key = query.first;
std::transform(key.begin(), key.end(), key.begin(), [](char c) {
return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
});
ordered_kv.emplace_back(std::make_pair(std::move(key), query.second));
ordered_kv.emplace_back(std::make_pair(
Azure::Core::Http::Url::Decode(key), Azure::Core::Http::Url::Decode(query.second)));
}
std::sort(ordered_kv.begin(), ordered_kv.end());
for (const auto& p : ordered_kv)

View File

@ -96,10 +96,10 @@ namespace Azure { namespace Storage { namespace Details {
std::string sas = getWithDefault(connectionStringMap, "SharedAccessSignature");
if (!sas.empty())
{
connectionStringParts.BlobServiceUri.AppendQueries(sas);
connectionStringParts.DataLakeServiceUri.AppendQueries(sas);
connectionStringParts.FileServiceUri.AppendQueries(sas);
connectionStringParts.QueueServiceUri.AppendQueries(sas);
connectionStringParts.BlobServiceUri.AppendQueryParameters(sas);
connectionStringParts.DataLakeServiceUri.AppendQueryParameters(sas);
connectionStringParts.FileServiceUri.AppendQueryParameters(sas);
connectionStringParts.QueueServiceUri.AppendQueryParameters(sas);
}
return connectionStringParts;

View File

@ -8,6 +8,7 @@
#include "azure/core/http/pipeline.hpp"
#include "azure/core/nullable.hpp"
#include "azure/core/response.hpp"
#include "azure/storage/common/crypt.hpp"
#include "azure/storage/common/json.hpp"
#include "azure/storage/common/storage_common.hpp"
#include "azure/storage/common/storage_error.hpp"
@ -898,22 +899,26 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
const ListFileSystemsOptions& listFileSystemsOptions)
{
Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url);
request.GetUrl().AppendQuery(Details::c_QueryResource, "account");
request.GetUrl().AppendQueryParameter(Details::c_QueryResource, "account");
if (listFileSystemsOptions.Prefix.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryPrefix, listFileSystemsOptions.Prefix.GetValue());
request.GetUrl().AppendQueryParameter(
Details::c_QueryPrefix,
Storage::Details::UrlEncodeQueryParameter(listFileSystemsOptions.Prefix.GetValue()));
}
if (listFileSystemsOptions.Continuation.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryContinuation, listFileSystemsOptions.Continuation.GetValue());
request.GetUrl().AppendQueryParameter(
Details::c_QueryContinuation,
Storage::Details::UrlEncodeQueryParameter(
listFileSystemsOptions.Continuation.GetValue()));
}
if (listFileSystemsOptions.MaxResults.HasValue())
{
request.GetUrl().AppendQuery(
request.GetUrl().AppendQueryParameter(
Details::c_QueryMaxResults,
std::to_string(listFileSystemsOptions.MaxResults.GetValue()));
Storage::Details::UrlEncodeQueryParameter(
std::to_string(listFileSystemsOptions.MaxResults.GetValue())));
}
if (listFileSystemsOptions.ClientRequestId.HasValue())
{
@ -922,8 +927,10 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
}
if (listFileSystemsOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryTimeout, std::to_string(listFileSystemsOptions.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(listFileSystemsOptions.Timeout.GetValue())));
}
request.AddHeader(
Details::c_HeaderApiVersionParameter, listFileSystemsOptions.ApiVersionParameter);
@ -995,7 +1002,9 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
{
Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader(Details::c_HeaderContentLength, "0");
request.GetUrl().AppendQuery(Details::c_QueryFileSystemResource, "filesystem");
request.GetUrl().AppendQueryParameter(
Details::c_QueryFileSystemResource,
Storage::Details::UrlEncodeQueryParameter("filesystem"));
if (createOptions.ClientRequestId.HasValue())
{
request.AddHeader(
@ -1003,8 +1012,10 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
}
if (createOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryTimeout, std::to_string(createOptions.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(createOptions.Timeout.GetValue())));
}
request.AddHeader(Details::c_HeaderApiVersionParameter, createOptions.ApiVersionParameter);
if (createOptions.Properties.HasValue())
@ -1052,7 +1063,9 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
const SetPropertiesOptions& setPropertiesOptions)
{
Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Patch, url);
request.GetUrl().AppendQuery(Details::c_QueryFileSystemResource, "filesystem");
request.GetUrl().AppendQueryParameter(
Details::c_QueryFileSystemResource,
Storage::Details::UrlEncodeQueryParameter("filesystem"));
if (setPropertiesOptions.ClientRequestId.HasValue())
{
request.AddHeader(
@ -1060,8 +1073,10 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
}
if (setPropertiesOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryTimeout, std::to_string(setPropertiesOptions.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(setPropertiesOptions.Timeout.GetValue())));
}
request.AddHeader(
Details::c_HeaderApiVersionParameter, setPropertiesOptions.ApiVersionParameter);
@ -1106,7 +1121,9 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
const GetPropertiesOptions& getPropertiesOptions)
{
Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Head, url);
request.GetUrl().AppendQuery(Details::c_QueryFileSystemResource, "filesystem");
request.GetUrl().AppendQueryParameter(
Details::c_QueryFileSystemResource,
Storage::Details::UrlEncodeQueryParameter("filesystem"));
if (getPropertiesOptions.ClientRequestId.HasValue())
{
request.AddHeader(
@ -1114,8 +1131,10 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
}
if (getPropertiesOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryTimeout, std::to_string(getPropertiesOptions.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(getPropertiesOptions.Timeout.GetValue())));
}
request.AddHeader(
Details::c_HeaderApiVersionParameter, getPropertiesOptions.ApiVersionParameter);
@ -1150,7 +1169,9 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
const DeleteOptions& deleteOptions)
{
Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Delete, url);
request.GetUrl().AppendQuery(Details::c_QueryFileSystemResource, "filesystem");
request.GetUrl().AppendQueryParameter(
Details::c_QueryFileSystemResource,
Storage::Details::UrlEncodeQueryParameter("filesystem"));
if (deleteOptions.ClientRequestId.HasValue())
{
request.AddHeader(
@ -1158,8 +1179,10 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
}
if (deleteOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryTimeout, std::to_string(deleteOptions.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(deleteOptions.Timeout.GetValue())));
}
request.AddHeader(Details::c_HeaderApiVersionParameter, deleteOptions.ApiVersionParameter);
if (deleteOptions.IfModifiedSince.HasValue())
@ -1220,7 +1243,9 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
const ListPathsOptions& listPathsOptions)
{
Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url);
request.GetUrl().AppendQuery(Details::c_QueryFileSystemResource, "filesystem");
request.GetUrl().AppendQueryParameter(
Details::c_QueryFileSystemResource,
Storage::Details::UrlEncodeQueryParameter("filesystem"));
if (listPathsOptions.ClientRequestId.HasValue())
{
request.AddHeader(
@ -1228,33 +1253,42 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
}
if (listPathsOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryTimeout, std::to_string(listPathsOptions.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(listPathsOptions.Timeout.GetValue())));
}
request.AddHeader(
Details::c_HeaderApiVersionParameter, listPathsOptions.ApiVersionParameter);
if (listPathsOptions.Continuation.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryContinuation, listPathsOptions.Continuation.GetValue());
request.GetUrl().AppendQueryParameter(
Details::c_QueryContinuation,
Storage::Details::UrlEncodeQueryParameter(listPathsOptions.Continuation.GetValue()));
}
if (listPathsOptions.Directory.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryDirectory, listPathsOptions.Directory.GetValue());
request.GetUrl().AppendQueryParameter(
Details::c_QueryDirectory,
Storage::Details::UrlEncodeQueryParameter(listPathsOptions.Directory.GetValue()));
}
request.GetUrl().AppendQuery(
request.GetUrl().AppendQueryParameter(
Details::c_QueryRecursiveRequired,
(listPathsOptions.RecursiveRequired ? "true" : "false"));
Storage::Details::UrlEncodeQueryParameter(
(listPathsOptions.RecursiveRequired ? "true" : "false")));
if (listPathsOptions.MaxResults.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryMaxResults, std::to_string(listPathsOptions.MaxResults.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryMaxResults,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(listPathsOptions.MaxResults.GetValue())));
}
if (listPathsOptions.Upn.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryUpn, (listPathsOptions.Upn.GetValue() ? "true" : "false"));
request.GetUrl().AppendQueryParameter(
Details::c_QueryUpn,
Storage::Details::UrlEncodeQueryParameter(
(listPathsOptions.Upn.GetValue() ? "true" : "false")));
}
return ListPathsParseResult(context, pipeline.Send(context, request));
}
@ -1502,26 +1536,31 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
}
if (createOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryTimeout, std::to_string(createOptions.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(createOptions.Timeout.GetValue())));
}
request.AddHeader(Details::c_HeaderApiVersionParameter, createOptions.ApiVersionParameter);
if (createOptions.Resource.HasValue())
{
request.GetUrl().AppendQuery(
request.GetUrl().AppendQueryParameter(
Details::c_QueryPathResourceType,
PathResourceTypeToString(createOptions.Resource.GetValue()));
Storage::Details::UrlEncodeQueryParameter(
PathResourceTypeToString(createOptions.Resource.GetValue())));
}
if (createOptions.Continuation.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryContinuation, createOptions.Continuation.GetValue());
request.GetUrl().AppendQueryParameter(
Details::c_QueryContinuation,
Storage::Details::UrlEncodeQueryParameter(createOptions.Continuation.GetValue()));
}
if (createOptions.Mode.HasValue())
{
request.GetUrl().AppendQuery(
request.GetUrl().AppendQueryParameter(
Details::c_QueryPathRenameMode,
PathRenameModeToString(createOptions.Mode.GetValue()));
Storage::Details::UrlEncodeQueryParameter(
PathRenameModeToString(createOptions.Mode.GetValue())));
}
if (createOptions.CacheControl.HasValue())
{
@ -1766,45 +1805,60 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
}
if (updateOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryTimeout, std::to_string(updateOptions.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(updateOptions.Timeout.GetValue())));
}
request.AddHeader(Details::c_HeaderApiVersionParameter, updateOptions.ApiVersionParameter);
request.GetUrl().AppendQuery(
Details::c_QueryPathUpdateAction, PathUpdateActionToString(updateOptions.Action));
request.GetUrl().AppendQueryParameter(
Details::c_QueryPathUpdateAction,
Storage::Details::UrlEncodeQueryParameter(
PathUpdateActionToString(updateOptions.Action)));
if (updateOptions.MaxRecords.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryMaxRecords, std::to_string(updateOptions.MaxRecords.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryMaxRecords,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(updateOptions.MaxRecords.GetValue())));
}
if (updateOptions.Continuation.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryContinuation, updateOptions.Continuation.GetValue());
request.GetUrl().AppendQueryParameter(
Details::c_QueryContinuation,
Storage::Details::UrlEncodeQueryParameter(updateOptions.Continuation.GetValue()));
}
request.GetUrl().AppendQuery(
request.GetUrl().AppendQueryParameter(
Details::c_QueryPathSetAccessControlRecursiveMode,
PathSetAccessControlRecursiveModeToString(updateOptions.Mode));
Storage::Details::UrlEncodeQueryParameter(
PathSetAccessControlRecursiveModeToString(updateOptions.Mode)));
if (updateOptions.ForceFlag.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryForceFlag, (updateOptions.ForceFlag.GetValue() ? "true" : "false"));
request.GetUrl().AppendQueryParameter(
Details::c_QueryForceFlag,
Storage::Details::UrlEncodeQueryParameter(
(updateOptions.ForceFlag.GetValue() ? "true" : "false")));
}
if (updateOptions.Position.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryPosition, std::to_string(updateOptions.Position.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryPosition,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(updateOptions.Position.GetValue())));
}
if (updateOptions.RetainUncommittedData.HasValue())
{
request.GetUrl().AppendQuery(
request.GetUrl().AppendQueryParameter(
Details::c_QueryRetainUncommittedData,
(updateOptions.RetainUncommittedData.GetValue() ? "true" : "false"));
Storage::Details::UrlEncodeQueryParameter(
(updateOptions.RetainUncommittedData.GetValue() ? "true" : "false")));
}
if (updateOptions.Close.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryClose, (updateOptions.Close.GetValue() ? "true" : "false"));
request.GetUrl().AppendQueryParameter(
Details::c_QueryClose,
Storage::Details::UrlEncodeQueryParameter(
(updateOptions.Close.GetValue() ? "true" : "false")));
}
if (updateOptions.ContentLength.HasValue())
{
@ -1955,8 +2009,10 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
}
if (leaseOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryTimeout, std::to_string(leaseOptions.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(leaseOptions.Timeout.GetValue())));
}
request.AddHeader(Details::c_HeaderApiVersionParameter, leaseOptions.ApiVersionParameter);
request.AddHeader(
@ -2058,8 +2114,10 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
}
if (readOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryTimeout, std::to_string(readOptions.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(readOptions.Timeout.GetValue())));
}
request.AddHeader(Details::c_HeaderApiVersionParameter, readOptions.ApiVersionParameter);
if (readOptions.Range.HasValue())
@ -2153,21 +2211,26 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
}
if (getPropertiesOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryTimeout, std::to_string(getPropertiesOptions.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(getPropertiesOptions.Timeout.GetValue())));
}
request.AddHeader(
Details::c_HeaderApiVersionParameter, getPropertiesOptions.ApiVersionParameter);
if (getPropertiesOptions.Action.HasValue())
{
request.GetUrl().AppendQuery(
request.GetUrl().AppendQueryParameter(
Details::c_QueryPathGetPropertiesAction,
PathGetPropertiesActionToString(getPropertiesOptions.Action.GetValue()));
Storage::Details::UrlEncodeQueryParameter(
PathGetPropertiesActionToString(getPropertiesOptions.Action.GetValue())));
}
if (getPropertiesOptions.Upn.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryUpn, (getPropertiesOptions.Upn.GetValue() ? "true" : "false"));
request.GetUrl().AppendQueryParameter(
Details::c_QueryUpn,
Storage::Details::UrlEncodeQueryParameter(
(getPropertiesOptions.Upn.GetValue() ? "true" : "false")));
}
if (getPropertiesOptions.LeaseIdOptional.HasValue())
{
@ -2247,20 +2310,24 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
}
if (deleteOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryTimeout, std::to_string(deleteOptions.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(deleteOptions.Timeout.GetValue())));
}
request.AddHeader(Details::c_HeaderApiVersionParameter, deleteOptions.ApiVersionParameter);
if (deleteOptions.RecursiveOptional.HasValue())
{
request.GetUrl().AppendQuery(
request.GetUrl().AppendQueryParameter(
Details::c_QueryRecursiveOptional,
(deleteOptions.RecursiveOptional.GetValue() ? "true" : "false"));
Storage::Details::UrlEncodeQueryParameter(
(deleteOptions.RecursiveOptional.GetValue() ? "true" : "false")));
}
if (deleteOptions.Continuation.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryContinuation, deleteOptions.Continuation.GetValue());
request.GetUrl().AppendQueryParameter(
Details::c_QueryContinuation,
Storage::Details::UrlEncodeQueryParameter(deleteOptions.Continuation.GetValue()));
}
if (deleteOptions.LeaseIdOptional.HasValue())
{
@ -2337,11 +2404,13 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
const SetAccessControlOptions& setAccessControlOptions)
{
Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Patch, url);
request.GetUrl().AppendQuery(Details::c_QueryAction, "setAccessControl");
request.GetUrl().AppendQueryParameter(Details::c_QueryAction, "setAccessControl");
if (setAccessControlOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryTimeout, std::to_string(setAccessControlOptions.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(setAccessControlOptions.Timeout.GetValue())));
}
if (setAccessControlOptions.LeaseIdOptional.HasValue())
{
@ -2445,33 +2514,38 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
const SetAccessControlRecursiveOptions& setAccessControlRecursiveOptions)
{
Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Patch, url);
request.GetUrl().AppendQuery(Details::c_QueryAction, "setAccessControlRecursive");
request.GetUrl().AppendQueryParameter(Details::c_QueryAction, "setAccessControlRecursive");
if (setAccessControlRecursiveOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
std::to_string(setAccessControlRecursiveOptions.Timeout.GetValue()));
Storage::Details::UrlEncodeQueryParameter(
std::to_string(setAccessControlRecursiveOptions.Timeout.GetValue())));
}
if (setAccessControlRecursiveOptions.Continuation.HasValue())
{
request.GetUrl().AppendQuery(
request.GetUrl().AppendQueryParameter(
Details::c_QueryContinuation,
setAccessControlRecursiveOptions.Continuation.GetValue());
Storage::Details::UrlEncodeQueryParameter(
setAccessControlRecursiveOptions.Continuation.GetValue()));
}
request.GetUrl().AppendQuery(
request.GetUrl().AppendQueryParameter(
Details::c_QueryPathSetAccessControlRecursiveMode,
PathSetAccessControlRecursiveModeToString(setAccessControlRecursiveOptions.Mode));
Storage::Details::UrlEncodeQueryParameter(
PathSetAccessControlRecursiveModeToString(setAccessControlRecursiveOptions.Mode)));
if (setAccessControlRecursiveOptions.ForceFlag.HasValue())
{
request.GetUrl().AppendQuery(
request.GetUrl().AppendQueryParameter(
Details::c_QueryForceFlag,
(setAccessControlRecursiveOptions.ForceFlag.GetValue() ? "true" : "false"));
Storage::Details::UrlEncodeQueryParameter(
(setAccessControlRecursiveOptions.ForceFlag.GetValue() ? "true" : "false")));
}
if (setAccessControlRecursiveOptions.MaxRecords.HasValue())
{
request.GetUrl().AppendQuery(
request.GetUrl().AppendQueryParameter(
Details::c_QueryMaxRecords,
std::to_string(setAccessControlRecursiveOptions.MaxRecords.GetValue()));
Storage::Details::UrlEncodeQueryParameter(
std::to_string(setAccessControlRecursiveOptions.MaxRecords.GetValue())));
}
if (setAccessControlRecursiveOptions.Acl.HasValue())
{
@ -2575,27 +2649,34 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
const FlushDataOptions& flushDataOptions)
{
Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Patch, url);
request.GetUrl().AppendQuery(Details::c_QueryAction, "flush");
request.GetUrl().AppendQueryParameter(Details::c_QueryAction, "flush");
if (flushDataOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryTimeout, std::to_string(flushDataOptions.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(flushDataOptions.Timeout.GetValue())));
}
if (flushDataOptions.Position.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryPosition, std::to_string(flushDataOptions.Position.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryPosition,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(flushDataOptions.Position.GetValue())));
}
if (flushDataOptions.RetainUncommittedData.HasValue())
{
request.GetUrl().AppendQuery(
request.GetUrl().AppendQueryParameter(
Details::c_QueryRetainUncommittedData,
(flushDataOptions.RetainUncommittedData.GetValue() ? "true" : "false"));
Storage::Details::UrlEncodeQueryParameter(
(flushDataOptions.RetainUncommittedData.GetValue() ? "true" : "false")));
}
if (flushDataOptions.Close.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryClose, (flushDataOptions.Close.GetValue() ? "true" : "false"));
request.GetUrl().AppendQueryParameter(
Details::c_QueryClose,
Storage::Details::UrlEncodeQueryParameter(
(flushDataOptions.Close.GetValue() ? "true" : "false")));
}
if (flushDataOptions.ContentLength.HasValue())
{
@ -2710,16 +2791,20 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
{
Azure::Core::Http::Request request(
Azure::Core::Http::HttpMethod::Patch, std::move(url), &bodyStream);
request.GetUrl().AppendQuery(Details::c_QueryAction, "append");
request.GetUrl().AppendQueryParameter(Details::c_QueryAction, "append");
if (appendDataOptions.Position.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryPosition, std::to_string(appendDataOptions.Position.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryPosition,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(appendDataOptions.Position.GetValue())));
}
if (appendDataOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryTimeout, std::to_string(appendDataOptions.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(appendDataOptions.Timeout.GetValue())));
}
if (appendDataOptions.ContentLength.HasValue())
{
@ -2778,11 +2863,13 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
{
Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader(Details::c_HeaderContentLength, "0");
request.GetUrl().AppendQuery(Details::c_QueryComp, "expiry");
request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "expiry");
if (setExpiryOptions.Timeout.HasValue())
{
request.GetUrl().AppendQuery(
Details::c_QueryTimeout, std::to_string(setExpiryOptions.Timeout.GetValue()));
request.GetUrl().AppendQueryParameter(
Details::c_QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(setExpiryOptions.Timeout.GetValue())));
}
request.AddHeader(
Details::c_HeaderApiVersionParameter, setExpiryOptions.ApiVersionParameter);

View File

@ -133,49 +133,54 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
Storage::Details::HmacSha256(stringToSign, Base64Decode(credential.GetAccountKey())));
Azure::Core::Http::Url builder;
builder.AppendQuery("sv", Version);
builder.AppendQuery("spr", protocol);
builder.AppendQueryParameter("sv", Storage::Details::UrlEncodeQueryParameter(Version));
builder.AppendQueryParameter("spr", Storage::Details::UrlEncodeQueryParameter(protocol));
if (StartsOn.HasValue())
{
builder.AppendQuery("st", StartsOn.GetValue());
builder.AppendQueryParameter(
"st", Storage::Details::UrlEncodeQueryParameter(StartsOn.GetValue()));
}
if (!ExpiresOn.empty())
{
builder.AppendQuery("se", ExpiresOn);
builder.AppendQueryParameter("se", Storage::Details::UrlEncodeQueryParameter(ExpiresOn));
}
if (IPRange.HasValue())
{
builder.AppendQuery("sip", IPRange.GetValue());
builder.AppendQueryParameter(
"sip", Storage::Details::UrlEncodeQueryParameter(IPRange.GetValue()));
}
if (!Identifier.empty())
{
builder.AppendQuery("si", Identifier);
builder.AppendQueryParameter("si", Storage::Details::UrlEncodeQueryParameter(Identifier));
}
builder.AppendQuery("sr", resource);
builder.AppendQueryParameter("sr", Storage::Details::UrlEncodeQueryParameter(resource));
if (!Permissions.empty())
{
builder.AppendQuery("sp", Permissions);
builder.AppendQueryParameter("sp", Storage::Details::UrlEncodeQueryParameter(Permissions));
}
builder.AppendQuery("sig", signature);
builder.AppendQueryParameter("sig", Storage::Details::UrlEncodeQueryParameter(signature));
if (!CacheControl.empty())
{
builder.AppendQuery("rscc", CacheControl);
builder.AppendQueryParameter("rscc", Storage::Details::UrlEncodeQueryParameter(CacheControl));
}
if (!ContentDisposition.empty())
{
builder.AppendQuery("rscd", ContentDisposition);
builder.AppendQueryParameter(
"rscd", Storage::Details::UrlEncodeQueryParameter(ContentDisposition));
}
if (!ContentEncoding.empty())
{
builder.AppendQuery("rsce", ContentEncoding);
builder.AppendQueryParameter(
"rsce", Storage::Details::UrlEncodeQueryParameter(ContentEncoding));
}
if (!ContentLanguage.empty())
{
builder.AppendQuery("rscl", ContentLanguage);
builder.AppendQueryParameter(
"rscl", Storage::Details::UrlEncodeQueryParameter(ContentLanguage));
}
if (!ContentType.empty())
{
builder.AppendQuery("rsct", ContentType);
builder.AppendQueryParameter("rsct", Storage::Details::UrlEncodeQueryParameter(ContentType));
}
return builder.GetAbsoluteUrl();
@ -206,62 +211,78 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
Storage::Details::HmacSha256(stringToSign, Base64Decode(userDelegationKey.Value)));
Azure::Core::Http::Url builder;
builder.AppendQuery("sv", Version);
builder.AppendQuery("sr", resource);
builder.AppendQueryParameter("sv", Storage::Details::UrlEncodeQueryParameter(Version));
builder.AppendQueryParameter("sr", Storage::Details::UrlEncodeQueryParameter(resource));
if (StartsOn.HasValue())
{
builder.AppendQuery("st", StartsOn.GetValue());
builder.AppendQueryParameter(
"st", Storage::Details::UrlEncodeQueryParameter(StartsOn.GetValue()));
}
builder.AppendQuery("se", ExpiresOn);
builder.AppendQuery("sp", Permissions);
builder.AppendQueryParameter("se", Storage::Details::UrlEncodeQueryParameter(ExpiresOn));
builder.AppendQueryParameter("sp", Permissions);
if (IPRange.HasValue())
{
builder.AppendQuery("sip", IPRange.GetValue());
builder.AppendQueryParameter(
"sip", Storage::Details::UrlEncodeQueryParameter(IPRange.GetValue()));
}
builder.AppendQuery("spr", protocol);
builder.AppendQuery("skoid", userDelegationKey.SignedObjectId);
builder.AppendQuery("sktid", userDelegationKey.SignedTenantId);
builder.AppendQuery("skt", userDelegationKey.SignedStartsOn);
builder.AppendQuery("ske", userDelegationKey.SignedExpiresOn);
builder.AppendQuery("sks", userDelegationKey.SignedService);
builder.AppendQuery("skv", userDelegationKey.SignedVersion);
builder.AppendQueryParameter("spr", Storage::Details::UrlEncodeQueryParameter(protocol));
builder.AppendQueryParameter(
"skoid", Storage::Details::UrlEncodeQueryParameter(userDelegationKey.SignedObjectId));
builder.AppendQueryParameter(
"sktid", Storage::Details::UrlEncodeQueryParameter(userDelegationKey.SignedTenantId));
builder.AppendQueryParameter(
"skt", Storage::Details::UrlEncodeQueryParameter(userDelegationKey.SignedStartsOn));
builder.AppendQueryParameter(
"ske", Storage::Details::UrlEncodeQueryParameter(userDelegationKey.SignedExpiresOn));
builder.AppendQueryParameter(
"sks", Storage::Details::UrlEncodeQueryParameter(userDelegationKey.SignedService));
builder.AppendQueryParameter(
"skv", Storage::Details::UrlEncodeQueryParameter(userDelegationKey.SignedVersion));
if (!PreauthorizedAgentObjectId.empty())
{
builder.AppendQuery("saoid", PreauthorizedAgentObjectId);
builder.AppendQueryParameter(
"saoid", Storage::Details::UrlEncodeQueryParameter(PreauthorizedAgentObjectId));
}
if (!AgentObjectId.empty())
{
builder.AppendQuery("suoid", AgentObjectId);
builder.AppendQueryParameter(
"suoid", Storage::Details::UrlEncodeQueryParameter(AgentObjectId));
}
if (!CorrelationId.empty())
{
builder.AppendQuery("scid", CorrelationId);
builder.AppendQueryParameter(
"scid", Storage::Details::UrlEncodeQueryParameter(CorrelationId));
}
if (DirectoryDepth.HasValue())
{
builder.AppendQuery("sdd", std::to_string(DirectoryDepth.GetValue()));
builder.AppendQueryParameter(
"sdd",
Storage::Details::UrlEncodeQueryParameter(std::to_string(DirectoryDepth.GetValue())));
}
if (!CacheControl.empty())
{
builder.AppendQuery("rscc", CacheControl);
builder.AppendQueryParameter("rscc", Storage::Details::UrlEncodeQueryParameter(CacheControl));
}
if (!ContentDisposition.empty())
{
builder.AppendQuery("rscd", ContentDisposition);
builder.AppendQueryParameter(
"rscd", Storage::Details::UrlEncodeQueryParameter(ContentDisposition));
}
if (!ContentEncoding.empty())
{
builder.AppendQuery("rsce", ContentEncoding);
builder.AppendQueryParameter(
"rsce", Storage::Details::UrlEncodeQueryParameter(ContentEncoding));
}
if (!ContentLanguage.empty())
{
builder.AppendQuery("rscl", ContentLanguage);
builder.AppendQueryParameter(
"rscl", Storage::Details::UrlEncodeQueryParameter(ContentLanguage));
}
if (!ContentType.empty())
{
builder.AppendQuery("rsct", ContentType);
builder.AppendQueryParameter("rsct", Storage::Details::UrlEncodeQueryParameter(ContentType));
}
builder.AppendQuery("sig", signature);
builder.AppendQueryParameter("sig", Storage::Details::UrlEncodeQueryParameter(signature));
return builder.GetAbsoluteUrl();
}

View File

@ -132,11 +132,13 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
ShareClient newClient(*this);
if (snapshot.empty())
{
newClient.m_shareUri.RemoveQuery(Details::c_ShareSnapshotQueryParameter);
newClient.m_shareUri.RemoveQueryParameter(Details::c_ShareSnapshotQueryParameter);
}
else
{
newClient.m_shareUri.AppendQuery(Details::c_ShareSnapshotQueryParameter, snapshot);
newClient.m_shareUri.AppendQueryParameter(
Details::c_ShareSnapshotQueryParameter,
Storage::Details::UrlEncodeQueryParameter(snapshot));
}
return newClient;
}

View File

@ -135,12 +135,13 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
DirectoryClient newClient(*this);
if (shareSnapshot.empty())
{
newClient.m_shareDirectoryUri.RemoveQuery(Details::c_ShareSnapshotQueryParameter);
newClient.m_shareDirectoryUri.RemoveQueryParameter(Details::c_ShareSnapshotQueryParameter);
}
else
{
newClient.m_shareDirectoryUri.AppendQuery(
Details::c_ShareSnapshotQueryParameter, shareSnapshot);
newClient.m_shareDirectoryUri.AppendQueryParameter(
Details::c_ShareSnapshotQueryParameter,
Storage::Details::UrlEncodeQueryParameter(shareSnapshot));
}
return newClient;
}

View File

@ -122,11 +122,13 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
FileClient newClient(*this);
if (shareSnapshot.empty())
{
newClient.m_shareFileUri.RemoveQuery(Details::c_ShareSnapshotQueryParameter);
newClient.m_shareFileUri.RemoveQueryParameter(Details::c_ShareSnapshotQueryParameter);
}
else
{
newClient.m_shareFileUri.AppendQuery(Details::c_ShareSnapshotQueryParameter, shareSnapshot);
newClient.m_shareFileUri.AppendQueryParameter(
Details::c_ShareSnapshotQueryParameter,
Storage::Details::UrlEncodeQueryParameter(shareSnapshot));
}
return newClient;
}

View File

@ -94,49 +94,49 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
= Base64Encode(Details::HmacSha256(stringToSign, Base64Decode(credential.GetAccountKey())));
Azure::Core::Http::Url builder;
builder.AppendQuery("sv", Version);
builder.AppendQuery("spr", protocol);
builder.AppendQueryParameter("sv", Details::UrlEncodeQueryParameter(Version));
builder.AppendQueryParameter("spr", Details::UrlEncodeQueryParameter(protocol));
if (StartsOn.HasValue())
{
builder.AppendQuery("st", StartsOn.GetValue());
builder.AppendQueryParameter("st", Details::UrlEncodeQueryParameter(StartsOn.GetValue()));
}
if (!ExpiresOn.empty())
{
builder.AppendQuery("se", ExpiresOn);
builder.AppendQueryParameter("se", Details::UrlEncodeQueryParameter(ExpiresOn));
}
if (IPRange.HasValue())
{
builder.AppendQuery("sip", IPRange.GetValue());
builder.AppendQueryParameter("sip", Details::UrlEncodeQueryParameter(IPRange.GetValue()));
}
if (!Identifier.empty())
{
builder.AppendQuery("si", Identifier);
builder.AppendQueryParameter("si", Details::UrlEncodeQueryParameter(Identifier));
}
builder.AppendQuery("sr", resource);
builder.AppendQueryParameter("sr", Details::UrlEncodeQueryParameter(resource));
if (!Permissions.empty())
{
builder.AppendQuery("sp", Permissions);
builder.AppendQueryParameter("sp", Details::UrlEncodeQueryParameter(Permissions));
}
builder.AppendQuery("sig", signature);
builder.AppendQueryParameter("sig", Details::UrlEncodeQueryParameter(signature));
if (!CacheControl.empty())
{
builder.AppendQuery("rscc", CacheControl);
builder.AppendQueryParameter("rscc", Details::UrlEncodeQueryParameter(CacheControl));
}
if (!ContentDisposition.empty())
{
builder.AppendQuery("rscd", ContentDisposition);
builder.AppendQueryParameter("rscd", Details::UrlEncodeQueryParameter(ContentDisposition));
}
if (!ContentEncoding.empty())
{
builder.AppendQuery("rsce", ContentEncoding);
builder.AppendQueryParameter("rsce", Details::UrlEncodeQueryParameter(ContentEncoding));
}
if (!ContentLanguage.empty())
{
builder.AppendQuery("rscl", ContentLanguage);
builder.AppendQueryParameter("rscl", Details::UrlEncodeQueryParameter(ContentLanguage));
}
if (!ContentType.empty())
{
builder.AppendQuery("rsct", ContentType);
builder.AppendQueryParameter("rsct", Details::UrlEncodeQueryParameter(ContentType));
}
return builder.GetAbsoluteUrl();