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
use ntex::service::{ServiceFactory, fn_service};
use ntex_error::Error;
use ntex_h2::{Control, Message, MessageKind, OperationError, server};
use ntex_http::{HeaderMap, StatusCode, header};
use ntex_tls::openssl::SslAcceptor;
use openssl::ssl::{self, AlpnError, SslFiletype, SslMethod};
#[ntex::main]
async fn main() -> std::io::Result<()> {
let _ = env_logger::try_init();
// create self-signed certificates using:
// openssl req -x509 -nodes -subj '/CN=localhost' -newkey rsa:4096 -keyout examples/key8.pem -out examples/cert.pem -days 365 -keyform PEM
// openssl rsa -in examples/key8.pem -out examples/key.pem
let mut builder = ssl::SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
builder
.set_private_key_file("./tests/key.pem", SslFiletype::PEM)
.unwrap();
builder
.set_certificate_chain_file("./tests/cert.pem")
.unwrap();
builder.set_alpn_select_callback(|_, protos| {
const H2: &[u8] = b"\x02h2";
if protos.windows(3).any(|window| window == H2) {
Ok(b"h2")
} else {
Err(AlpnError::NOACK)
}
});
let acceptor = builder.build();
ntex::server::build()
.bind("http", "127.0.0.1:5928", async move |_| {
SslAcceptor::new(acceptor.clone())
.map_err(|_err| server::ServerError::Service(()))
.and_then(
server::Server::new(fn_service(|msg: Message| async move {
let Message { stream, kind } = msg;
match kind {
MessageKind::Headers {
pseudo,
headers,
eof,
} => {
println!(
"Got request (eof: {}): {:#?}\nheaders: {:#?}",
eof, pseudo, headers
);
// return Err(());
let mut hdrs = HeaderMap::default();
hdrs.insert(
header::CONTENT_TYPE,
header::HeaderValue::try_from("text/plain").unwrap(),
);
stream.send_response(StatusCode::OK, hdrs, false)?;
stream.send_payload("hello world".into(), false).await?;
let mut hdrs = HeaderMap::default();
hdrs.insert(
header::CONTENT_TYPE,
header::HeaderValue::try_from("blah").unwrap(),
);
stream.send_trailers(hdrs);
}
MessageKind::Data(data, _cap) => {
println!("Got data: {:?}", data.len());
}
MessageKind::Eof(data) => {
println!("Got eof: {:?}", data);
}
MessageKind::Disconnect(err) => {
log::trace!("Disconnect: {:?}", err);
}
}
Ok::<_, Error<OperationError>>(())
}))
.control(|msg: Control<_>| async move {
println!("Control message: {:?}", msg);
Ok::<_, ()>(msg.ack())
}),
)
})?
.workers(1)
.run()
.await
}