Skip to main content

sark_http/
preface.rs

1pub const CLIENT_PREFACE: &[u8] = b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
2
3#[derive(Debug, Default)]
4pub struct Prefix(u8);
5
6#[derive(Debug)]
7pub struct Complete(());
8
9#[derive(Debug)]
10pub enum Read {
11    Pending(Prefix),
12    Complete(Complete),
13}
14
15#[derive(Debug)]
16pub struct Mismatch {
17    prefix: Prefix,
18    offset: u8,
19    actual: u8,
20}
21
22impl AsRef<[u8]> for Prefix {
23    fn as_ref(&self) -> &[u8] {
24        &CLIENT_PREFACE[..self.0 as usize]
25    }
26}
27
28impl Prefix {
29    pub fn read(self, bytes: &[u8]) -> Result<(usize, Read), Mismatch> {
30        let offset = self.0 as usize;
31        let expected = &CLIENT_PREFACE[offset..];
32        let count = expected.len().min(bytes.len());
33        for (index, (&expected, &actual)) in expected.iter().zip(bytes).enumerate() {
34            if actual != expected {
35                return Err(Mismatch {
36                    prefix: self,
37                    offset: (offset + index) as u8,
38                    actual,
39                });
40            }
41        }
42        let matched = offset + count;
43        let read = if matched == CLIENT_PREFACE.len() {
44            Read::Complete(Complete(()))
45        } else {
46            Read::Pending(Self(matched as u8))
47        };
48        Ok((count, read))
49    }
50}
51
52impl Mismatch {
53    pub fn into_parts(self) -> (Prefix, usize, u8, u8) {
54        let offset = self.offset as usize;
55        (self.prefix, offset, CLIENT_PREFACE[offset], self.actual)
56    }
57}