proxy_server/http/
mod.rs

1pub mod headers;
2pub mod request;
3pub mod status;
4use self::request::Request;
5
6use super::log::Log;
7use super::prelude::constants::*;
8///! Module [`Http`].
9///! The minimum set of methods to work through [`TcpStream`].
10use regex::Regex;
11use std::{
12    io::{Error, ErrorKind, Read, Result, Write},
13    net::TcpStream,
14    str,
15};
16
17/// End of line constant ([`\r\n`])
18pub const CRLF: &str = "\r\n";
19
20#[derive(Debug)]
21pub struct Http {
22    pub socket: TcpStream,
23}
24
25impl Http {
26    /// Create [`Http`] with new TCP connection
27    pub fn connect(address: &str) -> Result<Http> {
28        let socket = TcpStream::connect(address)?;
29        Ok(Http::from(socket))
30    }
31
32    /// Create [`Http`] from exists socket
33    pub fn from(socket: TcpStream) -> Http {
34        Http { socket }
35    }
36
37    /// Write end of request
38    pub fn set_zero_byte(&mut self) -> Result<usize> {
39        self.write(format!("0{CRLF}{CRLF}").as_bytes())
40    }
41
42    /// Read request body
43    pub fn read_body(&mut self, req: &Request) -> Result<Vec<u8>> {
44        let mut buf: Vec<u8> = vec![];
45        if req.content_length == 0 && !req.chunked {
46            return Ok(vec![]);
47        }
48        loop {
49            let mut chunk = [0; super::CHUNK_SIZE];
50            self.read(&mut chunk)?;
51            let mut exit = false;
52            'b: for ch in chunk {
53                if ch == 0 {
54                    exit = true;
55                    break 'b;
56                }
57                buf.push(ch);
58            }
59            if exit == true {
60                break;
61            }
62        }
63        Ok(buf)
64    }
65
66    /// Body to string
67    pub fn body_to_string(&mut self, body: Vec<u8>) -> Result<String> {
68        let res = str::from_utf8(&body);
69        if let Err(err) = res {
70            println!("{}", err);
71            return Err(Error::new(
72                ErrorKind::InvalidData,
73                "Failed to parse body to string",
74            ));
75        }
76        let result = res.unwrap();
77        let rec = Regex::new(r"\d*\r\n(0$)?").unwrap().replace_all(result, "");
78        Ok(rec.to_string())
79    }
80
81    /// Client - Target tunnel core
82    pub fn tunnel(&mut self, http: &mut Self, _log: &Log) -> Result<usize> {
83        let mut size: usize = 0;
84        loop {
85            let mut b = [0; CHUNK_SIZE];
86            http.read(&mut b)?;
87            let mut buf = vec![];
88            b.map(|_b| {
89                if _b != 0 {
90                    buf.push(_b);
91                    return true;
92                }
93                false
94            });
95
96            size += buf.len();
97
98            if buf.len() == 0 {
99                break;
100            }
101
102            self.write(&buf)?;
103        }
104
105        Ok(size)
106    }
107
108    /// Read request headers by one byte for fist empty line
109    pub fn read_headers(&mut self) -> Result<Vec<u8>> {
110        let mut buf: Vec<u8> = vec![];
111        loop {
112            let mut b = [0; 1];
113            let len = self.read(&mut b)?;
114            if len == 0 {
115                break;
116            }
117            let b = b[0];
118            let len = buf.len();
119            if len > 2
120                && b == 10
121                && (buf[len - 1] == 10 || (buf[len - 1] == 13 && buf[len - 2] == 10))
122            {
123                buf.push(b);
124                break;
125            }
126            buf.push(b);
127        }
128        Ok(buf)
129    }
130}
131
132impl Read for Http {
133    /// Read chunk bytes from request
134    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
135        self.socket.read(buf)
136    }
137}
138
139impl Write for Http {
140    fn write(&mut self, data: &[u8]) -> Result<usize> {
141        self.socket.write(data)
142    }
143
144    fn flush(&mut self) -> Result<()> {
145        self.socket.flush()
146    }
147}