Skip to content

calternal_dav::files

RFC 4918 class 1 and class 2 access to a User’s Home.

This adapter delegates every operation to the Files service. It never opens a filesystem path. A WebDAV scope is checked before the protocol library sees a request, and the provider repeats the path checks at the Files boundary. Failed conditional PUTs keep their 412 response across the filesystem adapter (#459). Class 2 uses expiring per-User lock tokens. Resource, collection-membership and subtree gates keep overlapping mutations race-free while independent member uploads can run together (#409, #457, #476; RFC 4918 §7.4; docs/research/file-protocols.md, “WebDAV classes and conflicts”). PROPFIND replaces suffix-based MIME values in bounded output chunks, so a large response never needs a second whole-body buffer (#851; DESIGN §6). Request XML passes the shared iterative budget before the protocol library can allocate a recursive tree (#785, DESIGN §21).

Source: crates/calternal-dav/src/files.rs

pub struct DavFilesIdentity

A route authority for file WebDAV. Only the authenticated server layer may add this value to request extensions.

Fields

  • pub user: String
  • pub access: DavFilesAccess
  • pub home_prefix: Option<String>: A validated Home-relative prefix. A trailing slash is accepted when this value is created and is removed before it is stored.
  • pub upload_session: Option<String>: Non-secret authenticated Installation boundary for companion uploads (#648).

Implements: Clone, Debug, PartialEq, Eq

pub fn new(
user: impl Into<String>,
access: DavFilesAccess,
home_prefix: Option<&str>,
) -> Result<Self, FileDavError>

Build the Home scope carried by an authenticated WebDAV request.

pub fn with_upload_session(mut self, session: impl Into<String>) -> Self

Bind companion uploads to the authenticated App Password identity. No credential secret enters the provider or durable copy record (#648).

pub fn with_apple_client(mut self) -> Self

Mark an identity for AppleDouble support after validating its request User-Agent. The DAV route is the only production caller (#648).

pub fn is_apple_client(&self) -> bool

Whether this DAV request may read and write hidden Apple metadata.

pub fn includes(&self, path: &str) -> bool

Whether a path is inside this credential’s Home prefix.

Source: crates/calternal-dav/src/files.rs:88

pub struct FileDavDirectoryEntry

A single row from one index-backed folder listing. The metadata is kept with the name so PROPFIND does not stat each entry again.

Fields

  • pub name: String
  • pub metadata: FileDavMetadata

Implements: Clone, Debug

Source: crates/calternal-dav/src/files.rs:173

pub struct FileDavMetadata

The current resource properties needed by DAV and by HTTP conditionals. etag contains the unquoted BLAKE3 digest for a file, or a strong directory validator. dav-server adds the required quotes on the wire.

Fields

  • pub size: u64
  • pub is_dir: bool
  • pub modified: SystemTime
  • pub etag: Option<String>
  • pub mime: Option<String>: MIME from the Files Index, used by PROPFIND and file response headers.

Implements: Clone, Debug

Source: crates/calternal-dav/src/files.rs:161

pub struct FileDavPreconditions

HTTP preconditions forwarded to the Files upload installer.

Fields

  • pub if_match: Option<String>
  • pub if_none_match: Option<String>

Implements: Clone, Debug, Default

Source: crates/calternal-dav/src/files.rs:186

pub struct FileDavRead

A read handle whose metadata describes the same immutable inode.

Fields

  • pub file: File
  • pub metadata: FileDavMetadata

Source: crates/calternal-dav/src/files.rs:179

pub struct FileDavUpload

An upload created by Files. A zero-length upload can already be installed.

Fields

  • pub id: String
  • pub installed_path: Option<String>

Implements: Clone, Debug

Source: crates/calternal-dav/src/files.rs:193

pub enum DavFilesAccess

The access selected by an authenticated WebDAV app password.

Variants

  • Read: Read file content and list metadata.
  • Write: Read, create and replace. This access cannot delete, copy or move.
  • ReadUploadOnly: Read files and create files or folders without replacing existing files. This combines Read with UploadOnly’s create-only behavior.
  • UploadOnly: Create files and folders below home_prefix. PROPFIND lists names, but GET and HEAD never return file content.
  • Full: Read and mutate all visible Home paths.

Implements: Clone, Copy, Debug, PartialEq, Eq

Source: crates/calternal-dav/src/files.rs:70

pub enum FileDavCopyDepth

COPY’s supported collection depth.

Variants

  • Zero
  • Infinity

Implements: Clone, Copy, Debug, PartialEq, Eq

Source: crates/calternal-dav/src/files.rs:200

pub enum FileDavError

Failure returned by the Files service adapter.

Variants

  • NotFound
  • Forbidden
  • Exists
  • Conflict
  • Precondition
  • Invalid
  • TooLarge
  • InsufficientStorage
  • ServiceUnavailable
  • Internal

Implements: Clone, Copy, Debug, PartialEq, Eq

Source: crates/calternal-dav/src/files.rs:207

pub trait FileDavProvider: Send + Sync

The Files plugin implements this boundary with FilesState operations. Writes use the Files upload staging and install path; DELETE goes to Trash.

fn stat<'a>(
&'a self,
identity: &'a DavFilesIdentity,
path: &'a str,
) -> FileDavFuture<'a, FileDavMetadata>;

No doc comment.

fn list<'a>(
&'a self,
identity: &'a DavFilesIdentity,
path: &'a str,
) -> FileDavFuture<'a, Vec<FileDavDirectoryEntry>>;

No doc comment.

fn open_read<'a>(
&'a self,
identity: &'a DavFilesIdentity,
path: &'a str,
) -> FileDavFuture<'a, FileDavRead>;

No doc comment.

fn start_put<'a>(
&'a self,
identity: &'a DavFilesIdentity,
path: &'a str,
length: u64,
conditions: FileDavPreconditions,
) -> FileDavFuture<'a, FileDavUpload>;

