Skip to main content

fileloft_core/
config.rs

1use std::time::Duration;
2
3use crate::hooks::HookConfig;
4
5/// Runtime flags controlling which tus protocol extensions are active.
6///
7/// These are runtime config, not Cargo features, so one compiled binary can
8/// serve any combination without recompilation.
9#[derive(Debug, Clone)]
10pub struct Extensions {
11    /// POST to create a new upload (required by most clients).
12    pub creation: bool,
13    /// POST with body to combine creation and first chunk.
14    pub creation_with_upload: bool,
15    /// Allow `Upload-Defer-Length: 1` to defer declaring size at creation.
16    pub creation_defer_length: bool,
17    /// Attach expiry timestamps to incomplete uploads.
18    pub expiration: bool,
19    /// How long incomplete uploads live before expiry. Used when `expiration = true`.
20    pub expiration_ttl: Option<Duration>,
21    /// Validate chunk integrity via `Upload-Checksum` header.
22    pub checksum: bool,
23    /// Accept checksum in HTTP trailers (requires HTTP/1.1 chunked or HTTP/2).
24    pub checksum_trailer: bool,
25    /// Allow clients to DELETE uploads.
26    pub termination: bool,
27    /// Allow parallel partial uploads assembled into a final upload.
28    pub concatenation: bool,
29    /// After a successful `final` concatenation, delete partial upload resources.
30    pub cleanup_concat_partials: bool,
31}
32
33impl Default for Extensions {
34    fn default() -> Self {
35        Self {
36            creation: true,
37            creation_with_upload: true,
38            creation_defer_length: true,
39            expiration: false,
40            expiration_ttl: None,
41            checksum: true,
42            checksum_trailer: false,
43            termination: true,
44            concatenation: false,
45            cleanup_concat_partials: false,
46        }
47    }
48}
49
50/// Top-level handler configuration.
51#[derive(Debug, Clone)]
52pub struct Config {
53    /// URL path prefix where upload resources are rooted, e.g. `"/files/"`.
54    /// Used to build the `Location` header value on POST responses.
55    pub base_path: String,
56    /// Optional absolute base URL override (e.g. `"https://uploads.example.com"`).
57    /// When `None` the handler builds the Location from the request's `Host` header.
58    pub base_url: Option<String>,
59    /// Maximum allowed `Upload-Length` in bytes. `0` means no server-imposed limit.
60    pub max_size: u64,
61    /// Enabled protocol extensions.
62    pub extensions: Extensions,
63    /// How long to wait when acquiring a per-upload lock before returning 408.
64    pub lock_timeout: Duration,
65    /// Add permissive CORS headers to every response.
66    pub enable_cors: bool,
67    /// When `base_url` is unset, use `X-Forwarded-Proto` / `X-Forwarded-Host` to build absolute
68    /// URLs (e.g. behind TLS termination). **Only enable when this service is not directly exposed
69    /// to untrusted clients** (forwarded headers can be spoofed).
70    pub trust_forwarded_headers: bool,
71    /// Hook callbacks and event-channel configuration.
72    pub hooks: HookConfig,
73}
74
75impl Default for Config {
76    fn default() -> Self {
77        Self {
78            base_path: "/files/".to_string(),
79            base_url: None,
80            max_size: 0,
81            extensions: Extensions::default(),
82            lock_timeout: Duration::from_secs(20),
83            enable_cors: false,
84            trust_forwarded_headers: false,
85            hooks: HookConfig::default(),
86        }
87    }
88}