Basic HTTP web server
This commit is contained in:
parent
c17baa112c
commit
44222d2d9a
4 changed files with 1412 additions and 1 deletions
1311
Cargo.lock
generated
1311
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -5,4 +5,12 @@ authors = ["traxys <quentin@familleboyer.net>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
axum = "0.6.20"
|
||||||
|
envious = "0.2.2"
|
||||||
|
serde = { version = "1.0.190", features = ["derive"] }
|
||||||
|
tera = "1.19.1"
|
||||||
|
thiserror = "1.0.50"
|
||||||
tokio = { version = "1.33.0", features = ["rt", "macros"] }
|
tokio = { version = "1.33.0", features = ["rt", "macros"] }
|
||||||
|
tower-http = { version = "0.4.4", features = ["trace"] }
|
||||||
|
tracing = "0.1.40"
|
||||||
|
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
|
||||||
|
|
|
||||||
85
src/main.rs
85
src/main.rs
|
|
@ -1,4 +1,87 @@
|
||||||
|
use std::{net::SocketAddr, sync::Arc};
|
||||||
|
|
||||||
|
use axum::{
|
||||||
|
http::StatusCode,
|
||||||
|
response::{Html, IntoResponse},
|
||||||
|
routing::get,
|
||||||
|
Router,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tera::{Context, Tera};
|
||||||
|
use tower_http::trace::TraceLayer;
|
||||||
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
enum Error {
|
||||||
|
#[error("Could not render tera template")]
|
||||||
|
Template(#[from] tera::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoResponse for Error {
|
||||||
|
fn into_response(self) -> axum::response::Response {
|
||||||
|
tracing::error!("Failure in route: {self:?}");
|
||||||
|
|
||||||
|
match self {
|
||||||
|
Error::Template(_) => (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"an internal error occured",
|
||||||
|
)
|
||||||
|
.into_response(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const TEMPLATE_DIR: &str = match option_env!("TEMPLATE_DIR") {
|
||||||
|
Some(s) => s,
|
||||||
|
None => "templates",
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AppState {
|
||||||
|
templates: Tera,
|
||||||
|
}
|
||||||
|
|
||||||
|
type State = axum::extract::State<Arc<AppState>>;
|
||||||
|
|
||||||
|
async fn index(state: State) -> Result<Html<String>, Error> {
|
||||||
|
let rendered = state.templates.render("index.html", &Context::new())?;
|
||||||
|
|
||||||
|
Ok(rendered.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mk_port() -> u16 {
|
||||||
|
8080
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct Config {
|
||||||
|
#[serde(default = "mk_port")]
|
||||||
|
port: u16,
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
println!("Hello world");
|
tracing_subscriber::registry()
|
||||||
|
.with(tracing_subscriber::EnvFilter::from_default_env())
|
||||||
|
.with(tracing_subscriber::fmt::layer())
|
||||||
|
.init();
|
||||||
|
|
||||||
|
let config: Config = envious::Config::default()
|
||||||
|
.build_from_env()
|
||||||
|
.expect("could not get env vars");
|
||||||
|
|
||||||
|
let templates = Tera::new(&format!("{TEMPLATE_DIR}/**/*.html")).unwrap();
|
||||||
|
let state = Arc::new(AppState { templates });
|
||||||
|
|
||||||
|
let router = Router::new()
|
||||||
|
.route("/", get(index))
|
||||||
|
.with_state(state)
|
||||||
|
.layer(TraceLayer::new_for_http());
|
||||||
|
|
||||||
|
tracing::info!("Listening on port {}", config.port);
|
||||||
|
|
||||||
|
let listen = SocketAddr::new("0.0.0.0".parse().unwrap(), config.port);
|
||||||
|
axum::Server::bind(&listen)
|
||||||
|
.serve(router.into_make_service())
|
||||||
|
.await
|
||||||
|
.expect("web server failed");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
9
templates/index.html
Normal file
9
templates/index.html
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>Home Assistant Guest</title>
|
||||||
|
</head>
|
||||||
|
<body></body>
|
||||||
|
</html>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue