proxy_server/prelude/
mod.rs

1use regex::Regex;
2use std::{
3    io::{Result, Write},
4    net::{TcpListener, TcpStream},
5    str,
6};
7
8use crate::{
9    http::{
10        headers::{Header, Headers},
11        request::{Request, Socket},
12        status::Status,
13        Http, CRLF,
14    },
15    log::{Log, LogLevel},
16};
17pub mod constants;
18
19/// Set spaces before capitalize letters. For change [`Http::Status`] enum items.
20pub fn space_bef_cap(src: String) -> String {
21    let chars = src.chars().into_iter();
22    let mut res = "".to_string();
23    for v in chars {
24        let mut buf = [0; 2];
25        v.encode_utf8(&mut buf);
26        let ch = Regex::new(r"[A-Z]{1}")
27            .unwrap()
28            .captures(&str::from_utf8(&buf).unwrap());
29        if let Some(_) = ch {
30            if src != "OK" {
31                res.push(' ');
32            } else if v == 'O' {
33                res.push(' ')
34            }
35        }
36        res.push(v);
37    }
38    res
39}
40
41pub fn target(addr: &str) -> Result<()> {
42    let listener = TcpListener::bind(addr)?;
43    println!("listening target on {}", addr);
44    for stream in listener.incoming() {
45        handle_target(stream?)?;
46    }
47    Ok(())
48}
49
50pub fn handle_target(client: TcpStream) -> Result<()> {
51    const TAG: &str = "Handle target";
52    let _log = Log::new(&super::LOG_LEVEL);
53    let mut client = Http::from(client);
54    _log.println(LogLevel::Info, TAG, "start client", &client);
55
56    let req_heads = client.read_headers()?;
57
58    let error = client.socket.take_error().unwrap();
59    let error = match error {
60        None => "".to_string(),
61        Some(val) => val.to_string(),
62    };
63
64    let req = Request::new(
65        Socket {
66            host: client.socket.local_addr().unwrap().to_string(),
67            peer_addr: client.socket.peer_addr().unwrap().to_string(),
68            ttl: client.socket.ttl().unwrap(),
69            error,
70        },
71        req_heads,
72    )?;
73    _log.println(LogLevel::Info, TAG, "headers", &req.headers);
74
75    let res_heads = Headers::new_response(
76        &Status::new(200),
77        vec![
78            Header {
79                name: "Content-Type".to_string(),
80                value: "plain/text".to_string(),
81            },
82            Header {
83                name: "Transfer-Encoding".to_string(),
84                value: "chunked".to_string(),
85            },
86            Header {
87                name: "Server".to_string(),
88                value: "echo-rs".to_string(),
89            },
90        ],
91    );
92
93    client.write(res_heads.raw.as_bytes())?;
94
95    if req.content_length != 0 {
96        let body = client.read_body(&req)?;
97        _log.println(LogLevel::Info, TAG, "body", str::from_utf8(&body).unwrap());
98        for i in body {
99            let chunk = format!("1{CRLF}{}{CRLF}", str::from_utf8(&[i]).unwrap());
100            client.write(chunk.as_bytes())?;
101        }
102    }
103
104    client.set_zero_byte()?;
105    client.flush()?;
106    _log.println(LogLevel::Info, TAG, "end client", client);
107    Ok(())
108}