Upload Finalization Contracts
This document captures the provider-resumable upload finalization contract. The complete upload service still owns session-kind validation, quota accounting, verified blob finalization, retry behavior, and cleanup. This page records the storage-path rules consumed by both frontend-direct and server-relay provider sessions.
Provider Resumable Upload
Section titled “Provider Resumable Upload”OneDrive and similar providers expose a stateful upload session whose progress can be queried. The connector selects one of two data paths:
FrontendDirect: the authenticated browser receives the temporary provider upload URL and uploads ranges directly.ServerRelay: the browser receives only the AsterDrive upload ID and sequential scheduling metadata; a Primary streams each authenticated chunk request into the provider session.
Initialization
Section titled “Initialization”- The connector must select
ProviderResumable(FrontendDirect | ServerRelay)and the driver must exposeprovider_resumable. Only the direct path additionally requiresfrontend_direct_upload = true. - Fragment size must satisfy the provider minimum, maximum, and alignment constraints.
- All ranges are sequential: the direct frontend follows
next_expected_ranges, while the relay backend enforces ordering through scheduling metadata and its shared-database state machine. create_upload_session(object_temp_key)receives an object path generated bynondedup_storage_path_for_policy().- The object path comes from the policy connector descriptor:
opaque_uuid:files/{upload_id}original_filename:files/{upload_id}/{normalized_filename}
- OneDrive declares
original_filename, so the Graph item keeps the original filename and can return it from a direct download URL. - Upload naming must not be inferred from
ProviderResumableorDriverTypeinside upload services. - The upload URL is a write credential and is encrypted in
upload_sessions.provider_session_ciphertext. - Direct sessions persist as
provider_direct_resumableand return the temporary provider upload URL. Relay sessions persist asprovider_relay_resumable, return the ordinarychunkedmode without the provider URL, and declaresequentialscheduling withmax_chunk_concurrency = 1. - Database persistence failure, upload-ID collision, or session encryption failure must abort the provider session and delete
object_temp_key.
Frontend-Direct Data Path
Section titled “Frontend-Direct Data Path”The browser sends PUT requests with Content-Range to the provider upload URL without AsterDrive credentials. The frontend follows next_expected_ranges; non-final fragments obey the provider alignment requirement. The provider completes the item after the final range.
Server-Relay Data Path
Section titled “Server-Relay Data Path”- The browser calls only AsterDrive’s authenticated chunk endpoint. The Graph upload URL remains encrypted on the server.
- A Primary uses a fixed 64 KiB duplex pipe to connect the Actix request payload to
upload_session_fragment_reader; a complete fragment is neither staged on disk nor buffered as one allocation. - Graph range PUTs carry exact
Content-LengthandContent-Rangeheaders. The preauthenticated upload URL is not sent an OAuth authorization header. OneDrive non-final fragments stay aligned to 320 KiB and each request is capped at 50 MiB. - The unique
(upload_id, part_number)row inupload_session_partsis the shared-database claim. An empty ETag is an active claim;provider-range-v1is the durable receipt confirming provider acceptance. received_countis the only legal next chunk number. A claim heartbeat is refreshed every 30 seconds; a claim older than 120 seconds is reclaimed only after the provider still reports the same range start. This supports multiple Primaries without sticky sessions or a shared local staging directory.
Progress and Completion
Section titled “Progress and Completion”Direct progress decrypts the provider session metadata and calls query_upload_session. Relay progress additionally converts the provider offset into durable range receipts and advances received_count in order.
A failed relay PUT is ambiguous until provider progress is queried:
- An offset at or beyond the range end proves that the fragment committed, so AsterDrive finalizes the receipt without another PUT.
- An offset equal to the range start proves that it did not commit, so the claim is released for retry.
- An offset inside the range marks the session corrupted.
- If the status query also fails, the claim is retained for later reconciliation rather than risking a duplicate PUT.
When the provider session returns NotFound, existence of object_temp_key distinguishes an uncommitted session from a final range that completed and caused Graph to remove the upload session.
Relay completion first reconciles all provider ranges and requires received_count == total_chunks. Both paths then read metadata from object_temp_key, verify that the actual size equals session.total_size, and enter verified blob finalization and atomic database quota accounting.
Cleanup Matrix
Section titled “Cleanup Matrix”Initialization, cancellation, expiration, forced policy cleanup, and failed finalization must retain ownership of both provider resources and AsterDrive object paths:
abort provider upload sessiondelete object_temp_key / named OneDrive UUID namespaceProvider NotFound during abort is treated as already complete. Retryable failures retain the upload session for another cleanup attempt; permission or configuration failures retain it for operator intervention. A temp-object delete error is considered complete only when an existence check proves that the object is already absent.
Initialization failures still report both abort and delete results:
| Abort | Delete | Result |
|---|---|---|
| success | success | cleanup succeeds |
| failure | success | abort error is returned |
| success | failure | delete error is returned |
| failure | failure | both errors are retained |
Database persistence failure, upload-ID collision, session encryption failure, an empty provider URL, and database finalization failure require the same explicit cleanup ownership.
Compatibility
Section titled “Compatibility”Legacy OneDrive objects may use files/{upload_id}. They remain readable and
deletable. In provider_native mode they can continue to use Graph direct
download, which may expose the provider’s UUID filename; in
strict_current mode the download service uses relay streaming so the current
AsterDrive filename is applied. No legacy-name check is performed unless the
administrator selects strict_current.
See Object Naming and OneDrive Direct Downloads for the full connector capability, path, and download acceptance matrix.