forked from lavina/lavina
http server
This commit is contained in:
parent
1950453cae
commit
734ca6c423
|
@ -55,6 +55,45 @@ dependencies = [
|
||||||
"version_check",
|
"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]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
|
@ -64,18 +103,93 @@ dependencies = [
|
||||||
"libc",
|
"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]]
|
[[package]]
|
||||||
name = "inlinable_string"
|
name = "inlinable_string"
|
||||||
version = "0.1.15"
|
version = "0.1.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb"
|
checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lavina"
|
name = "lavina"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"figment",
|
"figment",
|
||||||
|
"http-body-util",
|
||||||
|
"hyper",
|
||||||
"serde",
|
"serde",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
@ -215,6 +329,12 @@ version = "0.2.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.49"
|
version = "1.0.49"
|
||||||
|
@ -433,6 +553,12 @@ dependencies = [
|
||||||
"tracing-log",
|
"tracing-log",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "try-lock"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uncased"
|
name = "uncased"
|
||||||
version = "0.9.7"
|
version = "0.9.7"
|
||||||
|
@ -460,6 +586,16 @@ version = "0.9.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
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]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
|
|
@ -15,6 +15,8 @@ path = "src/main.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.68" # error utils
|
anyhow = "1.0.68" # error utils
|
||||||
figment = { version = "0.10.8", features = ["env", "toml"] } # configuration files
|
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"] }
|
serde = { version = "1.0.152", features = ["rc", "serde_derive"] }
|
||||||
tokio = { version = "1.24.1", features = ["full"] } # async runtime
|
tokio = { version = "1.24.1", features = ["full"] } # async runtime
|
||||||
tracing = "0.1.37" # logging & tracing api
|
tracing = "0.1.37" # logging & tracing api
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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::collections::HashMap;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
@ -39,12 +42,16 @@ async fn main() -> Result<()> {
|
||||||
dbg!(config);
|
dbg!(config);
|
||||||
tracing::info!("Booting up");
|
tracing::info!("Booting up");
|
||||||
let listener = TcpListener::bind("127.0.0.1:3721").await?;
|
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");
|
tracing::info!("Started");
|
||||||
|
|
||||||
run(listener, sleep).await?;
|
run(listener, sleep).await?;
|
||||||
|
|
||||||
// sleep.await;
|
// sleep.await;
|
||||||
tracing::info!("Begin shutdown");
|
tracing::info!("Begin shutdown");
|
||||||
|
http_server_actor.terminate().await?;
|
||||||
tracing::info!("Shutdown complete");
|
tracing::info!("Shutdown complete");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
Loading…
Reference in New Issue