synchronous_server/
lib.rs

1pub use proxy_server;
2pub use proxy_server::http;
3use proxy_server::http::{
4    headers::{Header, Headers},
5    request::{Request, Socket},
6    status::Status,
7    Http,
8};
9use std::{
10    io::{Result, Write},
11    net::TcpListener,
12    str,
13};
14
15macro_rules! trace {
16    ($($args: expr),*) => {
17        format!("TRACE: file: {}, line: {}", file!(), line!())
18    };
19}
20
21pub fn listen<T>(addr: &str, callback: T) -> Result<()>
22where
23    T: Fn(Request) -> Result<(String, u16, Headers)>,
24{
25    let listener = TcpListener::bind(addr)?;
26    println!("listening on: {}", addr);
27    for stream in listener.incoming() {
28        let st = stream;
29        if let Err(err) = st {
30            println!(
31                "Failed to create connection {:?}: {}: {:?}",
32                err,
33                &addr,
34                trace!()
35            );
36            continue;
37        }
38        let st = st.unwrap();
39
40        let mut client = Http::from(st);
41
42        let h = client.read_headers();
43        if let Err(err) = h {
44            println!(
45                "Failed to read headers {:?}: {:?}: {:?}",
46                err,
47                &client.socket,
48                trace!()
49            );
50            continue;
51        }
52        let h = h.unwrap();
53
54        let error = client.socket.take_error().unwrap();
55        let error = match error {
56            None => "".to_string(),
57            Some(val) => val.to_string(),
58        };
59
60        let req = Request::new(
61            Socket {
62                host: client.socket.local_addr().unwrap().to_string(),
63                peer_addr: client.socket.peer_addr().unwrap().to_string(),
64                ttl: client.socket.ttl().unwrap(),
65                error,
66            },
67            h,
68        );
69        if let Err(err) = req {
70            println!(
71                "Failed to create request {:?}: {:?}: {:?}",
72                err,
73                &client.socket,
74                trace!()
75            );
76            continue;
77        }
78        let mut req = req.unwrap();
79
80        let body = client.read_body(&req);
81        if let Err(err) = body {
82            println!("Failed to read body {:?}: {:?}: {:?}", err, &req, trace!());
83            continue;
84        }
85        let body = body.unwrap();
86
87        let body = client.body_to_string(body);
88        if let Err(err) = body {
89            println!(
90                "Failed to stringify body {:?}: {:?}: {:?}",
91                err,
92                &req,
93                trace!()
94            );
95            continue;
96        }
97        req.body = body.unwrap();
98
99        let cb_res = callback(req.clone());
100        if let Err(err) = cb_res {
101            println!(
102                "Failed to handle request {:?}: {:?}: {:?}",
103                err,
104                &req,
105                trace!()
106            );
107            continue;
108        }
109        let (result, code, headers) = cb_res.unwrap();
110
111        let length = result.len();
112        let status = Status::new(code);
113        let mut res_heads = Headers::new_response(
114            &status,
115            vec![
116                Header {
117                    name: "Content-Type".to_string(),
118                    value: "application/json".to_string(),
119                },
120                Header {
121                    name: "Content-Length".to_string(),
122                    value: length.to_string(),
123                },
124                Header {
125                    name: "Server".to_string(),
126                    value: "synchronous-server".to_string(),
127                },
128            ],
129        );
130
131        for h in headers.list {
132            let added_header = res_heads.set_header(h.name.as_str(), h.value.as_str());
133            if let Err(err) = &added_header {
134                println!("Failed to add header {:?}: {:?}: {:?}", err, &h, trace!());
135            }
136            res_heads = added_header.unwrap();
137        }
138
139        let res = client.write(res_heads.raw.as_bytes());
140        if let Err(err) = res {
141            println!(
142                "Failed to write headers {:?}: {:?}: {:?}",
143                err,
144                &req,
145                trace!()
146            );
147            continue;
148        }
149
150        let res = client.write(result.as_bytes());
151        if let Err(err) = res {
152            println!(
153                "Failed to write response {:?}: {:?}: {:?}",
154                err,
155                &req,
156                trace!()
157            );
158            continue;
159        }
160
161        let res = client.set_zero_byte();
162        if let Err(err) = res {
163            println!(
164                "Failed to set zero byte {:?}: {:?}: {:?}",
165                err,
166                &req,
167                trace!()
168            );
169            continue;
170        }
171
172        let res = client.flush();
173        if let Err(err) = res {
174            println!(
175                "Failed to flush client {:?}: {:?}: {:?}",
176                err,
177                &req,
178                trace!()
179            );
180            continue;
181        }
182    }
183    Ok(())
184}