aws-crt-cpp
C++ wrapper around the aws-c-* libraries. Provides Cross-Platform Transport Protocols and SSL/TLS implementations for C++.
S3.h
Go to the documentation of this file.
1 #pragma once
2 
7 #include <aws/crt/Exports.h>
8 #include <aws/crt/Optional.h>
9 #include <aws/crt/Types.h>
13 #include <aws/crt/io/TlsOptions.h>
14 #include <aws/crt/io/Uri.h>
16 
17 #include <cstdint>
18 #include <functional>
19 #include <future>
20 #include <memory>
21 
22 struct aws_s3_client;
23 struct aws_s3_client_config;
24 struct aws_s3_meta_request;
25 struct aws_s3_meta_request_options;
26 struct aws_retry_strategy;
27 
28 namespace Aws
29 {
30  namespace Crt
31  {
32  namespace Auth
33  {
34  class ICredentialsProvider;
35  }
36 
37  namespace S3
38  {
44  // Mapped to their aws-c-s3 counterparts by a switch in S3.cpp.
45  enum class S3MetaRequestType
46  {
47  Default,
48  GetObject,
49  PutObject,
50  CopyObject,
51  };
52 
58  enum class S3ChecksumLocation
59  {
60  None,
61  Header,
62  Trailer,
63  };
64 
70  {
71  None,
72  Crc32c,
73  Crc32,
74  Sha1,
75  Sha256,
76  Crc64Nvme,
77  Sha512,
78  XXHash64,
79  XXHash3_64,
81  };
82 
88  enum class S3TlsMode
89  {
90  Enabled,
91  Disabled,
92  };
93 
100  enum class S3RecvFileMode
101  {
105  CreateNew,
113  };
114 
121  {
123  Default,
125  Standard,
129  NoRetry,
130  };
131 
145  {
151  size_t maxRetries = 0;
153  uint32_t scaleFactorMs = 500;
155  uint32_t maxBackoffSecs = 20;
156  };
157 
169  {
170  public:
171  S3RetryStrategy(const S3RetryStrategy &) = delete;
172  S3RetryStrategy &operator=(const S3RetryStrategy &) = delete;
173  S3RetryStrategy(S3RetryStrategy &&other) noexcept = default;
174  S3RetryStrategy &operator=(S3RetryStrategy &&other) noexcept = default;
175  ~S3RetryStrategy() noexcept = default;
176 
182  static S3RetryStrategy CreateStandard() noexcept;
183 
192  static S3RetryStrategy CreateExponentialBackoff(
193  Io::EventLoopGroup &elGroup,
194  const S3RetryStrategyExponentialBackoffOptions &options = {}) noexcept;
195 
201  static S3RetryStrategy CreateNoRetry() noexcept;
202 
206  explicit operator bool() const noexcept { return m_strategy != nullptr; }
207 
210  explicit S3RetryStrategy(aws_retry_strategy *strategy) noexcept;
211 
213  aws_retry_strategy *GetUnderlyingHandle() const noexcept { return m_strategy.get(); }
214 
215  private:
217  };
218 
219  class S3Client;
220  class S3MetaRequest;
221  class S3MetaRequestOptions;
222 
231  {
234 
236  bool IsSuccess() const noexcept;
237 
240  int responseStatus;
241 
243  Vector<Http::HttpHeader> errorResponseHeaders;
244 
251  ByteCursor errorResponseBody;
252 
254  bool didValidateChecksum;
255 
257  S3ChecksumAlgorithm validationAlgorithm;
258  };
259 
267  {
268  public:
269  S3ChecksumConfig() noexcept;
270 
278  {
279  m_location = location;
280  return *this;
281  }
282 
290  {
291  m_algorithm = algorithm;
292  return *this;
293  }
294 
303  {
304  m_validateResponseChecksum = validate;
305  return *this;
306  }
307 
311  S3ChecksumLocation GetLocation() const noexcept { return m_location; }
312 
316  S3ChecksumAlgorithm GetChecksumAlgorithm() const noexcept { return m_algorithm; }
317 
321  bool GetValidateResponseChecksum() const noexcept { return m_validateResponseChecksum; }
322 
323  private:
324  S3ChecksumLocation m_location;
325  S3ChecksumAlgorithm m_algorithm;
326  bool m_validateResponseChecksum;
327  };
328 
338  {
339  public:
340  S3ClientConfig(const S3ClientConfig &) = delete;
341  S3ClientConfig(S3ClientConfig &&) = delete;
342  S3ClientConfig &operator=(const S3ClientConfig &) = delete;
343  S3ClientConfig &operator=(S3ClientConfig &&) = delete;
344 
365  explicit S3ClientConfig(
366  const std::shared_ptr<Auth::ICredentialsProvider> &credentialsProvider) noexcept;
367 
368  // Defined out-of-line in S3.cpp where Impl is a complete type
369  // (required to destroy the ScopedResource<Impl> pImpl member).
370  ~S3ClientConfig() noexcept;
371 
379  S3ClientConfig &SetRegion(const Crt::String &region) noexcept;
380 
388  S3ClientConfig &SetThroughputTargetGbps(double gbps) noexcept;
389 
399  S3ClientConfig &SetPartSize(uint64_t bytes) noexcept;
400 
406  S3ClientConfig &SetMultipartUploadThreshold(uint64_t bytes) noexcept;
407 
415  S3ClientConfig &SetMemoryLimit(uint64_t bytes) noexcept;
416 
425  S3ClientConfig &SetClientBootstrap(Io::ClientBootstrap &bootstrap) noexcept;
426 
431  S3ClientConfig &SetConnectTimeoutMs(uint32_t timeoutMs) noexcept;
432 
444  S3ClientConfig &SetReadBackpressure(bool enable, uint64_t initialReadWindow) noexcept;
445 
454  S3ClientConfig &SetEnableS3Express(bool enable) noexcept;
455 
464  S3ClientConfig &SetTlsMode(S3TlsMode mode) noexcept;
465 
474  S3ClientConfig &SetTlsConnectionOptions(const Io::TlsConnectionOptions &options) noexcept;
475 
483  S3ClientConfig &SetProxyOptions(const Http::HttpClientConnectionProxyOptions &proxyOptions) noexcept;
484 
494  S3ClientConfig &SetTcpKeepAlive(uint16_t keepAliveIntervalSec, uint16_t keepAliveTimeoutSec) noexcept;
495 
505  S3ClientConfig &SetConnectionMonitoring(
506  uint64_t minimumThroughputBytesPerSecond,
507  uint32_t allowableThroughputFailureIntervalSeconds) noexcept;
508 
523  S3ClientConfig &SetNetworkInterfaceNames(const Vector<String> &networkInterfaceNames) noexcept;
524 
536  S3ClientConfig &SetRetryStrategy(
537  S3RetryStrategyType type,
538  const S3RetryStrategyExponentialBackoffOptions &options = {}) noexcept;
539 
550  S3ClientConfig &SetRetryStrategyFactory(
551  std::function<S3RetryStrategy(const S3ClientConfig &)> factory) noexcept;
552 
566  S3ClientConfig &SetClientShutdownCallback(std::function<void()> callback) noexcept;
567 
571  struct aws_s3_client_config *GetUnderlyingHandle() const noexcept;
572 
576  String GetRegion() const noexcept { return m_region; }
577 
581  uint64_t GetPartSize() const noexcept;
582 
586  uint64_t GetMultipartUploadThreshold() const noexcept;
587 
591  double GetThroughputTargetGbps() const noexcept;
592 
596  S3RetryStrategyType GetRetryStrategyType() const noexcept { return m_retryStrategyType; }
597 
603  {
604  return m_retryStrategyOptions;
605  }
606 
611  const std::function<S3RetryStrategy(const S3ClientConfig &)> &GetRetryStrategyFactory() const noexcept
612  {
613  return m_retryStrategyFactory;
614  }
615 
620  const Vector<String> &GetNetworkInterfaceNames() const noexcept { return m_networkInterfaceNames; }
621 
626  const std::function<void()> &GetClientShutdownCallback() const noexcept
627  {
628  return m_clientShutdownCallback;
629  }
630 
634  std::shared_ptr<Auth::ICredentialsProvider> GetCredentialsProvider() const noexcept
635  {
636  return m_credentialsProvider;
637  }
638 
639  private:
640  // The CRT C-struct storage (aws_s3_client_config plus the proxy,
641  // TCP keep-alive, and connection-monitoring option backings) lives
642  // by value inside Impl, defined in S3.cpp. This keeps the C headers
643  // out of this public header and collapses what were four separate
644  // heap allocations into the single Impl allocation.
645  struct Impl;
646  ScopedResource<Impl> m_impl;
647  String m_region;
648  Optional<Io::TlsConnectionOptions> m_tlsConnectionOptions;
650  Vector<String> m_networkInterfaceNames;
651 
652  // Strategy is materialized at S3Client construction; the
653  // factory (when set) takes precedence over the enum.
654  S3RetryStrategyType m_retryStrategyType;
655  S3RetryStrategyExponentialBackoffOptions m_retryStrategyOptions;
656  std::function<S3RetryStrategy(const S3ClientConfig &)> m_retryStrategyFactory;
657 
658  std::function<void()> m_clientShutdownCallback;
659  std::shared_ptr<Auth::ICredentialsProvider> m_credentialsProvider;
660  // Held by value (no heap): single-owner, scope-bound to this
661  // config. Optional carries the "no signing config" state the
662  // ctor relies on when no credentials provider is supplied.
663  Optional<Auth::AwsSigningConfig> m_signingConfig;
664  };
665 
678  {
679  public:
680  // Callbacks return bool (continue/abort) so C++ callers don't have to name the C
681  // AWS_OP_SUCCESS sentinel; the binding translates false to an aborted meta request.
682 
689  using BodyCallback = std::function<bool(ByteCursor body, uint64_t rangeStart)>;
690 
701  using BodyCallbackEx =
702  std::function<bool(ByteCursor body, uint64_t rangeStart, S3BufferTicket &ticket)>;
703 
710  using HeadersCallback =
711  std::function<bool(const Vector<Http::HttpHeader> &headers, int responseStatus)>;
712 
718  using ProgressCallback = std::function<void(uint64_t bytesTransferred, uint64_t contentLength)>;
719 
728  using FinishCallback = std::function<void(const S3MetaRequestResult &result)>;
729 
735  using ShutdownCallback = std::function<void()>;
736 
737  S3MetaRequestOptions(const S3MetaRequestOptions &) = delete;
739  S3MetaRequestOptions &operator=(const S3MetaRequestOptions &) = delete;
740  S3MetaRequestOptions &operator=(S3MetaRequestOptions &&) = delete;
741 
742  virtual ~S3MetaRequestOptions() noexcept;
743 
755  S3MetaRequestOptions &SetSigningConfig(const Auth::AwsSigningConfig &config) noexcept;
756 
771  S3MetaRequestOptions &SetSigningConfigFromEndpoint(
772  const String &region,
773  const String &signingRegion,
774  const String &signingName,
775  bool isS3Express,
776  const std::shared_ptr<Auth::ICredentialsProvider> &provider) noexcept;
777 
784  S3MetaRequestOptions &SetChecksumConfig(const S3ChecksumConfig &config) noexcept;
785 
798  S3MetaRequestOptions &SetEndpoint(const Io::Uri &endpoint) noexcept;
799 
806  S3MetaRequestOptions &SetHeadersCallback(HeadersCallback cb) noexcept;
807 
814  S3MetaRequestOptions &SetProgressCallback(ProgressCallback cb) noexcept;
815 
823  S3MetaRequestOptions &SetFinishCallback(FinishCallback cb) noexcept;
824 
833  S3MetaRequestOptions &SetShutdownCallback(ShutdownCallback cb) noexcept;
834 
843  S3MetaRequestOptions &SetRecvFileMode(S3RecvFileMode mode) noexcept;
844 
852  S3MetaRequestOptions &SetRecvFilePosition(uint64_t position) noexcept;
853 
863  S3MetaRequestOptions &SetRecvFileDeleteOnFailure(bool deleteOnFailure) noexcept;
864 
873  S3MetaRequestOptions &SetObjectSizeHint(uint64_t bytes) noexcept;
874 
883  S3MetaRequestOptions &SetPartSize(uint64_t bytes) noexcept;
884 
894  S3MetaRequestOptions &SetMultipartUploadThreshold(uint64_t bytes) noexcept;
895 
899  struct aws_s3_meta_request_options *GetUnderlyingHandle() const noexcept;
900 
902  const BodyCallback &GetBodyCallback() const noexcept { return m_bodyCb; }
904  const BodyCallbackEx &GetBodyCallbackEx() const noexcept { return m_bodyCbEx; }
906  const HeadersCallback &GetHeadersCallback() const noexcept { return m_headersCb; }
908  const ProgressCallback &GetProgressCallback() const noexcept { return m_progressCb; }
910  const FinishCallback &GetFinishCallback() const noexcept { return m_finishCb; }
912  const ShutdownCallback &GetShutdownCallback() const noexcept { return m_shutdownCb; }
913 
919  int GetLastError() const noexcept { return m_lastError; }
920 
921  protected:
932  S3MetaRequestType type,
933  const std::shared_ptr<Http::HttpRequest> &request) noexcept;
934 
935  // The CRT C-struct storage (aws_s3_meta_request_options plus the
936  // checksum-config backing) lives by value inside Impl, defined in
937  // S3.cpp. Keeps the C headers out of this public header and
938  // collapses two heap allocations into the single Impl allocation.
939  // Protected so subclass ctors can reach it (through m_impl) to
940  // populate shape-specific fields directly rather than via a setter.
941  struct Impl;
943  std::shared_ptr<Http::HttpRequest> m_httpRequest;
947  // Endpoint override parsed in place (no heap). aws_uri's internal
948  // cursors point into its own buffer, so it must never be moved
949  // after parsing - hence a value member parsed directly, not a
950  // relocatable wrapper. m_endpointInit tracks whether it holds a
951  // parsed URI needing cleanup; m_options->endpoint being non-null
952  // is the "set" signal.
953  aws_uri m_endpoint;
955  // Backs the borrowed pointer the CRT holds via object_size_hint.
963  // Sticky validation error set by a Set* setter, surfaced at
964  // MakeMetaRequest (mirrors the MqttClient builder's LastError()).
965  int m_lastError = AWS_ERROR_SUCCESS;
966  };
967 
977  {
978  public:
983 
993  const std::shared_ptr<Http::HttpRequest> &request,
994  BodyCallback cb) noexcept;
995 
1006  const std::shared_ptr<Http::HttpRequest> &request,
1007  BodyCallbackEx cb) noexcept;
1008 
1019  const std::shared_ptr<Http::HttpRequest> &request,
1020  const Crt::String &recvFilepath) noexcept;
1021 
1024  explicit S3GetObjectMetaRequestOptions(const std::shared_ptr<Http::HttpRequest> &request) noexcept;
1025  };
1026 
1035  {
1036  public:
1039  S3PutObjectMetaRequestOptions &operator=(const S3PutObjectMetaRequestOptions &) = delete;
1041 
1050  const std::shared_ptr<Http::HttpRequest> &request) noexcept;
1051 
1062  const std::shared_ptr<Http::HttpRequest> &request,
1063  const Crt::String &sendFilepath) noexcept;
1064 
1075  static ScopedResource<S3MetaRequestOptions> CreateWithAsyncWrites(
1076  const std::shared_ptr<Http::HttpRequest> &request) noexcept;
1077 
1080  explicit S3PutObjectMetaRequestOptions(const std::shared_ptr<Http::HttpRequest> &request) noexcept;
1081  };
1082 
1089  {
1090  public:
1095 
1104  const std::shared_ptr<Http::HttpRequest> &request) noexcept;
1105 
1107  explicit S3CopyObjectMetaRequestOptions(const std::shared_ptr<Http::HttpRequest> &request) noexcept;
1108  };
1109 
1120  {
1121  public:
1126 
1136  const std::shared_ptr<Http::HttpRequest> &request,
1137  const Crt::String &operationName) noexcept;
1138 
1141  const std::shared_ptr<Http::HttpRequest> &request,
1142  const Crt::String &operationName) noexcept;
1143  };
1144 
1154  {
1155  public:
1156  S3Client(const S3Client &) = delete;
1157  S3Client(S3Client &&) = delete;
1158  S3Client &operator=(const S3Client &) = delete;
1159  S3Client &operator=(S3Client &&) = delete;
1160 
1161  explicit S3Client(const S3ClientConfig &config) noexcept;
1162  ~S3Client() noexcept = default;
1163 
1178  std::shared_ptr<S3MetaRequest> MakeMetaRequest(S3MetaRequestOptions &options) noexcept;
1179 
1194  static bool MakeDefaultSigningConfig(
1195  Auth::AwsSigningConfig &config,
1196  const String &region,
1197  const std::shared_ptr<Auth::ICredentialsProvider> &provider) noexcept;
1198 
1202  explicit operator bool() const noexcept { return m_client != nullptr; }
1203 
1209  int LastError() const noexcept;
1210 
1219  String GetRegion() const noexcept { return m_region; }
1220 
1224  uint64_t GetPartSize() const noexcept { return m_partSize; }
1225 
1229  uint64_t GetMultipartUploadThreshold() const noexcept { return m_multipartUploadThreshold; }
1230 
1234  double GetThroughputTargetGbps() const noexcept { return m_throughputTargetGbps; }
1235 
1239  std::shared_ptr<Auth::ICredentialsProvider> GetCredentialsProvider() const noexcept
1240  {
1241  return m_credentialsProvider;
1242  }
1243 
1244  private:
1246  int m_lastError;
1247  String m_region;
1248  uint64_t m_partSize = 0;
1249  uint64_t m_multipartUploadThreshold = 0;
1250  double m_throughputTargetGbps = 0.0;
1251  std::shared_ptr<Auth::ICredentialsProvider> m_credentialsProvider;
1252  };
1253 
1261  {
1262  public:
1263  S3MetaRequest(const S3MetaRequest &) = delete;
1264  S3MetaRequest(S3MetaRequest &&) = delete;
1265  S3MetaRequest &operator=(const S3MetaRequest &) = delete;
1266  S3MetaRequest &operator=(S3MetaRequest &&) = delete;
1267 
1268  ~S3MetaRequest() noexcept = default;
1269 
1275  void Cancel() noexcept;
1276 
1287  void IncrementReadWindow(uint64_t bytes) noexcept;
1288 
1301  std::future<int> Write(ByteCursor data, bool eof) noexcept;
1302 
1308  int LastError() const noexcept;
1309 
1313  S3MetaRequest() noexcept;
1314 
1318  void SetUnderlyingHandle(struct aws_s3_meta_request *handle) noexcept;
1319 
1321  void SetLastError(int errorCode) noexcept { m_lastError = errorCode; }
1322 
1323  private:
1325  int m_lastError;
1326  };
1327 
1328  } // namespace S3
1329  } // namespace Crt
1330 } // namespace Aws
S3ChecksumAlgorithm
Definition: S3.h:69
uint64_t GetMultipartUploadThreshold() const noexcept
Definition: S3.h:1229
String GetRegion() const noexcept
Definition: S3.h:576
Definition: S3.h:1260
S3ChecksumConfig & SetValidateResponseChecksum(bool validate) noexcept
Definition: S3.h:302
Definition: EventLoopGroup.h:97
S3TlsMode
Definition: S3.h:88
const std::function< S3RetryStrategy(const S3ClientConfig &)> & GetRetryStrategyFactory() const noexcept
Definition: S3.h:611
aws_uri m_endpoint
Definition: S3.h:953
int GetLastError() const noexcept
Definition: S3.h:919
std::shared_ptr< Auth::ICredentialsProvider > GetCredentialsProvider() const noexcept
Definition: S3.h:1239
const S3RetryStrategyExponentialBackoffOptions & GetRetryStrategyOptions() const noexcept
Definition: S3.h:602
uint64_t GetPartSize() const noexcept
Definition: S3.h:1224
#define AWS_CRT_CPP_API
Definition: Exports.h:36
std::function< void(const S3MetaRequestResult &result)> FinishCallback
Definition: S3.h:728
const FinishCallback & GetFinishCallback() const noexcept
Definition: S3.h:910
Definition: StringView.h:861
std::function< bool(ByteCursor body, uint64_t rangeStart)> BodyCallback
Definition: S3.h:689
std::function< void()> ShutdownCallback
Definition: S3.h:735
String m_operationName
Definition: S3.h:944
std::basic_string< char, std::char_traits< char >, StlAllocator< char >> String
Definition: Types.h:45
aws_byte_cursor ByteCursor
Definition: Types.h:31
S3ChecksumAlgorithm GetChecksumAlgorithm() const noexcept
Definition: S3.h:316
Definition: S3.h:168
FinishCallback m_finishCb
Definition: S3.h:961
const Vector< String > & GetNetworkInterfaceNames() const noexcept
Definition: S3.h:620
bool m_endpointInit
Definition: S3.h:954
const ShutdownCallback & GetShutdownCallback() const noexcept
Definition: S3.h:912
Definition: HttpConnection.h:298
const std::function< void()> & GetClientShutdownCallback() const noexcept
Definition: S3.h:626
int errorCode
Definition: S3.h:233
BodyCallbackEx m_bodyCbEx
Definition: S3.h:958
Optional< uint64_t > m_objectSizeHint
Definition: S3.h:956
S3RetryStrategyType
Definition: S3.h:120
Definition: S3.h:266
std::shared_ptr< Http::HttpRequest > m_httpRequest
Definition: S3.h:943
std::function< bool(const Vector< Http::HttpHeader > &headers, int responseStatus)> HeadersCallback
Definition: S3.h:711
std::function< bool(ByteCursor body, uint64_t rangeStart, S3BufferTicket &ticket)> BodyCallbackEx
Definition: S3.h:702
HeadersCallback m_headersCb
Definition: S3.h:959
std::function< void(uint64_t bytesTransferred, uint64_t contentLength)> ProgressCallback
Definition: S3.h:718
S3ChecksumLocation
Definition: S3.h:58
String m_sendFilepath
Definition: S3.h:945
S3ChecksumConfig & SetLocation(S3ChecksumLocation location) noexcept
Definition: S3.h:277
ProgressCallback m_progressCb
Definition: S3.h:960
ScopedResource< Impl > m_impl
Definition: S3.h:941
double GetThroughputTargetGbps() const noexcept
Definition: S3.h:1234
std::shared_ptr< Auth::ICredentialsProvider > GetCredentialsProvider() const noexcept
Definition: S3.h:634
Definition: Bootstrap.h:34
BodyCallback m_bodyCb
Definition: S3.h:957
AWS_CRT_CPP_API int LastError() noexcept
Definition: Api.cpp:469
String m_recvFilepath
Definition: S3.h:946
aws_http_header HttpHeader
Definition: HttpConnection.h:35
std::vector< T, StlAllocator< T >> Vector
Definition: Types.h:53
Definition: Sigv4Signing.h:134
bool GetValidateResponseChecksum() const noexcept
Definition: S3.h:321
Definition: S3.h:1153
S3RecvFileMode
Definition: S3.h:100
S3ChecksumLocation GetLocation() const noexcept
Definition: S3.h:311
std::unique_ptr< T, std::function< void(T *)>> ScopedResource
Definition: Types.h:168
const ProgressCallback & GetProgressCallback() const noexcept
Definition: S3.h:908
ShutdownCallback m_shutdownCb
Definition: S3.h:962
const BodyCallbackEx & GetBodyCallbackEx() const noexcept
Definition: S3.h:904
Definition: TlsOptions.h:317
Definition: S3.h:337
S3ChecksumConfig & SetChecksumAlgorithm(S3ChecksumAlgorithm algorithm) noexcept
Definition: S3.h:289
const HeadersCallback & GetHeadersCallback() const noexcept
Definition: S3.h:906
S3MetaRequestType
Definition: S3.h:45
Definition: Allocator.h:10