Skip to content

Add content type and checksum support to the direct upload methods - #44

Merged
alexis- merged 1 commit into
mainfrom
develop
Aug 26, 2026
Merged

Add content type and checksum support to the direct upload methods#44
alexis- merged 1 commit into
mainfrom
develop

Conversation

@alexis-

@alexis- alexis- commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Each of the six direct upload members (UploadAsync, UploadSinglePartAsync, UploadMultipartAsync, file path and stream forms) gains an overload taking an optional content type, following the shape InitiateMultipartUploadAsync already uses: the existing signature stays and delegates with a null type, so no compiled caller changes behavior. A null or blank value leaves the property unset and R2 applies its default; a non-blank value is applied verbatim and never inferred from the file extension, the bytes, or the object key. The single PUT path sets PutObjectRequest.ContentType; the multipart path records the type on the initiate request, the only place S3 reads the assembled object's Content-Type from. UploadAsync forwards the value down whichever branch its size check picks.

The overloads that can take the single PUT path also accept an optional UploadChecksum. The digest is copied onto the PutObjectRequest property matching its algorithm (ChecksumCRC32, ChecksumCRC32C, ChecksumSHA1, ChecksumSHA256, MD5Digest) and R2 verifies the arriving bytes against it, failing the upload with 400 BadDigest and storing nothing on a mismatch (verified against live R2 for all five algorithms, 2026-08-25). Because the digest covers the whole object while a multipart upload is verified per part, UploadAsync throws ArgumentException when a checksum accompanies an input that would go multipart, before anything is sent; the multipart overloads take no checksum parameter.

Unit tests cover the request each path sends (type set, blank left unset, pre-existing overloads unchanged, one digest property per algorithm) and both branches of both UploadAsync overloads. Integration tests verify the stored Content-Type via object metadata and pin BadDigest rejection on the direct upload path. The uploads article's threshold claim (5 GiB) is corrected to the actual 50 MiB. Version 2.4.0.

Each of the six direct upload members (UploadAsync, UploadSinglePartAsync,
UploadMultipartAsync, file path and stream forms) gains an overload taking
an optional content type, following the shape InitiateMultipartUploadAsync
already uses: the existing signature stays and delegates with a null type,
so no compiled caller changes behavior. A null or blank value leaves the
property unset and R2 applies its default; a non-blank value is applied
verbatim and never inferred from the file extension, the bytes, or the
object key. The single PUT path sets PutObjectRequest.ContentType; the
multipart path records the type on the initiate request, the only place S3
reads the assembled object's Content-Type from. UploadAsync forwards the
value down whichever branch its size check picks.

The overloads that can take the single PUT path also accept an optional
UploadChecksum. The digest is copied onto the PutObjectRequest property
matching its algorithm (ChecksumCRC32, ChecksumCRC32C, ChecksumSHA1,
ChecksumSHA256, MD5Digest) and R2 verifies the arriving bytes against it,
failing the upload with 400 BadDigest and storing nothing on a mismatch
(verified against live R2 for all five algorithms, 2026-08-25). Because
the digest covers the whole object while a multipart upload is verified
per part, UploadAsync throws ArgumentException when a checksum accompanies
an input that would go multipart, before anything is sent; the multipart
overloads take no checksum parameter.

Unit tests cover the request each path sends (type set, blank left unset,
pre-existing overloads unchanged, one digest property per algorithm) and
both branches of both UploadAsync overloads. Integration tests verify the
stored Content-Type via object metadata and pin BadDigest rejection on
the direct upload path. The uploads article's threshold claim (5 GiB) is
corrected to the actual 50 MiB. Version 2.4.0.
@alexis-
alexis- merged commit 2ce21d3 into main Aug 26, 2026
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant