forked from lavina/lavina
				
			http server
This commit is contained in:
		
							parent
							
								
									1950453cae
								
							
						
					
					
						commit
						734ca6c423
					
				|  | @ -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" | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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::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(()) | ||||
| } | ||||
|  |  | |||
|  | @ -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