rust_rsm/net_ext/
restserver.rs

1#![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}
36//从URL中获取路径,去掉头部
37pub 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
58//map between errcode and HTTP CODE
59pub 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            //println!("recv req={}", req.method().as_str());
110            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=[0u8; MaxBufferSize];
119        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        //println!("[restserver]recv request,url={},msg={}",url,buf);
124        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    //发送错误响应
144    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        //
155        //let resp = http::Response::from_string("HTTP/1.1 200 OK\r\n Server: Rest-Rust\r\n");
156        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 new_body = !format("{}\r\n",body);
165        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}