feat(tus): return etag and permissions after the last TUS chunk#718
Merged
Merged
Conversation
The finalizing PATCH of a chunked TUS upload returned only the file id, so a client had to issue a follow-up PROPFIND to learn the new etag and permissions, an extra round-trip per upload. The creation-with-upload path already returns them: the ocdav gateway stats the resource and sets OC-ETag/ETag/OC-Perm. This registers tusd's PreFinishResponseCallback in the dataprovider tus handler and attaches the same headers to the chunked finalize. The finalized resource is resolved by the storage driver through a new UploadSessionResolver interface, so the generic datatx layer does not reconstruct the upload's executant: decomposedfs resolves the finished upload as its own executant (the data path's transfer token carries no user identity) and returns the resource info. The session is rebuilt from the in-hand tus info, so it still resolves after a synchronous upload has cleaned up its session. The lookup is best-effort: on a stat error, or a driver that does not implement the interface, it sets no headers and leaves the PROPFIND fallback intact. The WebDAV-permission derivation is shared with the gateway's creation-with-upload path via net.WebDAVPermissions, so the two cannot drift; the propfind handler keeps its own share-types-aware variant. Fixes: opencloud-eu/opencloud#2409
This was referenced Jun 30, 2026
rhafer
approved these changes
Jul 3, 2026
rhafer
left a comment
Member
There was a problem hiding this comment.
Are you going to implement acceptance tests for this in OpenCloud?
Author
|
Yes, I'll add acceptance tests for this in OpenCloud. 👍 I'll open a follow-up PR there once this one is merged. Thanks for the review! 🎉 |
michaelstingl
added a commit
to michaelstingl/opencloud-eu-opencloud
that referenced
this pull request
Jul 6, 2026
…lizing TUS chunk The chunked TUS finalize returns OC-ETag, ETag and OC-Perm since opencloud-eu/reva#718, so a client no longer needs a follow-up PROPFIND for the new etag and permissions. Add a scenario asserting these headers on the finalizing chunk, reusing existing step definitions (the etag is a dynamic quoted hash, hence the header-regex assertion). Verified locally red->green: red on stock (headers absent), green on an opencloud built on reva-with-opencloud-eu#718, on posix and decomposed. opencloud-eu#2409
michaelstingl
added a commit
to michaelstingl/opencloud-eu-opencloud
that referenced
this pull request
Jul 6, 2026
…lizing TUS chunk The chunked TUS finalize returns OC-ETag, ETag and OC-Perm since opencloud-eu/reva#718, so a client no longer needs a follow-up PROPFIND for the new etag and permissions. Add a scenario asserting these headers on the finalizing chunk, reusing existing step definitions (the etag is a dynamic quoted hash, hence the header-regex assertion). Verified locally red->green: red on stock (headers absent), green on an opencloud built on a reva carrying that change, on posix and decomposed. opencloud-eu#2409
9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
A chunked TUS upload's finalizing PATCH returned only
OC-FileID, so a client needed a follow-up PROPFIND for the new etag and permissions. The creation-with-upload path already setsOC-ETag/ETag/OC-Permin the ocdav gateway.This registers tusd's
PreFinishResponseCallbackin the dataprovider and sets the same headers on the chunked finalize. A new optionalstorage.UploadSessionResolverresolves the finished upload to itsResourceInfo, read as the upload's executant:decomposedfs implements it from the upload's own session, so the datatx layer no longer reconstructs the executant or reads decomposedfs
FileInfokeys. The session is rebuilt from the givenFileInfo, not the store, because a synchronous upload has cleaned its session up by callback time. On any lookup failure the callback sets no headers and the client keeps its PROPFIND fallback.The WebDAV-permission derivation moves into
net.WebDAVPermissions, shared with the gateway so the two cannot drift; propfind keeps its share-types-aware variant.Related Issue
Motivation and Context
The storage-interface variant of #666: it keeps the executant handling inside the storage driver instead of depending on decomposedfs
FileInfokeys in the datatx layer.How Has This Been Tested?
tus_internal_test.godrives the callback against a fake resolver (etag, permissions, executant-context shared marker, no-op on stat error / nil resource / non-resolver driver);net/permissions_test.gocovers the sharedWebDAVPermissionshelpergo build,gofmt,go vet, pinnedgolangci-lint v2.10.1: 0 issuesOC-ETag/ETag(equal to a follow-up PROPFIND) andOC-Perm,OC-FileIDunchanged; the creation-with-upload path is unchangedTypes of changes
Checklist:
🤖 drafted with Claude Code, reviewed before submitting.