synchronous_server/
lib.rs1pub 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}