Skip to content
AsterDrive Developer DocsDeveloper

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.

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.
  • The connector must select ProviderResumable(FrontendDirect | ServerRelay) and the driver must expose provider_resumable. Only the direct path additionally requires frontend_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 by nondedup_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 ProviderResumable or DriverType inside upload services.
  • The upload URL is a write credential and is encrypted in upload_sessions.provider_session_ciphertext.
  • Direct sessions persist as provider_direct_resumable and return the temporary provider upload URL. Relay sessions persist as provider_relay_resumable, return the ordinary chunked mode without the provider URL, and declare sequential scheduling with max_chunk_concurrency = 1.
  • Database persistence failure, upload-ID collision, or session encryption failure must abort the provider session and delete object_temp_key.

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.

  • 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-Length and Content-Range headers. 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 in upload_session_parts is the shared-database claim. An empty ETag is an active claim; provider-range-v1 is the durable receipt confirming provider acceptance.
  • received_count is 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.

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.

Initialization, cancellation, expiration, forced policy cleanup, and failed finalization must retain ownership of both provider resources and AsterDrive object paths:

abort provider upload session
delete object_temp_key / named OneDrive UUID namespace

Provider 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:

AbortDeleteResult
successsuccesscleanup succeeds
failuresuccessabort error is returned
successfailuredelete error is returned
failurefailureboth 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.

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.