http_type/stream/struct.rs
1use super::*;
2
3#[derive(CustomDebug, Data, DisplayDebug)]
4pub struct Stream {
5 /// The bidirectional byte pipe the request/response cycle runs over.
6 ///
7 /// The concrete type is erased behind `Transport`, so a plain TCP socket, a
8 /// TLS session and a per-request duplex stream are interchangeable here.
9 /// Address metadata comes from the transport itself, so a transport without
10 /// a socket identity reports an error instead of a fabricated address.
11 pub stream: Box<dyn Transport>,
12 #[get_mut(pub(super))]
13 #[set(pub(super))]
14 pub(super) request_config: RequestConfig,
15 #[get(type(copy))]
16 #[get_mut(pub(super))]
17 pub(super) closed: bool,
18 /// Bytes read ahead of the current request, already consumed from the
19 /// transport but not yet parsed into a request.
20 ///
21 /// A single read can deliver bytes belonging to the next pipelined
22 /// request. Those bytes are carried here between requests so
23 /// HTTP pipelining is not silently dropped.
24 #[get_mut(pub(super))]
25 #[set(pub(super))]
26 pub(super) leftover: Vec<u8>,
27 /// Offset of the first unconsumed byte in `leftover`.
28 #[get(type(copy))]
29 #[get_mut(pub(super))]
30 #[set(pub(super))]
31 pub(super) leftover_start: usize,
32 /// Offset one past the last valid byte in `leftover`.
33 #[get(type(copy))]
34 #[get_mut(pub(super))]
35 #[set(pub(super))]
36 pub(super) leftover_end: usize,
37 /// The buffer the request line is read into.
38 ///
39 /// It lives with the connection rather than with the request, so a
40 /// keep-alive connection reads its second, third and later request lines
41 /// into the same allocation instead of a fresh one per request.
42 #[get_mut(pub(super))]
43 #[set(pub(super))]
44 pub(super) line_buffer: String,
45 /// The buffer the header lines are read into, kept for the same reason as
46 /// the request line buffer.
47 #[get_mut(pub(super))]
48 #[set(pub(super))]
49 pub(super) header_line_buffer: String,
50}
51
52/// A buffered reader over a transport with a reusable read buffer.
53///
54/// This reader batches reads into an internal buffer to reduce syscall count,
55/// and returns drained buffers to a thread-local pool while waiting for more
56/// input so idle keep-alive connections do not each retain a read buffer.
57#[derive(Data, New)]
58pub(crate) struct PooledReader<'a> {
59 /// The underlying transport being read.
60 #[get(pub(super))]
61 #[get_mut(pub(super))]
62 #[set(pub(super))]
63 pub(super) stream: &'a mut Box<dyn Transport>,
64 /// The reusable read buffer holding unconsumed bytes in `start..end`.
65 #[get(pub(super))]
66 #[get_mut(pub(super))]
67 #[set(pub(super))]
68 pub(super) buffer: Vec<u8>,
69 /// The required buffer length when the transport becomes readable.
70 #[get(pub(super), type(copy))]
71 #[get_mut(pub(super))]
72 #[set(pub(super))]
73 pub(super) capacity: usize,
74 /// The index of the first unconsumed byte in the buffer.
75 #[get(pub(super), type(copy))]
76 #[get_mut(pub(super))]
77 #[set(pub(super))]
78 #[new(skip)]
79 pub(super) start: usize,
80 /// The index one past the last valid byte in the buffer.
81 #[get(pub(super), type(copy))]
82 #[get_mut(pub(super))]
83 #[set(pub(super))]
84 #[new(skip)]
85 pub(super) end: usize,
86}