Skip to main content

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    /// Lazily allocated WebSocket parsing state retained across cancelled reads.
51    #[get(pub(super), type(ref))]
52    #[get_mut(pub(super))]
53    #[set(pub(super))]
54    pub(super) websocket_state: Option<Box<WebSocketReadState>>,
55}
56
57/// Partial WebSocket input that must survive selection of an outbound message.
58#[derive(Clone, Data, Debug, Default)]
59pub(super) struct WebSocketReadState {
60    /// Wire bytes not yet consumed by a complete frame.
61    #[get(pub(super), type(ref))]
62    #[get_mut(pub(super))]
63    #[set(pub(super))]
64    pub(super) buffer: Vec<u8>,
65    /// Payload accumulated from a message spanning multiple frames.
66    #[get(pub(super))]
67    #[get_mut(pub(super))]
68    #[set(pub(super))]
69    pub(super) full_frame: Vec<u8>,
70    /// Whether a peer response has arrived since the last heartbeat.
71    #[get(pub(super), type(copy))]
72    #[get_mut(pub(super))]
73    #[set(pub(super))]
74    pub(super) is_client_response: bool,
75}
76
77/// A buffered reader over a transport with a reusable read buffer.
78///
79/// This reader batches reads into an internal buffer to reduce syscall count,
80/// and returns drained buffers to a thread-local pool while waiting for more
81/// input so idle keep-alive connections do not each retain a read buffer.
82#[derive(Data, New)]
83pub(crate) struct PooledReader<'a> {
84    /// The underlying transport being read.
85    #[get(pub(super))]
86    #[get_mut(pub(super))]
87    #[set(pub(super))]
88    pub(super) stream: &'a mut Box<dyn Transport>,
89    /// The reusable read buffer holding unconsumed bytes in `start..end`.
90    #[get(pub(super))]
91    #[get_mut(pub(super))]
92    #[set(pub(super))]
93    pub(super) buffer: Vec<u8>,
94    /// The required buffer length when the transport becomes readable.
95    #[get(pub(super), type(copy))]
96    #[get_mut(pub(super))]
97    #[set(pub(super))]
98    pub(super) capacity: usize,
99    /// The index of the first unconsumed byte in the buffer.
100    #[get(pub(super), type(copy))]
101    #[get_mut(pub(super))]
102    #[set(pub(super))]
103    #[new(skip)]
104    pub(super) start: usize,
105    /// The index one past the last valid byte in the buffer.
106    #[get(pub(super), type(copy))]
107    #[get_mut(pub(super))]
108    #[set(pub(super))]
109    #[new(skip)]
110    pub(super) end: usize,
111}