forked from lavina/lavina
1
0
Fork 0

http server

This commit is contained in:
Nikita Vilunov 2023-01-19 18:18:41 +01:00
parent 1950453cae
commit 734ca6c423
5 changed files with 222 additions and 1 deletions

136
Cargo.lock generated
View File

@ -55,6 +55,45 @@ dependencies = [
"version_check",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "futures-channel"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
dependencies = [
"futures-core",
]
[[package]]
name = "futures-core"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
[[package]]
name = "futures-task"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
[[package]]
name = "futures-util"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
dependencies = [
"futures-core",
"futures-task",
"pin-project-lite",
"pin-utils",
]
[[package]]
name = "hermit-abi"
version = "0.2.6"
@ -64,18 +103,93 @@ dependencies = [
"libc",
]
[[package]]
name = "http"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "http-body"
version = "1.0.0-rc.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "951dfc2e32ac02d67c90c0d65bd27009a635dc9b381a2cc7d284ab01e3a0150d"
dependencies = [
"bytes",
"http",
]
[[package]]
name = "http-body-util"
version = "0.1.0-rc.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92445bc9cc14bfa0a3ce56817dc3b5bcc227a168781a356b702410789cec0d10"
dependencies = [
"bytes",
"futures-util",
"http",
"http-body",
"pin-project-lite",
]
[[package]]
name = "httparse"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
[[package]]
name = "httpdate"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
[[package]]
name = "hyper"
version = "1.0.0-rc.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "289cfdbf735dea222b0ec6a10224b4d9552c7662bb451d4589cbfda3d407d1a3"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"http",
"http-body",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"tokio",
"tracing",
"want",
]
[[package]]
name = "inlinable_string"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb"
[[package]]
name = "itoa"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
[[package]]
name = "lavina"
version = "0.1.0"
dependencies = [
"anyhow",
"figment",
"http-body-util",
"hyper",
"serde",
"tokio",
"tracing",
@ -215,6 +329,12 @@ version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "proc-macro2"
version = "1.0.49"
@ -433,6 +553,12 @@ dependencies = [
"tracing-log",
]
[[package]]
name = "try-lock"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
[[package]]
name = "uncased"
version = "0.9.7"
@ -460,6 +586,16 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "want"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
dependencies = [
"log",
"try-lock",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"

View File

@ -15,6 +15,8 @@ path = "src/main.rs"
[dependencies]
anyhow = "1.0.68" # error utils
figment = { version = "0.10.8", features = ["env", "toml"] } # configuration files
hyper = { version = "1.0.0-rc.2", features = ["server", "http1"] } # http server
http-body-util = "0.1.0-rc.2"
serde = { version = "1.0.152", features = ["rc", "serde_derive"] }
tokio = { version = "1.24.1", features = ["full"] } # async runtime
tracing = "0.1.37" # logging & tracing api

62
src/http.rs Normal file
View File

@ -0,0 +1,62 @@
use crate::prelude::*;
use http_body_util::Full;
use hyper::server::conn::http1;
use hyper::{body::Bytes, service::service_fn, Request, Response};
use std::convert::Infallible;
use tokio::sync::oneshot::{Receiver, Sender};
use tokio::task::JoinHandle;
use tokio::net::TcpListener;
pub struct HttpServerActor {
terminator: Sender<()>,
fiber: JoinHandle<Result<()>>,
}
impl HttpServerActor {
pub async fn launch(listener: TcpListener) -> Result<HttpServerActor> {
let (terminator, receiver) = tokio::sync::oneshot::channel::<()>();
let fiber = tokio::task::spawn(Self::main_loop(listener, receiver));
Ok(HttpServerActor { terminator, fiber })
}
pub async fn terminate(self) -> Result<()> {
match self.terminator.send(()) {
Ok(_) => {}
Err(_) => failure("wat")?,
}
self.fiber.await??;
Ok(())
}
async fn hello(
_: Request<hyper::body::Incoming>,
) -> std::result::Result<Response<Full<Bytes>>, Infallible> {
Ok(Response::new(Full::new(Bytes::from("Hello World!"))))
}
async fn main_loop(listener: TcpListener, termination: impl Future) -> Result<()> {
log::info!("Starting the http server");
pin!(termination);
loop {
select! {
_ = &mut termination => {
log::info!("Terminating the http server");
return Ok(())
},
result = listener.accept() => {
let (stream, _) = result?;
tokio::task::spawn(async move {
if let Err(err) = http1::Builder::new()
.serve_connection(stream, service_fn(HttpServerActor::hello))
.await
{
tracing::error!("Error serving connection: {:?}", err);
}
});
},
}
}
}
}

View File

@ -1,4 +1,7 @@
type Result<T> = std::result::Result<T, anyhow::Error>;
mod http;
mod prelude;
use crate::prelude::*;
use std::collections::HashMap;
use std::future::Future;
@ -39,12 +42,16 @@ async fn main() -> Result<()> {
dbg!(config);
tracing::info!("Booting up");
let listener = TcpListener::bind("127.0.0.1:3721").await?;
let listener_http = TcpListener::bind("127.0.0.1:8080").await?;
let http_server_actor = http::HttpServerActor::launch(listener_http).await?;
tracing::info!("Started");
run(listener, sleep).await?;
// sleep.await;
tracing::info!("Begin shutdown");
http_server_actor.terminate().await?;
tracing::info!("Shutdown complete");
Ok(())
}

14
src/prelude.rs Normal file
View File

@ -0,0 +1,14 @@
pub use tokio::pin;
pub use tokio::select;
pub mod log {
pub use tracing::{debug, error, info, warn};
}
pub type Result<T> = std::result::Result<T, anyhow::Error>;
pub fn failure(explain: &str) -> Result<()> {
panic!()
}
pub use std::future::Future;