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
//! The wire's framing (REMOTE §3, decided by bl-b6fa): **a big-endian `u32`
//! byte length followed by that many bytes of JSON, and a zero-length frame
//! ends a reply stream.**
//!
//! §3 left the choice to the implementation ball and named two candidates. This
//! is the length-delimited one, for three reasons and one that matters more
//! than all of them:
//!
//! - A reader never scans. It reads four bytes, then exactly that many — so a
//! payload's own bytes can never be mistaken for a delimiter, and no property
//! of the *encoder* (that `serde_json` escapes newlines, say) is load-bearing
//! in the *framing*.
//! - The allocation is bounded before it is made. A length above [`MAX_FRAME`]
//! is refused on its header, so a hostile peer on the open internet cannot
//! make a reader grow to meet it.
//! - The terminator is unambiguous by construction: a zero-length frame is not
//! a JSON value, so nothing a payload can say collides with it.
//!
//! **And the streaming form is not a second form.** §3 asks for "one streaming
//! form for follow-class reads, same envelope, chunked". Here *every* answer is
//! a stream: a request is one frame, and its answer is N ≥ 1 reply frames
//! followed by the terminator. Today N is always 1 because no [`Query`] is
//! follow-class — the seat polls (§3) — so a follow-class read is the general
//! path with more than one frame in it, not a case of its own, and landing one
//! needs no version, no flag and no second reader. That is the same
//! edge-case-dissolving move §8.5 makes for a gesture that names no workspace.
use Value;
use ;
/// The largest frame either end will write or read: 16 MiB. A reply is JSON
/// derived from a world's own files, so this is orders above anything yog
/// says, and it is the bound that makes an unauthenticated-but-handshaken
/// peer unable to dictate an allocation.
pub const MAX_FRAME: usize = 16 * 1024 * 1024;
/// The frame header's width — a big-endian `u32`.
const HEADER: usize = 4;
/// Write one JSON frame.
/// Write the end-of-stream terminator: a zero-length frame.
/// Read one JSON frame: `Some(value)` a frame, `None` the terminator. An
/// oversized length, a short stream or a body that is not JSON is an error —
/// the strict-decode discipline the codec already keeps, at the framing.
/// The length-prefixed write both spellings above share.
/// The length-prefixed read: `None` for the zero-length terminator.
/// The one refusal a length can earn, said the same way on both sides.