Skip to main content

moq_transport/setup/
client.rs

1use super::Versions;
2use crate::coding::{Decode, DecodeError, Encode, EncodeError, KeyValuePairs};
3
4/// Sent by the client to setup the session.
5/// This CLIENT_SETUP message is used by moq-transport draft versions 11 and later.
6/// Id = 0x20 vs 0x40 for versions <= 10.
7#[derive(Debug)]
8pub struct Client {
9    /// The list of supported versions in preferred order.
10    pub versions: Versions,
11
12    /// Setup Parameters, ie: PATH, MAX_REQUEST_ID,
13    /// MAX_AUTH_TOKEN_CACHE_SIZE, AUTHORIZATION_TOKEN, etc.
14    pub params: KeyValuePairs,
15}
16
17impl Decode for Client {
18    /// Decode a client setup message.
19    fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
20        let typ = u64::decode(r)?;
21        if typ != 0x20 {
22            // CLIENT_SETUP message ID for draft versions 11 and later
23            return Err(DecodeError::InvalidMessage(typ));
24        }
25
26        let _len = u16::decode(r)?;
27        // TODO: Check the length of the message.
28
29        let versions = Versions::decode(r)?;
30        let params = KeyValuePairs::decode(r)?;
31
32        Ok(Self { versions, params })
33    }
34}
35
36impl Encode for Client {
37    /// Encode a server setup message.
38    fn encode<W: bytes::BufMut>(&self, w: &mut W) -> Result<(), EncodeError> {
39        (0x20_u64).encode(w)?; // CLIENT_SETUP message ID for draft versions 11 and later
40
41        // Find out the length of the message
42        // by encoding it into a buffer and then encoding the length.
43        // This is a bit wasteful, but it's the only way to know the length.
44        // TODO SLG - perhaps we can store the position of the Length field in the BufMut and
45        //       write the length later, to avoid the copy of the message bytes?
46        let mut buf = Vec::new();
47
48        self.versions.encode(&mut buf).unwrap();
49        self.params.encode(&mut buf).unwrap();
50
51        // Make sure buf.len() <= u16::MAX
52        if buf.len() > u16::MAX as usize {
53            return Err(EncodeError::MsgBoundsExceeded);
54        }
55        (buf.len() as u16).encode(w)?;
56
57        // At least don't encode the message twice.
58        // Instead, write the buffer directly to the writer.
59        Self::encode_remaining(w, buf.len())?;
60        w.put_slice(&buf);
61
62        Ok(())
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69    use crate::setup::{ParameterType, Version};
70    use bytes::BytesMut;
71
72    #[test]
73    fn encode_decode() {
74        let mut buf = BytesMut::new();
75
76        let mut params = KeyValuePairs::default();
77        params.set_bytesvalue(ParameterType::Path.into(), "testpath".as_bytes().to_vec());
78
79        let client = Client {
80            versions: [Version::DRAFT_13].into(),
81            params,
82        };
83        client.encode(&mut buf).unwrap();
84
85        #[rustfmt::skip]
86        assert_eq!(
87            buf.to_vec(),
88            vec![
89                0x20, // Type
90                0x00, 0x14, // Length
91                0x01, // 1 Version
92                0xC0, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0D, // Version DRAFT_13 (0xff00000D)
93                0x01, // 1 Param
94                0x01, 0x08, 0x74, 0x65, 0x73, 0x74, 0x70, 0x61, 0x74, 0x68, // Key=1 (Path), Value="testpath"
95            ]
96        );
97        let decoded = Client::decode(&mut buf).unwrap();
98        assert_eq!(decoded.versions, client.versions);
99        assert_eq!(decoded.params, client.params);
100    }
101}