1// Copyright (c) 2023 Huawei Device Co., Ltd.
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6//     http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14use crate::h3::parts::Parts;
15
16/// Data Frame type code.
17pub const DATA_FRAME_TYPE: u64 = 0x0;
18/// HEADERS Frame type code.
19pub const HEADERS_FRAME_TYPE: u64 = 0x1;
20/// CANCEL_PUSH Frame type code.
21pub const CANCEL_PUSH_FRAME_TYPE: u64 = 0x3;
22/// SETTINGS Frame type code.
23pub const SETTINGS_FRAME_TYPE: u64 = 0x4;
24/// PUSH_PROMISE Frame type code.
25pub const PUSH_PROMISE_FRAME_TYPE: u64 = 0x5;
26/// GOAWAY Frame type code.
27pub const GOAWAY_FRAME_TYPE: u64 = 0x7;
28/// MAX_PUSH_ID Frame type code.
29pub const MAX_PUSH_ID_FRAME_TYPE: u64 = 0xD;
30/// SETTING_QPACK_MAX_TABLE_CAPACITY setting code.
31pub const SETTING_QPACK_MAX_TABLE_CAPACITY: u64 = 0x1;
32/// SETTING_MAX_FIELD_SECTION_SIZE setting code.
33pub const SETTING_MAX_FIELD_SECTION_SIZE: u64 = 0x6;
34/// SETTING_QPACK_BLOCKED_STREAMS setting code.
35pub const SETTING_QPACK_BLOCKED_STREAMS: u64 = 0x7;
36/// SETTING_ENABLE_CONNECT_PROTOCOL setting code.
37pub const SETTING_ENABLE_CONNECT_PROTOCOL: u64 = 0x8;
38/// SETTING_H3_DATAGRAM setting code.
39pub const SETTING_H3_DATAGRAM: u64 = 0x33;
40/// MAX_SETTING_PAYLOAD_SIZE setting code.
41// Permit between 16 maximally-encoded and 128 minimally-encoded SETTINGS.
42const MAX_SETTING_PAYLOAD_SIZE: usize = 256;
43
44/// Http3 frame definition.
45#[derive(Clone, Debug)]
46pub struct Frame {
47    ty: u64,
48    payload: Payload,
49}
50
51/// Http3 frame payload.
52#[derive(Clone, Debug)]
53pub enum Payload {
54    /// HEADERS frame payload.
55    Headers(Headers),
56    /// DATA frame payload.
57    Data(Data),
58    /// SETTINGS frame payload.
59    Settings(Settings),
60    /// CancelPush frame payload.
61    CancelPush(CancelPush),
62    /// PushPromise frame payload.
63    PushPromise(PushPromise),
64    /// GOAWAY frame payload.
65    Goaway(GoAway),
66    /// MaxPushId frame payload.
67    MaxPushId(MaxPushId),
68    /// Unknown frame payload.
69    Unknown(Unknown),
70}
71
72/// Http3 Headers frame payload, which also contains instructions to send when
73/// decoding.
74#[derive(Clone, Debug)]
75pub struct Headers {
76    parts: Parts,
77    ins: Option<Vec<u8>>,
78}
79
80/// Http3 Data frame payload, containing the body data.
81#[derive(Clone, Debug)]
82pub struct Data {
83    data: Vec<u8>,
84}
85
86/// Http3 Settings frame payload.
87#[derive(Clone, Default, Debug)]
88pub struct Settings {
89    max_field_section_size: Option<u64>,
90    qpack_max_table_capacity: Option<u64>,
91    qpack_blocked_streams: Option<u64>,
92    connect_protocol_enabled: Option<u64>,
93    h3_datagram: Option<u64>,
94    additional: Option<Vec<(u64, u64)>>,
95}
96
97/// Http3 CancelPush frame payload.
98#[derive(Clone, Debug)]
99pub struct CancelPush {
100    push_id: u64,
101}
102
103/// Http3 PushPromise frame payload.
104#[derive(Clone, Debug)]
105pub struct PushPromise {
106    push_id: u64,
107    parts: Parts,
108    ins: Option<Vec<u8>>,
109}
110
111/// Http3 GoAway frame payload.
112#[derive(Clone, Debug)]
113pub struct GoAway {
114    id: u64,
115}
116
117/// Http3 MaxPushId frame payload.
118#[derive(Clone, Debug)]
119pub struct MaxPushId {
120    push_id: u64,
121}
122
123/// Http3 Unknown frame payload.
124#[derive(Clone, Debug)]
125pub struct Unknown {
126    raw_type: u64,
127    len: u64,
128}
129
130impl Frame {
131    /// Constructs a Frame with type and payload.
132    pub fn new(ty: u64, payload: Payload) -> Self {
133        Frame { ty, payload }
134    }
135
136    /// Gets frame type.
137    pub fn frame_type(&self) -> &u64 {
138        &self.ty
139    }
140
141    /// Gets frame payload.
142    pub fn payload(&self) -> &Payload {
143        &self.payload
144    }
145
146    /// Gets a mutable frame payload of current frame.
147    pub(crate) fn payload_mut(&mut self) -> &mut Payload {
148        &mut self.payload
149    }
150}
151
152impl Settings {
153    /// Sets SETTINGS_HEADER_TABLE_SIZE (0x01) setting.
154    pub fn set_max_field_section_size(&mut self, size: u64) {
155        self.max_field_section_size = Some(size)
156    }
157
158    /// Sets SETTINGS_ENABLE_PUSH (0x02) setting.
159    pub fn set_qpack_max_table_capacity(&mut self, size: u64) {
160        self.qpack_max_table_capacity = Some(size)
161    }
162
163    /// Sets SETTINGS_MAX_FRAME_SIZE (0x05) setting.
164    pub fn set_qpack_block_stream(&mut self, size: u64) {
165        self.qpack_blocked_streams = Some(size)
166    }
167
168    /// Sets SETTINGS_MAX_HEADER_LIST_SIZE (0x06) setting.
169    pub fn set_connect_protocol_enabled(&mut self, size: u64) {
170        self.connect_protocol_enabled = Some(size)
171    }
172
173    /// Sets SETTINGS_H3_DATAGRAM setting.
174    pub fn set_h3_datagram(&mut self, size: u64) {
175        self.h3_datagram = Some(size);
176    }
177
178    /// Sets additional settings.
179    pub fn set_additional(&mut self, addition: Vec<(u64, u64)>) {
180        self.additional = Some(addition)
181    }
182
183    /// Gets SETTINGS_MAX_FIELD_SECTION_SIZE setting.
184    pub fn max_fied_section_size(&self) -> Option<u64> {
185        self.max_field_section_size
186    }
187
188    /// Gets SETTINGS_QPACK_MAX_TABLE_CAPACITY setting.
189    pub fn qpack_max_table_capacity(&self) -> Option<u64> {
190        self.qpack_max_table_capacity
191    }
192
193    /// Gets SETTINGS_QPACK_BLOCKED_STREAMS setting.
194    pub fn qpack_block_stream(&self) -> Option<u64> {
195        self.qpack_blocked_streams
196    }
197
198    /// Gets SETTINGS_ENABLE_CONNECT_PROTOCOL setting.
199    pub fn connect_protocol_enabled(&self) -> Option<u64> {
200        self.connect_protocol_enabled
201    }
202
203    /// Gets SETTINGS_H3_DATAGRAM setting.
204    pub fn h3_datagram(&self) -> Option<u64> {
205        self.h3_datagram
206    }
207
208    /// Gets additional settings.
209    pub fn additional(&self) -> &Option<Vec<(u64, u64)>> {
210        &self.additional
211    }
212}
213
214impl Data {
215    /// Creates a new Data instance containing the provided data.
216    pub fn new(data: Vec<u8>) -> Self {
217        Data { data }
218    }
219
220    /// Return the `Vec` that contains the data payload.
221    pub fn data(&self) -> &Vec<u8> {
222        &self.data
223    }
224}
225
226impl CancelPush {
227    /// Creates a new CancelPush instance from the provided Parts.
228    pub fn new(id: u64) -> Self {
229        CancelPush { push_id: id }
230    }
231
232    /// Gets push id of CancelPush payload.
233    pub fn get_push_id(&self) -> &u64 {
234        &self.push_id
235    }
236}
237
238impl Headers {
239    /// Creates a new Headers instance from the provided Parts.
240    pub fn new(parts: Parts) -> Self {
241        Headers { parts, ins: None }
242    }
243
244    /// Gets the instructions generated by qpack decoder after decoding headers
245    /// frame.
246    pub fn get_instruction(&self) -> &Option<Vec<u8>> {
247        &self.ins
248    }
249
250    /// Gets headers part of Headers frame payload.
251    pub fn get_part(&self) -> Parts {
252        self.parts.clone()
253    }
254
255    pub(crate) fn set_instruction(&mut self, buf: Vec<u8>) {
256        self.ins = Some(buf)
257    }
258}
259
260impl PushPromise {
261    /// Creates a new PushPromise instance from the provided Parts.
262    pub fn new(push_id: u64, parts: Parts) -> Self {
263        PushPromise {
264            push_id,
265            parts,
266            ins: None,
267        }
268    }
269
270    /// Gets push id of PushPromise payload.
271    pub fn get_push_id(&self) -> u64 {
272        self.push_id
273    }
274
275    /// Returns a copy of the internal parts of the Headers.
276    pub(crate) fn get_parts(&self) -> &Parts {
277        &self.parts
278    }
279
280    pub(crate) fn set_instruction(&mut self, buf: Vec<u8>) {
281        self.ins = Some(buf)
282    }
283}
284
285impl GoAway {
286    /// Creates a new GoAway instance from the provided Parts.
287    pub fn new(id: u64) -> Self {
288        GoAway { id }
289    }
290
291    /// Gets go away stream id.
292    pub fn get_id(&self) -> &u64 {
293        &self.id
294    }
295}
296
297impl MaxPushId {
298    /// Creates a new MaxPushId instance from the provided Parts.
299    pub fn new(push_id: u64) -> Self {
300        MaxPushId { push_id }
301    }
302
303    /// Gets allowed max push stream id.
304    pub fn get_id(&self) -> &u64 {
305        &self.push_id
306    }
307}
308