Skip to content

Commit 7e5ced2

Browse files
committed
fix(storage): allow setting full checksum at finalize for appendable uploads
1 parent 9ea5a9d commit 7e5ced2

1 file changed

Lines changed: 22 additions & 4 deletions

File tree

google/cloud/storage/internal/async/writer_connection_impl.cc

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "google/cloud/storage/internal/async/write_payload_impl.h"
1919
#include "google/cloud/storage/internal/grpc/ctype_cord_workaround.h"
2020
#include "google/cloud/storage/internal/grpc/object_metadata_parser.h"
21+
#include "google/cloud/storage/internal/grpc/object_request_parser.h"
22+
#include "google/cloud/storage/async/options.h"
2123
#include "google/cloud/internal/make_status.h"
2224

2325
namespace google {
@@ -138,10 +140,26 @@ AsyncWriterConnectionImpl::Finalize(storage::WritePayload payload) {
138140

139141
auto p = WritePayloadImpl::GetImpl(payload);
140142
auto size = p.size();
141-
auto action = request_.has_append_object_spec() ||
142-
request_.write_object_spec().appendable()
143-
? PartialUpload::kFinalize
144-
: PartialUpload::kFinalizeWithChecksum;
143+
auto is_append = request_.has_append_object_spec() ||
144+
request_.write_object_spec().appendable();
145+
auto current_options = google::cloud::internal::CurrentOptions();
146+
147+
// Default to letting the internal hash function compute and send the checksum.
148+
auto action = PartialUpload::kFinalizeWithChecksum;
149+
150+
if (current_options.has<google::cloud::storage::UseCrc32cValueOption>()) {
151+
// The user provided a final CRC via OptionsSpan. We manually inject it into the
152+
// request. We use `kFinalize` so the internal hash function doesn't overwrite it.
153+
write.mutable_object_checksums()->set_crc32c(
154+
current_options.get<google::cloud::storage::UseCrc32cValueOption>());
155+
action = PartialUpload::kFinalize;
156+
} else if (is_append && !options_->has<google::cloud::storage::UseCrc32cValueOption>()) {
157+
// For appendable uploads, the internal hash function only sees the chunks uploaded
158+
// in this stream, not the full object. We use `kFinalize` to avoid sending this
159+
// partial CRC, which would otherwise fail validation.
160+
action = PartialUpload::kFinalize;
161+
}
162+
145163
auto coro = PartialUpload::Call(impl_, hash_function_, std::move(write),
146164
std::move(p), std::move(action));
147165
return coro->Start().then([coro, size, this](auto f) mutable {

0 commit comments

Comments
 (0)