socks5_protocol_async/protocol/
request.rs1use 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, 0x01, 0x00, 0x01, 127, 0, 0, 1, 0x00, 80, ]);
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}