|
6 | 6 | #include <aws/s3-transfer/S3Transfer_EXPORTS.h> |
7 | 7 | #include <aws/s3-transfer/ProgressListener.h> |
8 | 8 | #include <aws/s3-transfer/DownloadDataReceiver.h> |
| 9 | +#include <aws/core/client/AWSError.h> |
9 | 10 | #include <aws/core/utils/DateTime.h> |
| 11 | +#include <aws/core/utils/memory/AWSMemory.h> |
10 | 12 | #include <aws/core/utils/memory/stl/AWSString.h> |
11 | 13 | #include <aws/core/utils/memory/stl/AWSVector.h> |
| 14 | +#include <aws/crt/http/HttpRequestResponse.h> |
| 15 | +#include <aws/crt/s3/S3.h> |
| 16 | +#include <aws/s3/S3Errors.h> |
12 | 17 | #include <aws/s3/model/ChecksumMode.h> |
13 | 18 | #include <aws/s3/model/GetObjectRequest.h> |
14 | 19 | #include <aws/s3/model/RequestPayer.h> |
15 | | -#include <cassert> |
16 | 20 | #include <memory> |
17 | | -#include <utility> |
18 | 21 |
|
19 | 22 | namespace Aws { |
20 | 23 | namespace S3 { |
21 | 24 | namespace Transfer { |
22 | 25 |
|
23 | | -/** |
24 | | - * Request type for S3TransferManager::Download. Bucket, key, and the download destination (either |
25 | | - * a file path or a zero-copy DownloadDataReceiver) are required at construction time; the two |
26 | | - * constructors make the destination-kind choice exclusive so an invalid request is |
27 | | - * unconstructable. All other S3-level fields (version id, range constraints, SSE, etc.) are |
28 | | - * optional and set via the setters below; the customer does not construct a GetObjectRequest. |
29 | | - * Reads go through GetS3Request(). |
30 | | - */ |
31 | | -class AWS_S3_TRANSFER_API DownloadRequest final { |
32 | | - public: |
33 | | - // File download. |
34 | | - explicit DownloadRequest( |
35 | | - Aws::String bucket, |
36 | | - Aws::String key, |
37 | | - Aws::String destinationFilePath, |
38 | | - Aws::Vector<std::shared_ptr<DownloadProgressListener>> transferListeners = {}) |
39 | | - : m_destinationFilePath(std::move(destinationFilePath)), |
40 | | - m_transferListeners(std::move(transferListeners)) { |
41 | | - assert(!bucket.empty() && "DownloadRequest bucket must not be empty"); |
42 | | - assert(!key.empty() && "DownloadRequest key must not be empty"); |
43 | | - assert(!m_destinationFilePath.empty() && "DownloadRequest destination file path must not be empty"); |
44 | | - m_s3Request.SetBucket(std::move(bucket)); |
45 | | - m_s3Request.SetKey(std::move(key)); |
46 | | - } |
47 | | - |
48 | | - // Zero-copy stream download. Each part is delivered to the receiver in object order. |
49 | | - explicit DownloadRequest( |
50 | | - Aws::String bucket, |
51 | | - Aws::String key, |
52 | | - std::shared_ptr<DownloadDataReceiver> dataReceiver, |
53 | | - Aws::Vector<std::shared_ptr<DownloadProgressListener>> transferListeners = {}) |
54 | | - : m_dataReceiver(std::move(dataReceiver)), |
55 | | - m_transferListeners(std::move(transferListeners)) { |
56 | | - assert(!bucket.empty() && "DownloadRequest bucket must not be empty"); |
57 | | - assert(!key.empty() && "DownloadRequest key must not be empty"); |
58 | | - assert(m_dataReceiver && "DownloadRequest data receiver must not be null"); |
59 | | - m_s3Request.SetBucket(std::move(bucket)); |
60 | | - m_s3Request.SetKey(std::move(key)); |
61 | | - } |
62 | | - |
63 | | - inline const Aws::String& GetDestinationFilePath() const { return m_destinationFilePath; } |
64 | | - inline const std::shared_ptr<DownloadDataReceiver>& GetDownloadDataReceiver() const { return m_dataReceiver; } |
65 | | - inline const Aws::Vector<std::shared_ptr<DownloadProgressListener>>& GetTransferListeners() const { |
66 | | - return m_transferListeners; |
67 | | - } |
68 | | - |
69 | | - // Bucket and key are set at construction time and cannot be changed; see the constructors above. |
70 | | - // Read these fields back via GetS3Request(). |
71 | | - inline DownloadRequest& SetChecksumMode(Aws::S3::Model::ChecksumMode v) { m_s3Request.SetChecksumMode(v); return *this; } |
72 | | - |
73 | | - inline DownloadRequest& SetExpectedBucketOwner(Aws::String v) { m_s3Request.SetExpectedBucketOwner(std::move(v)); return *this; } |
74 | | - |
75 | | - inline DownloadRequest& SetIfMatch(Aws::String v) { m_s3Request.SetIfMatch(std::move(v)); return *this; } |
76 | | - |
77 | | - inline DownloadRequest& SetIfModifiedSince(Aws::Utils::DateTime v) { m_s3Request.SetIfModifiedSince(std::move(v)); return *this; } |
78 | | - |
79 | | - inline DownloadRequest& SetIfNoneMatch(Aws::String v) { m_s3Request.SetIfNoneMatch(std::move(v)); return *this; } |
80 | | - |
81 | | - inline DownloadRequest& SetIfUnmodifiedSince(Aws::Utils::DateTime v) { m_s3Request.SetIfUnmodifiedSince(std::move(v)); return *this; } |
82 | | - |
83 | | - // HTTP Range header (e.g. "bytes=0-999"). Not in the SEP field list but needed for byte-range |
84 | | - // downloads. |
85 | | - inline DownloadRequest& SetRange(Aws::String v) { m_s3Request.SetRange(std::move(v)); return *this; } |
86 | | - |
87 | | - inline DownloadRequest& SetRequestPayer(Aws::S3::Model::RequestPayer v) { m_s3Request.SetRequestPayer(v); return *this; } |
| 26 | +struct DownloadTransferState; |
88 | 27 |
|
89 | | - inline DownloadRequest& SetResponseCacheControl(Aws::String v) { m_s3Request.SetResponseCacheControl(std::move(v)); return *this; } |
| 28 | +namespace Internal { |
| 29 | +class DownloadRequestImpl; |
| 30 | +} |
90 | 31 |
|
91 | | - inline DownloadRequest& SetResponseContentDisposition(Aws::String v) { m_s3Request.SetResponseContentDisposition(std::move(v)); return *this; } |
92 | | - |
93 | | - inline DownloadRequest& SetResponseContentEncoding(Aws::String v) { m_s3Request.SetResponseContentEncoding(std::move(v)); return *this; } |
94 | | - |
95 | | - inline DownloadRequest& SetResponseContentLanguage(Aws::String v) { m_s3Request.SetResponseContentLanguage(std::move(v)); return *this; } |
96 | | - |
97 | | - inline DownloadRequest& SetResponseContentType(Aws::String v) { m_s3Request.SetResponseContentType(std::move(v)); return *this; } |
98 | | - |
99 | | - inline DownloadRequest& SetResponseExpires(Aws::Utils::DateTime v) { m_s3Request.SetResponseExpires(std::move(v)); return *this; } |
100 | | - |
101 | | - inline DownloadRequest& SetSSECustomerAlgorithm(Aws::String v) { m_s3Request.SetSSECustomerAlgorithm(std::move(v)); return *this; } |
102 | | - |
103 | | - inline DownloadRequest& SetSSECustomerKey(Aws::String v) { m_s3Request.SetSSECustomerKey(std::move(v)); return *this; } |
104 | | - |
105 | | - inline DownloadRequest& SetSSECustomerKeyMD5(Aws::String v) { m_s3Request.SetSSECustomerKeyMD5(std::move(v)); return *this; } |
106 | | - |
107 | | - inline DownloadRequest& SetVersionId(Aws::String v) { m_s3Request.SetVersionId(std::move(v)); return *this; } |
108 | | - |
109 | | - // Read the assembled S3 request. Use this to inspect any field set via the setters above, |
110 | | - // or bucket/key set at construction time. |
111 | | - inline const Aws::S3::Model::GetObjectRequest& GetS3Request() const { return m_s3Request; } |
| 32 | +// Request type for S3TransferManager::Download. Move-only; pass with std::move. |
| 33 | +class AWS_S3_TRANSFER_API DownloadRequest final { |
| 34 | + public: |
| 35 | + DownloadRequest(Aws::String bucket, |
| 36 | + Aws::String key, |
| 37 | + Aws::String destinationFilePath, |
| 38 | + Aws::Vector<std::shared_ptr<DownloadProgressListener>> transferListeners = {}); |
| 39 | + |
| 40 | + DownloadRequest(Aws::String bucket, |
| 41 | + Aws::String key, |
| 42 | + std::shared_ptr<DownloadDataReceiver> dataReceiver, |
| 43 | + Aws::Vector<std::shared_ptr<DownloadProgressListener>> transferListeners = {}); |
| 44 | + |
| 45 | + ~DownloadRequest(); |
| 46 | + |
| 47 | + DownloadRequest(const DownloadRequest&) = delete; |
| 48 | + DownloadRequest& operator=(const DownloadRequest&) = delete; |
| 49 | + DownloadRequest(DownloadRequest&&) noexcept; |
| 50 | + DownloadRequest& operator=(DownloadRequest&&) noexcept; |
| 51 | + |
| 52 | + const Aws::Vector<std::shared_ptr<DownloadProgressListener>>& GetTransferListeners() const { return m_transferListeners; } |
| 53 | + const Aws::String& GetDestinationFilePath() const { return m_destinationFilePath; } |
| 54 | + const Aws::String& GetTempFilePath() const { return m_tempFilePath; } |
| 55 | + const std::shared_ptr<DownloadDataReceiver>& GetDataReceiver() const { return m_dataReceiver; } |
| 56 | + |
| 57 | + DownloadRequest& SetChecksumMode(Aws::S3::Model::ChecksumMode v) { m_s3Request.SetChecksumMode(v); return *this; } |
| 58 | + DownloadRequest& SetExpectedBucketOwner(Aws::String v) { m_s3Request.SetExpectedBucketOwner(std::move(v)); return *this; } |
| 59 | + DownloadRequest& SetIfMatch(Aws::String v) { m_s3Request.SetIfMatch(std::move(v)); return *this; } |
| 60 | + DownloadRequest& SetIfModifiedSince(Aws::Utils::DateTime v) { m_s3Request.SetIfModifiedSince(std::move(v)); return *this; } |
| 61 | + DownloadRequest& SetIfNoneMatch(Aws::String v) { m_s3Request.SetIfNoneMatch(std::move(v)); return *this; } |
| 62 | + DownloadRequest& SetIfUnmodifiedSince(Aws::Utils::DateTime v) { m_s3Request.SetIfUnmodifiedSince(std::move(v)); return *this; } |
| 63 | + DownloadRequest& SetRange(Aws::String v) { m_s3Request.SetRange(std::move(v)); return *this; } |
| 64 | + DownloadRequest& SetRequestPayer(Aws::S3::Model::RequestPayer v) { m_s3Request.SetRequestPayer(v); return *this; } |
| 65 | + DownloadRequest& SetResponseCacheControl(Aws::String v) { m_s3Request.SetResponseCacheControl(std::move(v)); return *this; } |
| 66 | + DownloadRequest& SetResponseContentDisposition(Aws::String v) { m_s3Request.SetResponseContentDisposition(std::move(v)); return *this; } |
| 67 | + DownloadRequest& SetResponseContentEncoding(Aws::String v) { m_s3Request.SetResponseContentEncoding(std::move(v)); return *this; } |
| 68 | + DownloadRequest& SetResponseContentLanguage(Aws::String v) { m_s3Request.SetResponseContentLanguage(std::move(v)); return *this; } |
| 69 | + DownloadRequest& SetResponseContentType(Aws::String v) { m_s3Request.SetResponseContentType(std::move(v)); return *this; } |
| 70 | + DownloadRequest& SetResponseExpires(Aws::Utils::DateTime v) { m_s3Request.SetResponseExpires(std::move(v)); return *this; } |
| 71 | + DownloadRequest& SetSSECustomerAlgorithm(Aws::String v) { m_s3Request.SetSSECustomerAlgorithm(std::move(v)); return *this; } |
| 72 | + DownloadRequest& SetSSECustomerKey(Aws::String v) { m_s3Request.SetSSECustomerKey(std::move(v)); return *this; } |
| 73 | + DownloadRequest& SetSSECustomerKeyMD5(Aws::String v) { m_s3Request.SetSSECustomerKeyMD5(std::move(v)); return *this; } |
| 74 | + DownloadRequest& SetVersionId(Aws::String v) { m_s3Request.SetVersionId(std::move(v)); return *this; } |
| 75 | + |
| 76 | + const Aws::S3::Model::GetObjectRequest& GetS3Request() const { return m_s3Request; } |
| 77 | + |
| 78 | + Aws::Client::AWSError<Aws::S3::S3Errors> Validate() const; |
| 79 | + Aws::Crt::ScopedResource<Aws::Crt::S3::S3MetaRequestOptions> MakeMetaRequestOptions( |
| 80 | + std::shared_ptr<Aws::Crt::Http::HttpRequest> crtRequest, |
| 81 | + const std::shared_ptr<const DownloadTransferState>& state) const; |
| 82 | + Aws::Client::AWSError<Aws::S3::S3Errors> FinalizeOnSuccess( |
| 83 | + const std::shared_ptr<DownloadTransferState>& state) const; |
| 84 | + void CleanupOnFailure(const std::shared_ptr<DownloadTransferState>& state) const; |
112 | 85 |
|
113 | 86 | private: |
114 | 87 | Aws::S3::Model::GetObjectRequest m_s3Request; |
| 88 | + Aws::Vector<std::shared_ptr<DownloadProgressListener>> m_transferListeners; |
115 | 89 | Aws::String m_destinationFilePath; |
| 90 | + Aws::String m_tempFilePath; |
116 | 91 | std::shared_ptr<DownloadDataReceiver> m_dataReceiver; |
117 | | - Aws::Vector<std::shared_ptr<DownloadProgressListener>> m_transferListeners; |
| 92 | + Aws::UniquePtr<Internal::DownloadRequestImpl> m_strategy; |
118 | 93 | }; |
119 | 94 |
|
120 | 95 | } // namespace Transfer |
|
0 commit comments