Feature: Chunked Uploads (HTTP + Client)

Purpose

Support reliable, resumable uploads of large files over unreliable connections by splitting a payload into chunks and completing with an integrity check (CRC32):

Main Flows

sequenceDiagram
  participant C as Client (ManagedCode.Storage.Client)
  participant API as StorageControllerBase
  participant Ch as ChunkUploadService
  participant S as IStorage

  loop For each chunk
    C->>API: POST /upload-chunks/upload (multipart)
    API->>Ch: AppendChunkAsync(...)
    Ch-->>API: Result
    API-->>C: Result
  end

  C->>API: POST /upload-chunks/complete (JSON)
  API->>Ch: CompleteAsync(...)
  Ch->>S: UploadAsync(mergedStream, UploadOptions) [CommitToStorage=true]
  S-->>Ch: Result<BlobMetadata>
  Ch-->>API: Result<ChunkUploadCompleteResponse> (includes checksum)
  API-->>C: Result<ChunkUploadCompleteResponse>

Components

Server-side:

Client-side:

Current Behavior

Tests

Temporary file ownership

Each admitted session gets a new server-generated working directory, including when a previously completed upload ID is reused. IDs accept ASCII letters, digits, hyphens and underscores, up to 128 characters. The service generates the merged staging filename independently of client file names. Client names cannot overwrite files outside a session or collide with numbered part files. KeepMergedFile retains only the merged content after the part files are cleaned; callers requesting retention own its eventual cleanup. Expired sessions are cleaned up before completion can write to storage. For a known upload length, append requests check the combined size before staging. A replacement counts only its new size, and a rejected replacement preserves the accepted chunk.