azure-core
Loading...
Searching...
No Matches
http.hpp
Go to the documentation of this file.
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
9#pragma once
10
12#include "azure/core/dll_import_export.hpp"
16#include "azure/core/internal/contract.hpp"
19#include "azure/core/url.hpp"
20
21#include <algorithm>
22#include <cstdint>
23#include <functional>
24#include <map>
25#include <memory>
26#include <stdexcept>
27#include <string>
28#include <unordered_set>
29#include <utility>
30#include <vector>
31
32#if defined(_azure_TESTING_BUILD)
33// Define the class used from tests to validate retry enabled
34namespace Azure { namespace Core { namespace Test {
35 class TestHttp_getters_Test;
36 class TestHttp_query_parameter_Test;
37 class TestHttp_RequestStartTry_Test;
38 class TestURL_getters_Test;
39 class TestURL_query_parameter_Test;
40 class TransportAdapter_headWithStream_Test;
41 class TransportAdapter_putWithStream_Test;
42 class TransportAdapter_deleteRequestWithStream_Test;
43 class TransportAdapter_patchWithStream_Test;
44 class TransportAdapter_putWithStreamOnFail_Test;
45 class TransportAdapter_SizePutFromFile_Test;
46 class TransportAdapter_SizePutFromFileDefault_Test;
47 class TransportAdapter_SizePutFromFileBiggerPage_Test;
48}}} // namespace Azure::Core::Test
49#endif
50
51namespace Azure { namespace Core { namespace Http {
52
53 /********************* Exceptions **********************/
58 public:
67 explicit TransportException(std::string const& what) : Azure::Core::RequestFailedException(what)
68 {
69 }
70 };
71
77 struct HttpRange final
78 {
83 int64_t Offset = 0;
84
90 };
91
95 class HttpMethod final {
96 public:
104 explicit HttpMethod(std::string value) : m_value(std::move(value)) {}
105
112 bool operator==(const HttpMethod& other) const { return m_value == other.m_value; }
113
120 bool operator!=(const HttpMethod& other) const { return !(*this == other); }
121
125 const std::string& ToString() const { return m_value; }
126
131 AZ_CORE_DLLEXPORT const static HttpMethod Get;
132
137 AZ_CORE_DLLEXPORT const static HttpMethod Head;
138
143 AZ_CORE_DLLEXPORT const static HttpMethod Post;
144
149 AZ_CORE_DLLEXPORT const static HttpMethod Put;
150
155 AZ_CORE_DLLEXPORT const static HttpMethod Delete;
156
161 AZ_CORE_DLLEXPORT const static HttpMethod Patch;
162
167 AZ_CORE_DLLEXPORT const static HttpMethod Options;
168
169 private:
170 std::string m_value;
171 }; // extensible enum HttpMethod
172
173 namespace Policies { namespace _internal {
174 class RetryPolicy;
175 }} // namespace Policies::_internal
176
183 class Request final {
184 friend class Azure::Core::Http::Policies::_internal::RetryPolicy;
185#if defined(_azure_TESTING_BUILD)
186 // make tests classes friends to validate set Retry
187 friend class Azure::Core::Test::TestHttp_getters_Test;
188 friend class Azure::Core::Test::TestHttp_query_parameter_Test;
189 friend class Azure::Core::Test::TestHttp_RequestStartTry_Test;
190 friend class Azure::Core::Test::TestURL_getters_Test;
191 friend class Azure::Core::Test::TestURL_query_parameter_Test;
192 // make tests classes friends to validate private Request ctor that takes both stream and bool
193 friend class Azure::Core::Test::TransportAdapter_headWithStream_Test;
194 friend class Azure::Core::Test::TransportAdapter_putWithStream_Test;
195 friend class Azure::Core::Test::TransportAdapter_deleteRequestWithStream_Test;
196 friend class Azure::Core::Test::TransportAdapter_patchWithStream_Test;
197 friend class Azure::Core::Test::TransportAdapter_putWithStreamOnFail_Test;
198 friend class Azure::Core::Test::TransportAdapter_SizePutFromFile_Test;
199 friend class Azure::Core::Test::TransportAdapter_SizePutFromFileDefault_Test;
200 friend class Azure::Core::Test::TransportAdapter_SizePutFromFileBiggerPage_Test;
201#endif
202
203 private:
204 HttpMethod m_method;
205 Url m_url;
206 CaseInsensitiveMap m_headers;
207 CaseInsensitiveMap m_retryHeaders;
208
209 Azure::Core::IO::BodyStream* m_bodyStream;
210
211 // flag to know where to insert header
212 bool m_retryModeEnabled{false};
213 bool m_shouldBufferResponse{true};
214
215 // Expected to be called by a Retry policy to reset all headers set after this function was
216 // previously called
217 void StartTry();
218
219 public:
229 explicit Request(
230 HttpMethod httpMethod,
231 Url url,
232 Azure::Core::IO::BodyStream* bodyStream,
233 bool shouldBufferResponse)
234 : m_method(std::move(httpMethod)), m_url(std::move(url)), m_bodyStream(bodyStream),
235 m_retryModeEnabled(false), m_shouldBufferResponse(shouldBufferResponse)
236 {
237 AZURE_ASSERT_MSG(bodyStream, "The bodyStream pointer cannot be null.");
238 }
239
247 explicit Request(HttpMethod httpMethod, Url url, Azure::Core::IO::BodyStream* bodyStream)
248 : Request(std::move(httpMethod), std::move(url), bodyStream, true)
249 {
250 }
251
260 explicit Request(HttpMethod httpMethod, Url url, bool shouldBufferResponse);
261
268 explicit Request(HttpMethod httpMethod, Url url);
269
281 void SetHeader(std::string const& name, std::string const& value);
282
291 Azure::Nullable<std::string> GetHeader(std::string const& name);
292
298 void RemoveHeader(std::string const& name);
299
300 // Methods used by transport layer (and logger) to send request
305 HttpMethod const& GetMethod() const;
306
314
319 Azure::Core::IO::BodyStream* GetBodyStream() { return this->m_bodyStream; }
320
325 Azure::Core::IO::BodyStream const* GetBodyStream() const { return this->m_bodyStream; }
326
331 bool ShouldBufferResponse() const { return this->m_shouldBufferResponse; }
332
337 Url& GetUrl() { return this->m_url; }
338
343 Url const& GetUrl() const { return this->m_url; }
344 };
345
346 namespace _detail {
347 struct RawResponseHelpers final
348 {
359 static void InsertHeaderWithValidation(
360 CaseInsensitiveMap& headers,
361 std::string const& headerName,
362 std::string const& headerValue);
363
364 static void inline SetHeader(
366 uint8_t const* const first,
367 uint8_t const* const last)
368 {
369 // get name and value from header
370 auto start = first;
371 auto end = std::find(start, last, ':');
372
373 if (end == last)
374 {
375 throw std::invalid_argument("Invalid header. No delimiter ':' found.");
376 }
377
378 // Always toLower() headers
379 auto const headerName
380 = Azure::Core::_internal::StringExtensions::ToLower(std::string(start, end));
381 start = end + 1; // start value
382 while (start < last && (*start == ' ' || *start == '\t'))
383 {
384 ++start;
385 }
386
387 end = std::find(start, last, '\r');
388 auto headerValue = std::string(start, end); // remove \r
389
390 response.SetHeader(headerName, headerValue);
391 }
392 };
393 } // namespace _detail
394
395 namespace _internal {
396
397 struct HttpShared final
398 {
399 AZ_CORE_DLLEXPORT static char const ContentType[];
400 AZ_CORE_DLLEXPORT static char const ApplicationJson[];
401 AZ_CORE_DLLEXPORT static char const Accept[];
402 AZ_CORE_DLLEXPORT static char const MsRequestId[];
403 AZ_CORE_DLLEXPORT static char const MsClientRequestId[];
404
405 static inline std::string GetHeaderOrEmptyString(
406 Azure::Core::CaseInsensitiveMap const& headers,
407 std::string const& headerName)
408 {
409 auto header = headers.find(headerName);
410 if (header != headers.end())
411 {
412 return header->second; // second is the header value.
413 }
414 return {}; // empty string
415 }
416
435 static std::string GenerateUserAgent(
436 std::string const& componentName,
437 std::string const& componentVersion,
438 std::string const& applicationId,
439 long cplusplusValue);
440
441 private:
442 HttpShared() = delete;
443 ~HttpShared() = delete;
444 };
445 } // namespace _internal
446
447}}} // namespace Azure::Core::Http
#define AZURE_ASSERT_MSG(exp, msg)
Azure specific assert macro with message.
Definition azure_assert.hpp:53
BodyStream is used to read data to/from a service.
A map<string, string> with case-insensitive key comparison.
std::map< std::string, std::string, _internal::StringExtensions::CaseInsensitiveComparator > CaseInsensitiveMap
A type alias of std::map<std::string, std::string> with case-insensitive key comparison.
Definition case_insensitive_containers.hpp:24
The method to be performed on the resource identified by the Request.
Definition http.hpp:95
HttpMethod(std::string value)
Constructs HttpMethod from string.
Definition http.hpp:104
AZ_CORE_DLLEXPORT static const HttpMethod Patch
The representation of a PATCH HTTP method based on [RFC 5789] (https://datatracker....
Definition http.hpp:161
AZ_CORE_DLLEXPORT static const HttpMethod Delete
The representation of a DELETE HTTP method based on [RFC 7231] (https://datatracker....
Definition http.hpp:155
AZ_CORE_DLLEXPORT static const HttpMethod Head
The representation of a HEAD HTTP method based on [RFC 7231] (https://datatracker....
Definition http.hpp:137
const std::string & ToString() const
Returns the HttpMethod represented as a string.
Definition http.hpp:125
bool operator==(const HttpMethod &other) const
Compares two instances of HttpMethod for equality.
Definition http.hpp:112
bool operator!=(const HttpMethod &other) const
Compares two instances of HttpMethod for equality.
Definition http.hpp:120
AZ_CORE_DLLEXPORT static const HttpMethod Put
The representation of a PUT HTTP method based on [RFC 7231] (https://datatracker.ietf....
Definition http.hpp:149
AZ_CORE_DLLEXPORT static const HttpMethod Post
The representation of a POST HTTP method based on [RFC 7231] (https://datatracker....
Definition http.hpp:143
AZ_CORE_DLLEXPORT static const HttpMethod Options
The representation of an OPTIONS HTTP method based on [RFC 2616] (https://datatracker....
Definition http.hpp:167
AZ_CORE_DLLEXPORT static const HttpMethod Get
The representation of a GET HTTP method based on [RFC 7231] (https://datatracker.ietf....
Definition http.hpp:131
After receiving and interpreting a request message, a server responds with an HTTP response message.
Definition raw_response.hpp:24
void SetHeader(std::string const &name, std::string const &value)
Set an HTTP header to the Azure::Core::Http::RawResponse.
Definition raw_response.cpp:17
A request message from a client to a server.
Definition http.hpp:183
bool ShouldBufferResponse() const
A value indicating whether the returned raw response for this request will be buffered within a memor...
Definition http.hpp:331
Url const & GetUrl() const
Get URL.
Definition http.hpp:343
Request(HttpMethod httpMethod, Url url, Azure::Core::IO::BodyStream *bodyStream)
Constructs a Request.
Definition http.hpp:247
Azure::Core::IO::BodyStream const * GetBodyStream() const
Get HTTP body as Azure::Core::IO::BodyStream.
Definition http.hpp:325
Url & GetUrl()
Get URL.
Definition http.hpp:337
Azure::Nullable< std::string > GetHeader(std::string const &name)
Gets a specific HTTP header from an Azure::Core::Http::Request.
Definition request.cpp:38
HttpMethod const & GetMethod() const
Get HttpMethod.
Definition request.cpp:79
CaseInsensitiveMap GetHeaders() const
Get HTTP headers.
Definition request.cpp:81
void RemoveHeader(std::string const &name)
Remove an HTTP header.
Definition request.cpp:60
Azure::Core::IO::BodyStream * GetBodyStream()
Get HTTP body as Azure::Core::IO::BodyStream.
Definition http.hpp:319
Request(HttpMethod httpMethod, Url url, Azure::Core::IO::BodyStream *bodyStream, bool shouldBufferResponse)
Construct an Azure::Core::Http::Request.
Definition http.hpp:229
void SetHeader(std::string const &name, std::string const &value)
Set an HTTP header to the Azure::Core::Http::Request.
Definition request.cpp:52
An error while sending the HTTP request with the transport adapter.
Definition http.hpp:57
TransportException(std::string const &what)
Constructs TransportException with a message string.
Definition http.hpp:67
Used to read data to/from a service.
Definition body_stream.hpp:32
An error while trying to send a request to Azure service.
Definition exception.hpp:57
Represents the location where a request will be performed.
Definition url.hpp:46
Manages an optional contained value, i.e. a value that may or may not be present.
Definition nullable.hpp:30
Define RequestFailedException. It is used by HTTP exceptions.
HTTP status code definition.
Compute the hash value for the input binary data, using SHA256, SHA384 and SHA512.
Definition azure_assert.hpp:57
Manages an optional contained value, i.e. a value that may or may not be present.
Define the HTTP raw response.
The range of bytes within an HTTP resource.
Definition http.hpp:78
Azure::Nullable< int64_t > Length
The size of the HTTP Range.
Definition http.hpp:89
int64_t Offset
The starting point of the HTTP Range.
Definition http.hpp:83
Uniform Resource Locator (URL).