Skip to content

feat(Storage)!: Enable full object checksum validation for resumable uploads - #15769

Merged
krishnamd-jkp merged 15 commits into
googleapis:mainfrom
mahendra-google:feature/enable-full-object-checksum
Sep 18, 2026
Merged

krishnamd-jkp merged 15 commits into
googleapis:mainfrom
mahendra-google:feature/enable-full-object-checksum

Conversation

@mahendra-google

Copy link
Copy Markdown
Contributor

This PR transitions upload object checksum integrity validation from client-side to the server-side.

Previously, CRC32C validation occurred after the upload is completed, requiring the client to delete the object (using DeleteAndThrow upload validation mode) or leave a corrupted object in the bucket (using ThrowOnly upload validation mode) upon hash mismatches. By leveraging the new LastRequestExecuting event in google-api-dotnet-client core library, this implementation calculates CRC32C incrementally during streaming and injects the x-goog-hash: crc32c=... header on the final chunk. If a checksum mismatch occurs, the server rejects the upload with an HTTP 400 Bad Request, ensuring invalid objects are never created in the bucket.

@product-auto-label product-auto-label Bot added the api: storage Issues related to the Cloud Storage API. label Jul 20, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the upload validation mechanism in the Google Cloud Storage V1 client. It introduces UploadValidationMode.RejectAndThrow to allow the server to reject mismatched objects before creation, deprecates UploadValidationMode.DeleteAndThrow, and removes UploadValidationMode.ThrowOnly along with the UploadValidationException class. It also introduces a HashingStream within CustomMediaUpload to calculate CRC32C hashes on the fly and inject the x-goog-hash header. The feedback highlights that removing ThrowOnly and UploadValidationException are breaking changes for existing client applications, and recommends restoring them with an [Obsolete] attribute to maintain backward compatibility.

I am having trouble creating individual review comments. Click here to see my feedback.

apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1/UploadValidationMode.cs (29-35)

high

Removing ThrowOnly from the UploadValidationMode enum is a breaking change for existing client applications. To maintain backward compatibility, please restore ThrowOnly and mark it as [Obsolete], mapping it to the new validation behavior.

        /// <summary>
        /// Obsolete. Use <see cref="RejectAndThrow"/> instead.
        /// Previously, the hash of the data was computed while uploading, and if the resulting object had a different hash, an exception was thrown, but the object remained present in Storage.
        /// </summary>
        [Obsolete("ThrowOnly is deprecated. Use RejectAndThrow instead, as the server now rejects the object before creation.")]
        ThrowOnly = 1,

        /// <summary>
        /// Obsolete. Use <see cref="RejectAndThrow"/> instead.
        /// Previously, the object was uploaded and then deleted if the hash mismatched. 
        /// The server now rejects mismatched objects automatically before creation.
        /// </summary>
        [Obsolete("DeleteAndThrow is deprecated. Use RejectAndThrow instead, as the server now rejects the object before creation.")]
        DeleteAndThrow = 2,

apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1/UploadValidationException.cs (23-26)

high

Removing the public class UploadValidationException is a breaking change for existing client applications that catch this exception.

To maintain backward compatibility, please restore this class and mark it as [Obsolete]. This allows existing code to compile with a warning rather than failing with a compilation error.

@mahendra-google mahendra-google changed the title feat(Storage): Enable full object checksum validation for resumable uploads feat(Storage)!: Enable full object checksum validation for resumable uploads Jul 22, 2026
@mahendra-google
mahendra-google marked this pull request as ready for review July 30, 2026 06:14
@mahendra-google
mahendra-google requested review from a team as code owners July 30, 2026 06:14
@amanda-tarafa

Copy link
Copy Markdown
Contributor

Let's keep this one in draft until we have updated the core libraries to the newest dependency.

@amanda-tarafa
amanda-tarafa marked this pull request as draft August 4, 2026 07:04
@mahendra-google
mahendra-google force-pushed the feature/enable-full-object-checksum branch from 8160401 to 4b0d135 Compare August 21, 2026 06:59
@mahendra-google
mahendra-google marked this pull request as ready for review August 21, 2026 07:04
Comment thread apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1/CustomMediaUpload.cs Outdated
Comment thread apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1/CustomMediaUpload.cs Outdated
-   Add integration tests to verify ArgumentException propagation through
  Google.Apis ResumableUpload when resuming an upload from the intermediate offset.

@amanda-tarafa amanda-tarafa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of the breaking changes you need to update the next version of the library in pipeline-state.json. Add a new property for Storage "nextVersion" with value "5.0.0" and next time we release we'll automatically bump major.

Comment thread apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1/CustomMediaUpload.cs Outdated
Comment thread apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1/CustomMediaUpload.cs Outdated
…ry in pipeline-state.json

- Assign value 5.0.0 to the nextVersion propery so that next storage release will be major release
…76.0.4250 in apis.json.

- Removed Google.Apis 1.76 version dependency from Google.Cloud.Storage.V1 project file
- Regenerated project file using generateprojects.sh
- Throw an argument exception as soon as gap is found while resuming upload from an intermeditae offset
- Maintain -position value up to date in the CustomMediaUpload
- Add static method GetWrappedSourceStream to wrap source stream based on upload validation mode
- Modify upload object integration tests
- Create an unit test file for CustomMediaUpload test.
- Modify UploadObjectOptionsTest file.
@mahendra-google

Copy link
Copy Markdown
Contributor Author

Because of the breaking changes you need to update the next version of the library in pipeline-state.json. Add a new property for Storage "nextVersion" with value "5.0.0" and next time we release we'll automatically bump major.

New property for Storage nextVersion with value 5.0.0 is added in pipeline-state.json

@amanda-tarafa amanda-tarafa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with a small change request and a question. Thanks!!

@amanda-tarafa amanda-tarafa added the allow breaking changes Allows breaking changes to be merged. Use with care! label Sep 17, 2026
@amanda-tarafa

Copy link
Copy Markdown
Contributor

(Also, remember to squash in a single commit before merging).

@krishnamd-jkp
krishnamd-jkp merged commit 6949f54 into googleapis:main Sep 18, 2026
21 checks passed
google-cloud-sdk-librarian-dotnet-robot added a commit that referenced this pull request Sep 21, 2026
### New features

- Enable full object checksum validation for resumable uploads (#15769)

Librarian-Release-Library: Google.Cloud.Storage.V1
Librarian-Release-Version: 5.0.0
Librarian-Release-ID: release-20260921T190154Z
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

allow breaking changes Allows breaking changes to be merged. Use with care! api: storage Issues related to the Cloud Storage API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants