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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//! Serving files, both ways, and what each costs the description.
//!
//! ```text
//! cargo run -p kynos --example assets --no-default-features \
//! --features openapi31,macros,server,http1,assets-fs
//! ```
//!
//! Two things share the name "static assets", and only one of them is a
//! catch-all.
//!
//! A **known set of files** — a build output — is finite and enumerable. Every
//! path is a literal, so there is no wildcard, nothing is waived, and each file
//! is an ordinary described operation. `assets!` compiles the set into the
//! binary, and compile-time embedding is what *makes* the set knowable.
//!
//! A **directory as a live namespace** — drop a file in and it serves — matches
//! a set of paths no template describes. `assets_directory` serves one behind
//! `unchecked`, recorded at the document root where no client generator can act
//! on it.
//!
//! Six things are worth noticing:
//!
//! * **The embedded half is fully described.** Run this and read the document:
//! `/static/index.html` and `/static/css/app.css` are `paths` keys with their
//! media types, a 200, a 304 and an `ETag`. Nothing about them is opaque.
//! * **The filesystem half has no `paths` key at all.** It appears once, under
//! `x-kynos-opaque-routes`, with `reason: static-assets`. A generator emits
//! nothing for it *by construction* — which is stronger than a `paths` entry
//! marked with a vendor extension a generator may or may not honour.
//! * **The waiver names itself.** `unchecked_reasons` reports
//! `[StaticAssets]`, so a CI job can assert that this is the only waiver the
//! service takes and keep catching an accidental `layer_unchecked`.
//! `has_unchecked` alone would have to be deleted.
//! * **Traversal is unrepresentable rather than defended against.** The
//! embedded set joins no request input onto anything: the paths are literals
//! fixed at compile time. The directory resolver examines every component and
//! accepts only plain names, so `..` never climbs and an absolute segment
//! never replaces the base.
//! * **Adding a file to the embedded directory does not rebuild.**
//! `include_bytes!` tracks a file's *contents*, not a directory's membership.
//! The `build.rs` below is how that is closed, and it is three lines.
//! * **An oversized set warns at the `dir` literal.** Two mebibytes by default.
//! Raise it with `warn_over = "8MiB"` or turn it off with `"none"` — and note
//! that under `-D warnings` it becomes an error, which is arguably right.
//! * **Every file is a resumable download, and says so.** Each operation
//! declares a 206, a 416, and the `Range` and `If-Range` fields it reads:
//!
//! ```text
//! curl -r 0-9 http://localhost:3000/static/css/app.css -D -
//! ```
//!
//! Only the embedded half honours an `If-Range`. Its tag is a hash of the
//! file, which RFC 9110 section 13.1.5's strong comparison accepts; the
//! directory's is derived from a `stat` and is weak, so a conditional range
//! there is answered with the whole file. That is the tag it chose, not an
//! omission — and the directory still seeks to the part an unconditional
//! `Range` asked for rather than reading the file and throwing most of it
//! away.
//!
//! ```text
//! // build.rs
//! fn main() {
//! println!("cargo::rerun-if-changed=examples/assets");
//! }
//! ```
use Ipv4Addr;
use ;
assets!
async