ui work
This commit is contained in:
@@ -1,3 +1,122 @@
|
||||
pub fn run_server() {
|
||||
println!("hello world!")
|
||||
use quinn::{
|
||||
Endpoint,
|
||||
crypto::rustls::QuicServerConfig,
|
||||
rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer},
|
||||
};
|
||||
use std::{fs, net::SocketAddr, path::Path, str::FromStr, sync::Arc};
|
||||
use tracing::Instrument;
|
||||
|
||||
use crate::net::ClientMsg;
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn run_server() {
|
||||
quinn::rustls::crypto::aws_lc_rs::default_provider()
|
||||
.install_default()
|
||||
.unwrap();
|
||||
|
||||
let dirs = directories_next::ProjectDirs::from("", "", "openworm").unwrap();
|
||||
let path = dirs.data_local_dir();
|
||||
let endpoint = listen(path);
|
||||
println!("listening on {}", endpoint.local_addr().unwrap());
|
||||
|
||||
while let Some(conn) = endpoint.accept().await {
|
||||
let fut = handle_connection(conn);
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = fut.await {
|
||||
eprintln!("connection failed: {reason}", reason = e)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
println!("hello world!");
|
||||
}
|
||||
|
||||
pub fn listen(data_path: &Path) -> Endpoint {
|
||||
let cert_path = data_path.join("cert.der");
|
||||
let key_path = data_path.join("key.der");
|
||||
let (cert, key) = match fs::read(&cert_path).and_then(|x| Ok((x, fs::read(&key_path)?))) {
|
||||
Ok((cert, key)) => (
|
||||
CertificateDer::from(cert),
|
||||
PrivateKeyDer::try_from(key).unwrap(),
|
||||
),
|
||||
Err(ref e) if e.kind() == std::io::ErrorKind::NotFound => {
|
||||
let cert = rcgen::generate_simple_self_signed(vec!["localhost".into()]).unwrap();
|
||||
let key = PrivatePkcs8KeyDer::from(cert.signing_key.serialize_der());
|
||||
let cert = cert.cert.into();
|
||||
fs::create_dir_all(data_path).expect("failed to create certificate directory");
|
||||
fs::write(&cert_path, &cert).expect("failed to write certificate");
|
||||
fs::write(&key_path, key.secret_pkcs8_der()).expect("failed to write private key");
|
||||
(cert, key.into())
|
||||
}
|
||||
Err(e) => {
|
||||
panic!("failed to read certificate: {}", e);
|
||||
}
|
||||
};
|
||||
let server_crypto = quinn::rustls::ServerConfig::builder()
|
||||
.with_no_client_auth()
|
||||
.with_single_cert(vec![cert], key)
|
||||
.unwrap();
|
||||
|
||||
let mut server_config = quinn::ServerConfig::with_crypto(Arc::new(
|
||||
QuicServerConfig::try_from(server_crypto).unwrap(),
|
||||
));
|
||||
let transport_config = Arc::get_mut(&mut server_config.transport).unwrap();
|
||||
transport_config.max_concurrent_uni_streams(0_u8.into());
|
||||
|
||||
quinn::Endpoint::server(server_config, SocketAddr::from_str("[::1]:4433").unwrap()).unwrap()
|
||||
}
|
||||
|
||||
async fn handle_connection(conn: quinn::Incoming) -> std::io::Result<()> {
|
||||
let connection = conn.await?;
|
||||
let span = tracing::info_span!(
|
||||
"connection",
|
||||
remote = %connection.remote_address(),
|
||||
protocol = %connection
|
||||
.handshake_data()
|
||||
.unwrap()
|
||||
.downcast::<quinn::crypto::rustls::HandshakeData>().unwrap()
|
||||
.protocol
|
||||
.map_or_else(|| "<none>".into(), |x| String::from_utf8_lossy(&x).into_owned())
|
||||
);
|
||||
async {
|
||||
// Each stream initiated by the client constitutes a new request.
|
||||
loop {
|
||||
let stream = connection.accept_bi().await;
|
||||
// let time = Instant::now();
|
||||
let stream = match stream {
|
||||
Err(quinn::ConnectionError::ApplicationClosed { .. }) => {
|
||||
println!("connection closed");
|
||||
return Ok(());
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
Ok(s) => s,
|
||||
};
|
||||
tokio::spawn(
|
||||
async move {
|
||||
if let Err(e) = handle_stream(stream).await {
|
||||
eprintln!("failed: {reason}", reason = e);
|
||||
}
|
||||
}
|
||||
.instrument(tracing::info_span!("request")),
|
||||
);
|
||||
}
|
||||
}
|
||||
.instrument(span)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_stream(
|
||||
(send, mut recv): (quinn::SendStream, quinn::RecvStream),
|
||||
) -> Result<(), String> {
|
||||
drop(send);
|
||||
let msg = recv
|
||||
.read_to_end(std::mem::size_of::<ClientMsg>())
|
||||
.await
|
||||
.map_err(|e| format!("failed reading request: {}", e))?;
|
||||
println!("received message");
|
||||
println!("{:?}", msg);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user