example_custom_parser/
example_custom_parser.rs

1use std::{fmt, io::Cursor};
2
3use byteorder::{BigEndian, ReadBytesExt};
4use haprox_rs::{common, protocol::{PP2TlvDump, PP2TlvRestore}, ProxyV2Parser, return_error, HaProxRes, HdrV2Command, PP2TlvClient, PP2Tlvs, ProtocolVersion, ProxyTransportFam, ProxyV2Addr, ProxyV2AddrType, PP2_TYPE_MIN_CUSTOM};
5
6
7#[derive(Clone, Debug)]
8pub enum ProxyV2Dummy2 
9{
10    SomeTlvName(u32, u32),
11    OtherTlv,
12}
13
14impl fmt::Display for ProxyV2Dummy2
15{
16    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result 
17    {
18        write!(f, "DUMMY external reader")
19    }
20}
21
22impl PP2TlvRestore for ProxyV2Dummy2
23{
24    fn restore(tlv_type: u8, cur: &mut Cursor<&[u8]>) -> HaProxRes<Self> where Self: Sized 
25    {
26        match tlv_type
27        {
28            0xE0 =>
29            {
30                let arg0 = cur.read_u32::<BigEndian>().map_err(common::map_io_err)?;
31                let arg1 = cur.read_u32::<BigEndian>().map_err(common::map_io_err)?;
32
33                return Ok(Self::SomeTlvName(arg0, arg1));
34            },
35            _ => 
36                return_error!(ProtocolUnknownData, "unknown tlv_type: {}", tlv_type)
37        }
38        
39    }
40    
41    fn is_in_range(tlv_type: u8, _tlv_parent_type: Option<u8>) -> bool 
42    {
43        return tlv_type == PP2_TYPE_MIN_CUSTOM;
44    }
45    
46    fn contains_subtype(&self) -> bool 
47    {
48        return false;
49    }
50}
51
52impl PP2TlvDump for ProxyV2Dummy2
53{
54    fn get_type(&self) -> u8 
55    {
56        let Self::SomeTlvName(..) = self else { panic!("wrong") };
57
58        return 0xE0;
59    }
60
61    fn dump(&self, _cur: &mut Cursor<Vec<u8>>) -> HaProxRes<()> 
62    {
63        todo!()
64    }
65}
66
67
68fn main() -> HaProxRes<()>
69{
70
71    let pkt_ssl = 
72b"\x0d\x0a\x0d\x0a\x00\x0d\x0a\x51\x55\x49\x54\x0a\x21\x11\x00\x1e\
73\x7f\x00\x00\x01\x7f\x00\x00\x43\x9b\x4a\x2e\x6b\x20\x00\x0f\x01\
74\x00\x00\x00\x00\x21\x00\x07\x54\x4c\x53\x76\x31\x2e\x32\xE0\x00\
75\x08\x01\x02\x03\x04\x05\x06\x07\x08";
76
77        let dec = ProxyV2Parser::<ProxyV2Dummy2>::try_from_slice_custom(pkt_ssl.as_slice()).unwrap();
78
79        assert_eq!(dec.get_transport().is_ok(), true);
80        assert_eq!(dec.get_transport().unwrap(), ProxyTransportFam::STREAM);
81
82        assert_eq!(dec.get_proto_version(), ProtocolVersion::V2);
83        assert_eq!(dec.get_proto_command(), HdrV2Command::PROXY);
84
85        assert_eq!(dec.get_address_family().is_ok(), true);
86        assert_eq!(dec.get_address_family().unwrap(), ProxyV2AddrType::AfInet);
87        
88        let addr = dec.get_address().unwrap();
89
90        assert_eq!(addr.is_some(), true);
91
92        let addr = addr.unwrap();
93        let maddr = ProxyV2Addr::try_from(("127.0.0.1:39754", "127.0.0.67:11883")).unwrap();
94
95        assert_eq!(addr, maddr);
96
97        let tlv_iter = dec.get_tlvs_iter();
98
99        assert_eq!(tlv_iter.is_some(), true);
100
101        let mut tlv_iter = tlv_iter.unwrap();
102
103        let type_ssl = tlv_iter.next().unwrap().take_internal().unwrap();
104
105        assert_eq!(type_ssl.get_type(), PP2Tlvs::TYPE_SSL);
106        let PP2Tlvs::TypeSsl { client, verify } = type_ssl else {panic!("wrong")};
107
108        assert_eq!(client, PP2TlvClient::PP2_CLIENT_SSL);
109        assert_eq!(verify, 0);
110
111        // --
112        let type_ssl_version = tlv_iter.next().unwrap().take_internal().unwrap();
113
114        assert_eq!(type_ssl_version.get_type(), PP2Tlvs::TYPE_SUBTYPE_SSL_VERSION);
115
116        let PP2Tlvs::TypeSubtypeSslVersion(ssl_version) = type_ssl_version else { panic!("wrong") };
117
118        assert_eq!(ssl_version, "TLSv1.2");
119
120        // ---
121        let ext_type_e0 = tlv_iter.next().unwrap().take_external().unwrap();
122
123        assert_eq!(ext_type_e0.get_type(), 0xE0);
124
125        let ProxyV2Dummy2::SomeTlvName(arg0, arg1) = ext_type_e0 else {panic!("wrong")};
126
127        assert_eq!(arg0, 0x01020304);
128        assert_eq!(arg1, 0x05060708);
129
130
131    return Ok(());
132}