Coverage Report

Created: 2026-09-01 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/h2/src/proto/streams/mod.rs
Line
Count
Source
1
mod buffer;
2
mod counts;
3
mod flow_control;
4
mod prioritize;
5
mod recv;
6
mod send;
7
mod state;
8
mod store;
9
mod stream;
10
#[allow(clippy::module_inception)]
11
mod streams;
12
13
pub(crate) use self::prioritize::Prioritized;
14
pub(crate) use self::recv::Open;
15
pub(crate) use self::send::PollReset;
16
pub(crate) use self::streams::{DynStreams, OpaqueStreamRef, StreamRef, Streams};
17
18
use self::buffer::Buffer;
19
use self::counts::Counts;
20
use self::flow_control::FlowControl;
21
use self::prioritize::Prioritize;
22
use self::recv::Recv;
23
use self::send::Send;
24
use self::state::State;
25
use self::store::Store;
26
use self::stream::Stream;
27
28
use crate::frame::{StreamId, StreamIdOverflow};
29
use crate::proto::*;
30
31
use bytes::Bytes;
32
use std::time::Duration;
33
34
#[derive(Debug, Eq, PartialEq)]
35
pub(super) enum BufferStatus {
36
    Complete,
37
    CodecFull,
38
}
39
40
#[derive(Debug)]
41
pub struct Config {
42
    /// Initial maximum number of locally initiated streams.
43
    /// After receiving a Settings frame from the remote peer,
44
    /// the connection will overwrite this value with the
45
    /// MAX_CONCURRENT_STREAMS specified in the frame.
46
    pub initial_max_send_streams: usize,
47
48
    /// Max amount of DATA bytes to buffer per stream.
49
    pub local_max_buffer_size: usize,
50
51
    /// The stream ID to start the next local stream with
52
    pub local_next_stream_id: StreamId,
53
54
    /// If the local peer is willing to receive push promises
55
    pub local_push_enabled: bool,
56
57
    /// If extended connect protocol is enabled.
58
    pub extended_connect_protocol_enabled: bool,
59
60
    /// How long a locally reset stream should ignore frames
61
    pub local_reset_duration: Duration,
62
63
    /// Maximum number of locally reset streams to keep at a time
64
    pub local_reset_max: usize,
65
66
    /// Maximum number of remotely reset "pending accept" streams to keep at a
67
    /// time. Going over this number results in a connection error.
68
    pub remote_reset_max: usize,
69
70
    /// Initial window size of remote initiated streams
71
    pub remote_init_window_sz: WindowSize,
72
73
    /// Maximum number of remote initiated streams
74
    pub remote_max_initiated: Option<usize>,
75
76
    /// Maximum number of locally reset streams due to protocol error across
77
    /// the lifetime of the connection.
78
    ///
79
    /// When this gets exceeded, we issue GOAWAYs.
80
    pub local_max_error_reset_streams: Option<usize>,
81
82
    /// connection-level budget (in bytes) for DATA framing overhead.
83
    ///
84
    /// Default 25600 bytes
85
    pub data_frame_budget: usize,
86
}
87
88
trait DebugStructExt<'a, 'b> {
89
    // h2_ prefixes to protect against possible future name collisions
90
    fn h2_field_if(&mut self, name: &str, val: &bool) -> &mut std::fmt::DebugStruct<'a, 'b>;
91
92
    fn h2_field_if_then<T: std::fmt::Debug>(
93
        &mut self,
94
        name: &str,
95
        cond: bool,
96
        val: &T,
97
    ) -> &mut std::fmt::DebugStruct<'a, 'b>;
98
99
    fn h2_field_some<T: std::fmt::Debug>(
100
        &mut self,
101
        name: &str,
102
        val: &Option<T>,
103
    ) -> &mut std::fmt::DebugStruct<'a, 'b>;
104
}
105
106
impl<'a, 'b> DebugStructExt<'a, 'b> for std::fmt::DebugStruct<'a, 'b> {
107
0
    fn h2_field_if(&mut self, name: &str, val: &bool) -> &mut std::fmt::DebugStruct<'a, 'b> {
108
0
        if *val {
109
0
            self.field(name, val)
110
        } else {
111
0
            self
112
        }
113
0
    }
114
115
0
    fn h2_field_if_then<T: std::fmt::Debug>(
116
0
        &mut self,
117
0
        name: &str,
118
0
        cond: bool,
119
0
        val: &T,
120
0
    ) -> &mut std::fmt::DebugStruct<'a, 'b> {
121
0
        if cond {
122
0
            self.field(name, val)
123
        } else {
124
0
            self
125
        }
126
0
    }
Unexecuted instantiation: <core::fmt::builders::DebugStruct as h2::proto::streams::DebugStructExt>::h2_field_if_then::<h2::proto::streams::store::Queue<h2::proto::streams::stream::NextAccept>>
Unexecuted instantiation: <core::fmt::builders::DebugStruct as h2::proto::streams::DebugStructExt>::h2_field_if_then::<h2::proto::streams::buffer::Deque>
127
128
0
    fn h2_field_some<T: std::fmt::Debug>(
129
0
        &mut self,
130
0
        name: &str,
131
0
        val: &Option<T>,
132
0
    ) -> &mut std::fmt::DebugStruct<'a, 'b> {
133
0
        if val.is_some() {
134
0
            self.field(name, val)
135
        } else {
136
0
            self
137
        }
138
0
    }
Unexecuted instantiation: <core::fmt::builders::DebugStruct as h2::proto::streams::DebugStructExt>::h2_field_some::<h2::proto::streams::store::Key>
Unexecuted instantiation: <core::fmt::builders::DebugStruct as h2::proto::streams::DebugStructExt>::h2_field_some::<std::time::Instant>
Unexecuted instantiation: <core::fmt::builders::DebugStruct as h2::proto::streams::DebugStructExt>::h2_field_some::<()>
139
}