Skip to content

Commit 818d203

Browse files
fix: correct multipart XML CompleteMultipartUploadResult (#183)
existing implementation was not parsing complete multipart response properly. Bonus: add support for new checksum fields
1 parent 5a5533e commit 818d203

File tree

3 files changed

+23
-7
lines changed

3 files changed

+23
-7
lines changed

include/miniocpp/response.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ struct CompleteMultipartUploadResponse : public Response {
153153
std::string location;
154154
std::string etag;
155155
std::string version_id;
156+
std::string checksumCRC32;
157+
std::string checksumCRC32C;
158+
std::string checksumSHA1;
159+
std::string checksumSHA256;
156160

157161
CompleteMultipartUploadResponse() = default;
158162

src/response.cc

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,7 @@ CompleteMultipartUploadResponse CompleteMultipartUploadResponse::ParseXML(
123123
if (!result) {
124124
return error::make<CompleteMultipartUploadResponse>("unable to parse XML");
125125
}
126-
auto root = xdoc.select_node("/CompleteMultipartUploadOutput");
127-
126+
auto root = xdoc.select_node("/CompleteMultipartUploadResult");
128127
pugi::xpath_node text;
129128

130129
text = root.node().select_node("Bucket/text()");
@@ -139,6 +138,18 @@ CompleteMultipartUploadResponse CompleteMultipartUploadResponse::ParseXML(
139138
text = root.node().select_node("ETag/text()");
140139
resp.etag = utils::Trim(text.node().value(), '"');
141140

141+
text = root.node().select_node("ChecksumCRC32/text()");
142+
resp.checksumCRC32 = text.node().value();
143+
144+
text = root.node().select_node("ChecksumCRC32/text()");
145+
resp.checksumCRC32C = text.node().value();
146+
147+
text = root.node().select_node("ChecksumSHA1/text()");
148+
resp.checksumSHA1 = text.node().value();
149+
150+
text = root.node().select_node("ChecksumSHA256/text()");
151+
resp.checksumSHA256 = text.node().value();
152+
142153
resp.version_id = version_id;
143154

144155
return resp;

tests/tests.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,7 @@ class Tests {
461461
std::string object_name = RandObjectName();
462462
std::string data = "PutObject()";
463463
std::stringstream ss(data);
464-
minio::s3::PutObjectArgs args(
465-
ss, static_cast<long>(data.length()),
466-
0); // PWTODO: PutObjectArgs should accept size_t instead of long
464+
minio::s3::PutObjectArgs args(ss, data.length(), 0);
467465
args.bucket = bucket_name_;
468466
args.object = object_name;
469467
minio::s3::PutObjectResponse resp = client_.PutObject(args);
@@ -475,16 +473,19 @@ class Tests {
475473

476474
{
477475
std::string object_name = RandObjectName();
478-
size_t size = 13930573;
476+
size_t size = 67108865; // (64MiB + 1) bytes
479477
RandCharStream stream(size);
480-
minio::s3::PutObjectArgs args(stream, static_cast<long>(size), 0);
478+
minio::s3::PutObjectArgs args(stream, size, 0);
481479
args.bucket = bucket_name_;
482480
args.object = object_name;
483481
minio::s3::PutObjectResponse resp = client_.PutObject(args);
484482
if (!resp) {
485483
throw std::runtime_error("<Multipart> PutObject(): " +
486484
resp.Error().String());
487485
}
486+
if (resp.etag == "") {
487+
throw std::runtime_error("<Multipart> PutObject(): etag is missing");
488+
}
488489
RemoveObject(bucket_name_, object_name);
489490
}
490491
}

0 commit comments

Comments
 (0)