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
62
63
64
65
66
67
68
69
70
71
72
#[cfg(any(feature = "std_io", feature = "futures_util_io"))]
use std::io::{self, Cursor};

#[cfg(any(feature = "std_io", feature = "futures_util_io"))]
use tls_client_hello_parser::{ClientHelloPayload, ParseOutput, Parser};

#[cfg(feature = "std_io")]
use std_io_peek::Peek;

#[cfg(feature = "futures_util_io")]
use futures_util_io_peek::{AsyncPeek, AsyncPeekExt};

pub struct Detector {
    #[cfg(any(feature = "std_io", feature = "futures_util_io"))]
    parser: Parser,
}

impl Detector {
    #[cfg(any(feature = "std_io", feature = "futures_util_io"))]
    pub fn new() -> Self {
        Self {
            parser: Parser::new(),
        }
    }

    #[cfg(feature = "std_io")]
    pub fn detect<P: Peek>(&mut self, p: &mut P) -> io::Result<ClientHelloPayload> {
        let mut v = vec![0u8; 16 * 1024];
        let mut buf = Cursor::new(vec![]);

        loop {
            match p.peek_sync(&mut v)? {
                0 => return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "")),
                n => {
                    buf.get_mut().extend_from_slice(&v[..n]);
                    match self.parser.parse(&mut buf)? {
                        ParseOutput::Done(chp) => return Ok(chp),
                        ParseOutput::Partial => continue,
                        ParseOutput::Invalid(e) => {
                            return Err(io::Error::new(io::ErrorKind::UnexpectedEof, e))
                        }
                    }
                }
            }
        }
    }

    #[cfg(feature = "futures_util_io")]
    pub async fn detect_async<P: AsyncPeek + Unpin>(
        &mut self,
        p: &mut P,
    ) -> io::Result<ClientHelloPayload> {
        let mut v = vec![0u8; 16 * 1024];
        let mut buf = Cursor::new(vec![]);

        loop {
            match p.peek_async(&mut v).await? {
                0 => return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "")),
                n => {
                    buf.get_mut().extend_from_slice(&v[..n]);
                    match self.parser.parse(&mut buf)? {
                        ParseOutput::Done(chp) => return Ok(chp),
                        ParseOutput::Partial => continue,
                        ParseOutput::Invalid(e) => {
                            return Err(io::Error::new(io::ErrorKind::UnexpectedEof, e))
                        }
                    }
                }
            }
        }
    }
}