No doc comment.

fn write_put_chunk<'a>(
&'a self,
identity: &'a DavFilesIdentity,
upload_id: &'a str,
offset: u64,
bytes: Bytes,
) -> FileDavFuture<'a, Option<String>>;

No doc comment.

fn finish_put<'a>(
&'a self,
identity: &'a DavFilesIdentity,
upload_id: &'a str,
path: &'a str,
installed_path: Option<&'a str>,
) -> FileDavFuture<'a, FileDavMetadata>;

No doc comment.

fn abort_put<'a>(
&'a self,
identity: &'a DavFilesIdentity,
upload_id: &'a str,
) -> FileDavFuture<'a, ()>;

No doc comment.

fn create_dir<'a>(
&'a self,
identity: &'a DavFilesIdentity,
path: &'a str,
) -> FileDavFuture<'a, ()>;

No doc comment.

fn trash<'a>(&'a self, identity: &'a DavFilesIdentity, path: &'a str) -> FileDavFuture<'a, ()>;

No doc comment.

fn move_path<'a>(
&'a self,
identity: &'a DavFilesIdentity,
source: &'a str,
destination: &'a str,
overwrite: bool,
conditions: FileDavPreconditions,
) -> FileDavFuture<'a, bool>;

Return true when the destination existed and was replaced.

fn copy_path<'a>(
&'a self,
identity: &'a DavFilesIdentity,
source: &'a str,
destination: &'a str,
overwrite: bool,
depth: FileDavCopyDepth,
) -> FileDavFuture<'a, bool>;

Return true when the destination existed and was replaced.

Source: crates/calternal-dav/src/files.rs:284

pub type FileDavFuture<'a, T> = Pin<Box<dyn Future<Output = Result<T, FileDavError>> + Send + 'a>>;

No doc comment.

Source: crates/calternal-dav/src/files.rs:280

pub fn router(provider: Arc<dyn FileDavProvider>) -> Router

Mount /dav/files/{user-id}/ with one shared lock table per server route. Each request still passes its authenticated scope before DAV dispatch (#457, RFC 4918 §18.2).

Source: crates/calternal-dav/src/files.rs:421