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}