azure-core
Loading...
Searching...
No Matches
policy.hpp
Go to the documentation of this file.
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
9#pragma once
10
14#include "azure/core/dll_import_export.hpp"
17#include "azure/core/internal/http/http_sanitizer.hpp"
19#include "azure/core/uuid.hpp"
20
21#include <atomic>
22#include <chrono>
23#include <cstddef>
24#include <map>
25#include <memory>
26#include <mutex>
27#include <set>
28#include <shared_mutex>
29#include <string>
30#include <utility>
31#include <vector>
32
40extern std::shared_ptr<Azure::Core::Http::HttpTransport> AzureSdkGetCustomHttpTransport();
41
42namespace Azure { namespace Core { namespace Http { namespace Policies {
43
44 struct TransportOptions;
45 namespace _detail {
46 std::shared_ptr<HttpTransport> GetTransportAdapter(TransportOptions const& transportOptions);
47
48 AZ_CORE_DLLEXPORT extern std::set<std::string> const g_defaultAllowedHttpQueryParameters;
49 AZ_CORE_DLLEXPORT extern CaseInsensitiveSet const g_defaultAllowedHttpHeaders;
50 } // namespace _detail
51
56 struct TelemetryOptions final
57 {
65 std::string ApplicationId;
66
71 std::shared_ptr<Azure::Core::Tracing::TracerProvider> TracingProvider;
72 };
73
80 struct RetryOptions final
81 {
86 int32_t MaxRetries = 3;
87
93 std::chrono::milliseconds RetryDelay = std::chrono::milliseconds(800);
94
100 std::chrono::milliseconds MaxRetryDelay = std::chrono::seconds(60);
101
106 std::set<HttpStatusCode> StatusCodes{
107 HttpStatusCode::RequestTimeout,
108 HttpStatusCode::InternalServerError,
109 HttpStatusCode::BadGateway,
110 HttpStatusCode::ServiceUnavailable,
111 HttpStatusCode::GatewayTimeout,
112 };
113 };
114
120 struct LogOptions final
121 {
126 std::set<std::string> AllowedHttpQueryParameters = _detail::g_defaultAllowedHttpQueryParameters;
127
132 CaseInsensitiveSet AllowedHttpHeaders = _detail::g_defaultAllowedHttpHeaders;
133 };
134
138 struct TransportOptions final
139 {
150
158
166
176
189
202
221 std::shared_ptr<HttpTransport> Transport;
222 };
223
224 class NextHttpPolicy;
225
233 public:
234 // If we get a response that goes up the stack
235 // Any errors in the pipeline throws an exception
236 // At the top of the pipeline we might want to turn certain responses into exceptions
237
248 virtual std::unique_ptr<RawResponse> Send(
249 Request& request,
250 NextHttpPolicy nextPolicy,
251 Context const& context) const = 0;
252
257 virtual ~HttpPolicy() {}
258
263 virtual std::unique_ptr<HttpPolicy> Clone() const = 0;
264
265 protected:
270 HttpPolicy() = default;
271
277 HttpPolicy(const HttpPolicy& other) = default;
278
285 HttpPolicy& operator=(const HttpPolicy& other) = default;
286
292 HttpPolicy(HttpPolicy&& other) = default;
293 };
294
304 class NextHttpPolicy final {
305 const size_t m_index;
306 const std::vector<std::unique_ptr<HttpPolicy>>& m_policies;
307
308 public:
317 explicit NextHttpPolicy(size_t index, const std::vector<std::unique_ptr<HttpPolicy>>& policies)
318 : m_index(index), m_policies(policies)
319 {
320 }
321
331 std::unique_ptr<RawResponse> Send(Request& request, Context const& context);
332 };
333
334 namespace _internal {
335
340 class TransportPolicy final : public HttpPolicy {
341 private:
342 TransportOptions m_options;
343
344 public:
350 explicit TransportPolicy(TransportOptions const& options = TransportOptions());
351
352 std::unique_ptr<HttpPolicy> Clone() const override
353 {
354 return std::make_unique<TransportPolicy>(*this);
355 }
356
357 std::unique_ptr<RawResponse> Send(
358 Request& request,
359 NextHttpPolicy nextPolicy,
360 Context const& context) const override;
361 };
362
366 class RetryPolicy
367#if !defined(_azure_TESTING_BUILD)
368 final
369#endif
370 : public HttpPolicy {
371 private:
372 RetryOptions m_retryOptions;
373
374 public:
380 explicit RetryPolicy(RetryOptions options) : m_retryOptions(std::move(options)) {}
381
382 std::unique_ptr<HttpPolicy> Clone() const override
383 {
384 return std::make_unique<RetryPolicy>(*this);
385 }
386
387 std::unique_ptr<RawResponse> Send(
388 Request& request,
389 NextHttpPolicy nextPolicy,
390 Context const& context) const final;
391
403 static int32_t GetRetryCount(Context const& context);
404
405 protected:
406 virtual bool ShouldRetryOnTransportFailure(
407 RetryOptions const& retryOptions,
408 int32_t attempt,
409 std::chrono::milliseconds& retryAfter,
410 double jitterFactor = -1) const;
411
412 virtual bool ShouldRetryOnResponse(
413 RawResponse const& response,
414 RetryOptions const& retryOptions,
415 int32_t attempt,
416 std::chrono::milliseconds& retryAfter,
417 double jitterFactor = -1) const;
418 };
419
426 class RequestIdPolicy final : public HttpPolicy {
427 private:
428 constexpr static const char* RequestIdHeader = "x-ms-client-request-id";
429
430 public:
435 explicit RequestIdPolicy() {}
436
437 std::unique_ptr<HttpPolicy> Clone() const override
438 {
439 return std::make_unique<RequestIdPolicy>(*this);
440 }
441
442 std::unique_ptr<RawResponse> Send(
443 Request& request,
444 NextHttpPolicy nextPolicy,
445 Context const& context) const override
446 {
447 if (!request.GetHeader(RequestIdHeader).HasValue())
448 {
449 auto const uuid = Uuid::CreateUuid().ToString();
450 request.SetHeader(RequestIdHeader, uuid);
451 }
452
453 return nextPolicy.Send(request, context);
454 }
455 };
456
465 class RequestActivityPolicy final : public HttpPolicy {
466 private:
467 Azure::Core::Http::_internal::HttpSanitizer m_httpSanitizer;
468
469 public:
473 // explicit RequestActivityPolicy() = default;
479 explicit RequestActivityPolicy(
480 Azure::Core::Http::_internal::HttpSanitizer const& httpSanitizer)
481 : m_httpSanitizer(httpSanitizer)
482 {
483 }
484
485 std::unique_ptr<HttpPolicy> Clone() const override
486 {
487 return std::make_unique<RequestActivityPolicy>(*this);
488 }
489
490 std::unique_ptr<RawResponse> Send(
491 Request& request,
492 NextHttpPolicy nextPolicy,
493 Context const& context) const override;
494 };
495
509 class TelemetryPolicy final : public HttpPolicy {
510 private:
511 std::string const m_telemetryId;
512
513 public:
521 explicit TelemetryPolicy(
522 std::string const& packageName,
523 std::string const& packageVersion,
524 TelemetryOptions options = TelemetryOptions())
525 : m_telemetryId(Azure::Core::Http::_detail::UserAgentGenerator::GenerateUserAgent(
526 packageName,
527 packageVersion,
528 options.ApplicationId))
529 {
530 }
531
532 std::unique_ptr<HttpPolicy> Clone() const override
533 {
534 return std::make_unique<TelemetryPolicy>(*this);
535 }
536
537 std::unique_ptr<RawResponse> Send(
538 Request& request,
539 NextHttpPolicy nextPolicy,
540 Context const& context) const override;
541 };
542
547 class BearerTokenAuthenticationPolicy : public HttpPolicy {
548 private:
549 std::shared_ptr<Credentials::TokenCredential const> const m_credential;
550 Credentials::TokenRequestContext m_tokenRequestContext;
551
552 mutable Credentials::AccessToken m_accessToken;
553 mutable std::shared_timed_mutex m_accessTokenMutex;
554 mutable Credentials::TokenRequestContext m_accessTokenContext;
555
556 public:
563 explicit BearerTokenAuthenticationPolicy(
564 std::shared_ptr<Credentials::TokenCredential const> credential,
565 Credentials::TokenRequestContext tokenRequestContext)
566 : m_credential(std::move(credential)),
567 m_tokenRequestContext(std::move(tokenRequestContext))
568 {
569 }
570
571 std::unique_ptr<HttpPolicy> Clone() const override
572 {
573 // Can't use std::make_shared here because copy constructor is not public.
574 return std::unique_ptr<HttpPolicy>(new BearerTokenAuthenticationPolicy(*this));
575 }
576
577 std::unique_ptr<RawResponse> Send(
578 Request& request,
579 NextHttpPolicy nextPolicy,
580 Context const& context) const override;
581
582 protected:
583 BearerTokenAuthenticationPolicy(BearerTokenAuthenticationPolicy const& other)
584 : BearerTokenAuthenticationPolicy(other.m_credential, other.m_tokenRequestContext)
585 {
586 std::shared_lock<std::shared_timed_mutex> readLock(other.m_accessTokenMutex);
587 m_accessToken = other.m_accessToken;
588 m_accessTokenContext = other.m_accessTokenContext;
589 }
590
591 void operator=(BearerTokenAuthenticationPolicy const&) = delete;
592
593 virtual std::unique_ptr<RawResponse> AuthorizeAndSendRequest(
594 Request& request,
595 NextHttpPolicy& nextPolicy,
596 Context const& context) const;
597
598 virtual bool AuthorizeRequestOnChallenge(
599 std::string const& challenge,
600 Request& request,
601 Context const& context) const;
602
603 void AuthenticateAndAuthorizeRequest(
604 Request& request,
605 Credentials::TokenRequestContext const& tokenRequestContext,
606 Context const& context) const;
607 };
608
615 class LogPolicy final : public HttpPolicy {
616 LogOptions m_options;
617 Azure::Core::Http::_internal::HttpSanitizer m_httpSanitizer;
618
619 public:
624 explicit LogPolicy(LogOptions options)
625 : m_options(std::move(options)),
626 m_httpSanitizer(m_options.AllowedHttpQueryParameters, m_options.AllowedHttpHeaders)
627 {
628 }
629
630 std::unique_ptr<HttpPolicy> Clone() const override
631 {
632 return std::make_unique<LogPolicy>(*this);
633 }
634
635 std::unique_ptr<RawResponse> Send(
636 Request& request,
637 NextHttpPolicy nextPolicy,
638 Context const& context) const override;
639 };
640 } // namespace _internal
641}}}} // namespace Azure::Core::Http::Policies
A map<string, string> with case-insensitive key comparison.
std::set< std::string, _internal::StringExtensions::CaseInsensitiveComparator > CaseInsensitiveSet
A type alias of std::set<std::string> with case-insensitive element comparison.
Definition case_insensitive_containers.hpp:31
A context is a node within a tree that represents deadlines and key/value pairs.
Definition context.hpp:46
HTTP policy base class.
Definition policy.hpp:232
virtual ~HttpPolicy()
Destructs HttpPolicy.
Definition policy.hpp:257
HttpPolicy()=default
Constructs a default instance of HttpPolicy.
HttpPolicy & operator=(const HttpPolicy &other)=default
Assigns this HttpPolicy to copy the other.
virtual std::unique_ptr< HttpPolicy > Clone() const =0
Creates a clone of this HttpPolicy.
HttpPolicy(HttpPolicy &&other)=default
Constructs HttpPolicy by moving other HttpPolicy.
HttpPolicy(const HttpPolicy &other)=default
Constructs a copy of other HttpPolicy.
virtual std::unique_ptr< RawResponse > Send(Request &request, NextHttpPolicy nextPolicy, Context const &context) const =0
Applies this HTTP policy.
The next HTTP policy in the stack sequence of policies.
Definition policy.hpp:304
NextHttpPolicy(size_t index, const std::vector< std::unique_ptr< HttpPolicy > > &policies)
Constructs an abstraction representing a next line in the stack sequence of policies,...
Definition policy.hpp:317
std::unique_ptr< RawResponse > Send(Request &request, Context const &context)
Applies this HTTP policy.
Definition policy.cpp:14
A request message from a client to a server.
Definition http.hpp:182
std::string ToString()
Gets Uuid as a string.
Definition uuid.cpp:20
static Uuid CreateUuid()
Creates a new random UUID.
Definition uuid.cpp:50
Manages an optional contained value, i.e. a value that may or may not be present.
Definition nullable.hpp:30
Context for canceling long running operations.
Credentials used for authentication with many (not all) Azure SDK client libraries.
HTTP request and response functionality.
Compute the hash value for the input binary data, using SHA256, SHA384 and SHA512.
Definition azure_assert.hpp:57
std::shared_ptr< Azure::Core::Http::HttpTransport > AzureSdkGetCustomHttpTransport()
Log options that parameterize the information being logged.
Definition policy.hpp:121
std::set< std::string > AllowedHttpQueryParameters
HTTP query parameter names that are allowed to be logged.
Definition policy.hpp:126
CaseInsensitiveSet AllowedHttpHeaders
HTTP header names that are allowed to be logged.
Definition policy.hpp:132
The set of options that can be specified to influence how retry attempts are made,...
Definition policy.hpp:81
std::chrono::milliseconds RetryDelay
The minimum permissible delay between retry attempts.
Definition policy.hpp:93
int32_t MaxRetries
The maximum number of retry attempts before giving up.
Definition policy.hpp:86
std::chrono::milliseconds MaxRetryDelay
The maximum permissible delay between retry attempts.
Definition policy.hpp:100
std::set< HttpStatusCode > StatusCodes
The HTTP status codes that indicate when an operation should be retried.
Definition policy.hpp:106
Telemetry options, used to configure telemetry parameters.
Definition policy.hpp:57
std::string ApplicationId
The Application ID is the last part of the user agent for telemetry.
Definition policy.hpp:65
std::shared_ptr< Azure::Core::Tracing::TracerProvider > TracingProvider
Specifies the default distributed tracing provider to use for this client. By default,...
Definition policy.hpp:71
HTTP transport options parameterize the HTTP transport adapter being used.
Definition policy.hpp:139
bool DisableTlsCertificateValidation
Disable SSL/TLS certificate verification. This option allows transport layer to perform insecure SSL/...
Definition policy.hpp:188
std::shared_ptr< HttpTransport > Transport
Azure::Core::Http::HttpTransport that the transport policy will use to send and receive requests and ...
Definition policy.hpp:221
Azure::Nullable< std::string > ProxyPassword
The password to use when authenticating with the proxy server.
Definition policy.hpp:165
bool EnableCertificateRevocationListCheck
Enable TLS Certificate validation against a certificate revocation list.
Definition policy.hpp:175
std::string ExpectedTlsRootCertificate
Base64 encoded DER representation of an X.509 certificate expected in the certificate chain used in T...
Definition policy.hpp:201
Azure::Nullable< std::string > HttpProxy
The URL for the proxy server to use for this connection.
Definition policy.hpp:149
Azure::Nullable< std::string > ProxyUserName
The username to use when authenticating with the proxy server.
Definition policy.hpp:157
Utilities to be used by HTTP transport implementations.
Declaration of the UserAgentGenerator type.
Universally unique identifier.