1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//! Nextcloud WebDAV Chunked Upload v2 API client.
//!
//! Provides [`UploadClient`] for uploading large files to Nextcloud using the
//! WebDAV Chunked Upload v2 protocol, and [`UploadSession`] for tracking active
//! upload progress and calculating chunk ranges.
//!
//! # Protocol Overview
//!
//! 1. **Initialize Upload Session**:
//! - Sends `MKCOL /remote.php/dav/uploads/{user}/{upload_id}`
//! - Required header: `Destination: {destination_webdav_url_or_path}`
//! 2. **Upload Chunks**:
//! - Sends `PUT /remote.php/dav/uploads/{user}/{upload_id}/{chunk_number}` (e.g. `00001`, `00002`)
//! - Required headers: `Destination: {destination_path}`, `OC-Total-Length: {total_file_size}`
//! - Request body: chunk bytes (recommended 5 MiB to 5 GiB, last chunk may be smaller)
//! 3. **Assemble File**:
//! - Sends `MOVE /remote.php/dav/uploads/{user}/{upload_id}/.file`
//! - Required headers: `Destination: {destination_path}`, `OC-Total-Length: {total_file_size}`
//! - Optional header: `X-OC-Mtime: {unix_timestamp}`
//! 4. **Abort Upload**:
//! - Sends `DELETE /remote.php/dav/uploads/{user}/{upload_id}/` (cancels upload and cleans up temporary chunks)
//!
//! # Example
//!
//! ```no_run
//! use nextcloud_uploads::{UploadClient, UploadSession, DEFAULT_CHUNK_SIZE};
//! # use nextcloud_sdk_core::{Transport, AuthProvider};
//! # async fn run<T: Transport, A: AuthProvider>(transport: &T, auth: &A) -> Result<(), nextcloud_sdk_core::Error> {
//! let client = UploadClient::new(transport, auth);
//!
//! // 1. Start the upload session
//! let total_size = 25 * 1024 * 1024; // 25 MiB
//! let session = client.start("alice", "Documents/archive.zip", total_size).await?;
//!
//! // 2. Calculate chunk boundaries and upload each chunk
//! for boundary in session.chunk_boundaries(DEFAULT_CHUNK_SIZE).unwrap() {
//! let chunk_bytes = vec![0u8; boundary.len() as usize];
//! client.upload_chunk(&session, boundary.index, chunk_bytes).await?;
//! }
//!
//! // 3. Finish assembly
//! client.finish(&session, None).await?;
//! # Ok(())
//! # }
//! ```
pub use ;
pub use ;
pub use ;