socks5_protocol_async/protocol/
request.rs

1use super::address::Address;
2use super::shared_internal::*;
3use failure::Error;
4use futures_io::AsyncRead;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct Request {
8    pub command: u8,
9    pub address: super::address::Address,
10    pub port: u16,
11}
12
13impl Request {
14    pub async fn read<AR>(reader: &mut AR) -> Result<Self, Error>
15    where
16        AR: AsyncRead + Unpin,
17    {
18        super::shared_internal::read_version(reader).await?;
19
20        let command = read_u8(reader).await?;
21        let _reserved = read_u8(reader).await?;
22        let address = Address::read(reader).await?;
23        let port = read_u16(reader).await?;
24
25        Ok(Self {
26            command,
27            address,
28            port,
29        })
30    }
31}
32
33#[cfg(test)]
34mod test {
35    use super::*;
36    use crate::test_util::*;
37    use futures_util::io::Cursor;
38
39    #[test]
40    fn happy_path() {
41        let mut reader = Cursor::new(&[
42            5,    // Version
43            0x01, // Command
44            0x00, // Reserved octet
45            0x01, 127, 0, 0, 1, // Address
46            0x00, 80, // Port
47        ]);
48        let future = Request::read(&mut reader);
49        let result = extract_future_output(future);
50        assert_eq!(
51            result.unwrap(),
52            Request {
53                command: 0x01,
54                address: Address::IPv4([127, 0, 0, 1]),
55                port: 80,
56            }
57        )
58    }
59
60    #[test]
61    fn invalid_version() {
62        let mut reader = Cursor::new(&[1]);
63        let future = Request::read(&mut reader);
64        let result = extract_future_output(future);
65        let err = result.unwrap_err();
66        let err = err
67            .downcast::<crate::error::InvalidProtocolVersionError>()
68            .unwrap();
69        assert_eq!(err, crate::error::InvalidProtocolVersionError(1))
70    }
71
72    #[test]
73    fn not_enough_data() {
74        let mut reader = Cursor::new(&[]);
75        let future = Request::read(&mut reader);
76        let result = extract_future_output(future);
77        let err = result.unwrap_err();
78        let err = err.downcast::<std::io::Error>().unwrap();
79        assert_eq!(err.kind(), std::io::ErrorKind::UnexpectedEof);
80    }
81}