rust_rsm/net_ext/
restserver.rs1#![allow(non_camel_case_types)]
2#![allow(non_snake_case)]
3#![allow(non_upper_case_globals)]
4use crate::common::errcode;
5use std::net::{self, TcpListener};
6use std::thread;
7use tiny_http as http;
8
9const _DEBUG: bool = true;
10
11pub const MAX_BUFFER_SIZE: usize = 32768;
12pub const DEF_SERVER_PORT: u16 = 10011;
13pub type Method = http::Method;
14
15pub enum E_CONTENT_TYPE {
16 e_content_text =0,
17 e_application_json =1,
18}
19impl E_CONTENT_TYPE {
20 pub fn to_string(&self)->&str{
21 match self {
22 Self::e_content_text=>"text/plain",
23 Self::e_application_json=>"application/json",
24 }
25 }
26}
27pub type RestCallBack =
28 fn(method: &Method, path: &str, body: &String) -> Result<(String,E_CONTENT_TYPE), errcode::RESULT>;
29
30pub struct RestServer {
31 local_addr: net::SocketAddr,
32 server: http::Server,
33 call_back: RestCallBack,
34 terminated: bool,
35}
36pub fn get_url_path(url: &str) -> Result<String, errcode::RESULT> {
38 let res = url.find("//");
39 match res {
40 None => {
41 let res1 = url.find("/");
42 match res1 {
43 None => Err(errcode::ERROR_NOT_FOUND),
44 Some(pos) => Ok(String::from(&url[pos..url.len()])),
45 }
46 }
47 Some(pos) => {
48 let subs = String::from(&url[pos + 2..url.len()]);
49 let res1 = subs.find("/");
50 match res1 {
51 None => Err(errcode::ERROR_NOT_FOUND),
52 Some(pos) => Ok(String::from(&subs[pos..subs.len()])),
53 }
54 }
55 }
56}
57
58pub fn error_to_http_code(ec: errcode::RESULT) -> http::StatusCode {
60 let code = match ec {
61 errcode::RESULT_SUCCESS => errcode::HTTP_SUCCESS,
62 errcode::ERROR_DECODE_MSG => errcode::HTTP_BAD_REQUEST,
63 errcode::ERROR_NO_PERMISSION => errcode::HTTP_FORBIDDEN,
64 errcode::ERROR_COMMON => errcode::HTTP_SERVER_NOT_IMPLEMENT,
65 errcode::ERROR_NOT_FOUND => errcode::HTTP_NOT_FOUND,
66 errcode::ERROR_NOT_SUPPORT => errcode::HTTP_SERVER_NOT_IMPLEMENT,
67 _ => errcode::HTTP_BAD_REQUEST,
68 };
69
70 http::StatusCode::from(code)
71}
72
73impl RestServer {
74 pub fn new(
75 ip: net::IpAddr,
76 port: u16,
77 call_back: RestCallBack,
78 ) -> Result<RestServer, errcode::RESULT> {
79 let localAddr = net::SocketAddr::new(ip, port);
80
81 let res = TcpListener::bind(localAddr);
82 let rs = match res {
83 Ok(listener) => http::Server::from_listener(listener, None).unwrap(),
84 Err(_e) => return Err(errcode::ERROR_BIND_SOCKET),
85 };
86 let server = RestServer {
87 local_addr: localAddr,
88 server: rs,
89 call_back: call_back,
90 terminated: false,
91 };
92
93 return Ok(server);
94 }
95
96 pub fn run(self) -> thread::JoinHandle<()> {
97 let h = thread::spawn(move || self.event_loop());
98 return h;
99 }
100 pub fn terminate(&mut self) {
101 if !self.terminated {
102 self.terminated = true;
103 }
104 }
105
106 fn event_loop(&self) {
107 println!("[RestServer]Entering Event Loop");
108 for req in self.server.incoming_requests() {
109 self.handle_request(req);
111 if self.terminated {
112 break;
113 }
114 }
115 }
116
117 fn handle_request(&self, mut req: http::Request) -> errcode::RESULT {
118 let mut buf = String::with_capacity(MAX_BUFFER_SIZE);
120
121 let res = req.as_reader().read_to_string(&mut buf);
122 let url = req.url();
123 let _len = match res {
125 Ok(len) => len,
126 Err(_) => {
127 self.send_err_resp(req, errcode::ERROR_DECODE_MSG, "Read Buffer Error");
128 return errcode::ERROR_DECODE_MSG;
129 }
130 };
131 let path = match get_url_path(&url.to_lowercase()) {
132 Ok(s) => s,
133 Err(_) => String::default(),
134 };
135 let ret = (self.call_back)(req.method(), &path, &buf);
136 match ret {
137 Ok((body,ctype)) => self.send_success_resp(req, ctype, body),
138 Err(ec) => self.send_err_resp(req, ec, errcode::errcode_to_string(ec)),
139 }
140 errcode::RESULT_SUCCESS
141 }
142
143 fn send_err_resp(&self, req: http::Request, err: errcode::RESULT, msg: &str) {
145
146 let respCode = error_to_http_code(err);
147 let new_msg=format!("{}\r\n",msg);
148 let mut resp = http::Response::new_empty(respCode)
149 .with_data(new_msg.as_bytes(), Some(new_msg.len()))
150 .with_header(http::Header::from_bytes(&b"Server"[..], &b"Rest-Server"[..]).unwrap());
151 resp.add_header(
152 http::Header::from_bytes(&b"content-type"[..], &b"text/plain"[..]).unwrap(),
153 );
154 match req.respond(resp) {
157 Ok(())=>(),
158 Err(e)=>println!("Send response error,code={},err={},msg_body={}",err,e,msg),
159 }
160 }
161
162 fn send_success_resp(&self, req: http::Request, ctype:E_CONTENT_TYPE,body: String) {
163 let respCode = http::StatusCode::from(errcode::HTTP_SUCCESS);
164 let mut resp = http::Response::new_empty(respCode)
166 .with_data(body.as_bytes(), Some(body.len()))
167 .with_header(http::Header::from_bytes(&b"Server"[..], &b"Rest-Server"[..]).unwrap());
168 if body.len()> 0 {
169 resp.add_header(
170 http::Header::from_bytes(&b"content-type"[..], ctype.to_string().as_bytes()).unwrap(),
171 );
172 }
173
174 req.respond(resp).unwrap();
175 }
176}