-
Notifications
You must be signed in to change notification settings - Fork 6
/
https.rs
87 lines (76 loc) · 2.82 KB
/
https.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
extern crate bytes;
extern crate httparse;
#[macro_use]
extern crate mco;
extern crate native_tls;
use bytes::BufMut;
use httparse::Status;
use mco::net::TcpListener;
use native_tls::{Identity, TlsAcceptor};
use std::fs::File;
use std::io::{Read, Write};
use std::sync::Arc;
// This example is for demonstration only and is suitable for production environment please move on
// example see https://github.com/co-rs/mco-http/tree/main/examples
fn main() {
let mut file = File::open("examples/native-tls/mycert.pfx").unwrap();
let mut identity = vec![];
file.read_to_end(&mut identity).unwrap();
let identity = Identity::from_pkcs12(&identity, "password").unwrap();
let acceptor = TlsAcceptor::new(identity).unwrap();
let acceptor = Arc::new(acceptor);
let listener = TcpListener::bind("0.0.0.0:3000").unwrap();
while let Ok((stream, _)) = listener.accept() {
let acceptor = acceptor.clone();
let mut stream = acceptor.accept(stream).unwrap();
co!(move || {
let mut buf = Vec::new();
let mut path = String::new();
loop {
if let Some(i) = req_done(&buf, &mut path) {
let response = match &*path {
"/" => "Welcome to mco http demo\n",
"/hello" => "Hello, World!\n",
"/quit" => std::process::exit(1),
_ => "Cannot find page\n",
};
let s = format!(
"\
HTTP/1.1 200 OK\r\n\
Server: mco\r\n\
Content-Length: {}\r\n\
date: 1-1-2000\r\n\
\r\n\
{}",
response.len(),
response
);
stream
.write_all(s.as_bytes())
.expect("Cannot write to socket");
buf = buf.split_off(i);
} else {
let mut temp_buf = vec![0; 512];
match stream.read(&mut temp_buf) {
Ok(0) => return, // connection was closed
Ok(n) => buf.put(&temp_buf[0..n]),
Err(err) => {
println!("err = {:?}", err);
break;
}
}
}
}
});
}
}
fn req_done(buf: &[u8], path: &mut String) -> Option<usize> {
let mut headers = [httparse::EMPTY_HEADER; 16];
let mut req = httparse::Request::new(&mut headers);
if let Ok(Status::Complete(i)) = req.parse(buf) {
path.clear();
path.push_str(req.path.unwrap_or("/"));
return Some(i);
}
None
}