|
18 | 18 | #include "google/cloud/storage/internal/async/write_payload_impl.h" |
19 | 19 | #include "google/cloud/storage/internal/grpc/ctype_cord_workaround.h" |
20 | 20 | #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" |
21 | 23 | #include "google/cloud/internal/make_status.h" |
22 | 24 |
|
23 | 25 | namespace google { |
@@ -138,10 +140,26 @@ AsyncWriterConnectionImpl::Finalize(storage::WritePayload payload) { |
138 | 140 |
|
139 | 141 | auto p = WritePayloadImpl::GetImpl(payload); |
140 | 142 | 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 | + |
145 | 163 | auto coro = PartialUpload::Call(impl_, hash_function_, std::move(write), |
146 | 164 | std::move(p), std::move(action)); |
147 | 165 | return coro->Start().then([coro, size, this](auto f) mutable { |
|
0 commit comments