33#include < s3cpp/auth.h>
44#include < s3cpp/xml.hpp>
55
6- // ListBucketResult
6+ // ListObjects
77// https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html#API_ListObjectsV2_ResponseSyntax
88
99struct Contents_ {
@@ -28,7 +28,23 @@ struct CommonPrefix {
2828 std::string Prefix;
2929};
3030
31- struct ListBucketResult {
31+ struct GetObjectInput {
32+ std::optional<std::string> If_Match;
33+ std::optional<std::string> If_Modified_Since;
34+ std::optional<std::string> If_None_Match;
35+ std::optional<std::string> If_Unmodified_Since;
36+ std::optional<int > partNumber;
37+ std::optional<std::string> Range; // e.g. bytes=0-9
38+ std::optional<std::string> response_cache_control;
39+ std::optional<std::string> response_content_disposition;
40+ std::optional<std::string> response_content_encoding;
41+ std::optional<std::string> response_content_language;
42+ std::optional<std::string> response_content_type;
43+ std::optional<std::string> response_expires;
44+ std::optional<std::string> versionId;
45+ };
46+
47+ struct ListObjectsResult {
3248 bool IsTruncated;
3349 std::string Marker;
3450 std::string NextMarker;
@@ -47,7 +63,6 @@ struct ListBucketResult {
4763
4864// REST generic error
4965// https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#RESTErrorResponses
50- // TODO(cristian): Should we add the 3xx, 4xx, or 5xx HTTP status code
5166struct Error {
5267 std::string Code;
5368 std::string Message;
@@ -87,29 +102,31 @@ class S3Client {
87102 , addressing_style_(style) {
88103 }
89104
90- std::expected<std::string, Error> GetObject (const std::string& bucket, const std::string& key) {
91- std::string url = buildURL (bucket) + std::format (" /{}" , key);
92-
93- HttpRequest req = Client.get (url).header (" Host" , getHostHeader (bucket));
94- Signer.sign (req);
95- HttpResponse res = req.execute ();
96-
97- const std::vector<XMLNode>& XMLBody = Parser.parse (res.body ());
98-
99- if (res.status () != 200 ) {
100- return std::unexpected<Error>(deserializeError (XMLBody));
101- }
102-
103- return res.body ();
104- }
105- // TODO(cristian): HeadBucket and HeadObject
106-
107- std::expected<ListBucketResult, Error> ListObjects (const std::string& bucket) { return ListObjects (bucket, " /" , 1000 , " " ); }
108- std::expected<ListBucketResult, Error> ListObjects (const std::string& bucket, const std::string& prefix) { return ListObjects (bucket, prefix, 1000 , " " ); }
109- std::expected<ListBucketResult, Error> ListObjects (const std::string& bucket, const std::string& prefix, int maxKeys) { return ListObjects (bucket, prefix, maxKeys, " " ); }
110- std::expected<ListBucketResult, Error> ListObjects (const std::string& bucket, const std::string& prefix, int maxKeys, const std::string& continuationToken);
111-
112- std::expected<ListBucketResult, Error> deserializeListBucketResult (const std::vector<XMLNode>& nodes, const int maxKeys);
105+ // S3 operations
106+ // TODO(cristian): ListObjectsV2 missing URI params:
107+ // - Bucket
108+ // - Continuation token
109+ // - Delimiter
110+ // - EncodingType
111+ // - ExpectedBucketOwner
112+ // - FetchOwner
113+ // - MaxKeys
114+ // - OptionalObjectAttributes
115+ // - Prefix
116+ // - RequestPayer
117+ // - StartAfter
118+ std::expected<ListObjectsResult, Error> ListObjects (const std::string& bucket) { return ListObjects (bucket, " /" , 1000 , " " ); }
119+ std::expected<ListObjectsResult, Error> ListObjects (const std::string& bucket, const std::string& prefix) { return ListObjects (bucket, prefix, 1000 , " " ); }
120+ std::expected<ListObjectsResult, Error> ListObjects (const std::string& bucket, const std::string& prefix, int maxKeys) { return ListObjects (bucket, prefix, maxKeys, " " ); }
121+ std::expected<ListObjectsResult, Error> ListObjects (const std::string& bucket, const std::string& prefix, int maxKeys, const std::string& continuationToken);
122+
123+ std::expected<std::string, Error> GetObject (const std::string& bucket, const std::string& key);
124+ std::expected<std::string, Error> GetObject (const std::string& bucket, const std::string& key, const GetObjectInput& opt);
125+ // TODO(cristian): Add all overloading needed for different params
126+ // TODO(cristian): HeadBucket and HeadObject, PutObject, CreateBucket
127+
128+ // S3 responses
129+ std::expected<ListObjectsResult, Error> deserializeListBucketResult (const std::vector<XMLNode>& nodes, const int maxKeys);
113130 Error deserializeError (const std::vector<XMLNode>& nodes);
114131
115132private:
@@ -153,7 +170,7 @@ class ListObjectsPaginator {
153170
154171 bool HasMorePages () const { return hasMorePages_; }
155172
156- std::expected<ListBucketResult , Error> NextPage () {
173+ std::expected<ListObjectsResult , Error> NextPage () {
157174 auto response = client_.ListObjects (bucket_, prefix_, maxKeys_, continuationToken_);
158175 if (response.has_value ()) {
159176 hasMorePages_ = response.value ().IsTruncated ;
0 commit comments