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
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use crate::{frames::reader::FrameDecoder, Error, Res};
use neqo_common::{Decoder, Encoder};
use std::convert::TryFrom;
pub(crate) type WebTransportFrameType = u64;
const WT_FRAME_CLOSE_SESSION: WebTransportFrameType = 0x2843;
const WT_FRAME_CLOSE_MAX_MESSAGE_SIZE: u64 = 1024;
#[derive(PartialEq, Eq, Debug)]
pub enum WebTransportFrame {
CloseSession { error: u32, message: String },
}
impl WebTransportFrame {
pub fn encode(&self, enc: &mut Encoder) {
enc.encode_varint(WT_FRAME_CLOSE_SESSION);
let WebTransportFrame::CloseSession { error, message } = &self;
enc.encode_varint(4 + message.len() as u64);
enc.encode_uint(4, *error);
enc.encode(message.as_bytes());
}
}
impl FrameDecoder<WebTransportFrame> for WebTransportFrame {
fn decode(
frame_type: u64,
frame_len: u64,
data: Option<&[u8]>,
) -> Res<Option<WebTransportFrame>> {
if let Some(payload) = data {
let mut dec = Decoder::from(payload);
if frame_type == WT_FRAME_CLOSE_SESSION {
if frame_len > WT_FRAME_CLOSE_MAX_MESSAGE_SIZE + 4 {
return Err(Error::HttpMessageError);
}
let error =
u32::try_from(dec.decode_uint(4).ok_or(Error::HttpMessageError)?).unwrap();
let message = match String::from_utf8(dec.decode_remainder().to_vec()) {
Ok(s) => s,
Err(_) => return Err(Error::HttpMessageError),
};
Ok(Some(WebTransportFrame::CloseSession { error, message }))
} else {
Ok(None)
}
} else {
Ok(None)
}
}
fn is_known_type(frame_type: u64) -> bool {
frame_type == WT_FRAME_CLOSE_SESSION
}
}
|