Make server configurable through environment.
This commit is contained in:
parent
528d264b02
commit
8dfd84343d
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
/target
|
||||
localdata
|
||||
|
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -306,6 +306,12 @@ dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
@ -1381,9 +1387,11 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"actix-ws",
|
||||
"anyhow",
|
||||
"env_logger",
|
||||
"futures-util",
|
||||
"log",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
|
@ -8,7 +8,9 @@ edition = "2021"
|
||||
[dependencies]
|
||||
actix-web = "4.9.0"
|
||||
actix-ws = "0.3.0"
|
||||
anyhow = "1.0.86"
|
||||
env_logger = "0.11.5"
|
||||
futures-util = "0.3.30"
|
||||
log = "0.4.22"
|
||||
serde_json = "1.0.127"
|
||||
tokio = { version = "1.39.3", features = ["net", "macros", "tokio-macros", "rt-multi-thread"] }
|
||||
|
125
src/main.rs
125
src/main.rs
@ -1,21 +1,66 @@
|
||||
use actix_web::{
|
||||
self, get,
|
||||
self,
|
||||
error::InternalError,
|
||||
get,
|
||||
http::StatusCode,
|
||||
middleware::Logger,
|
||||
rt::{self, net::TcpStream},
|
||||
web, App, Error, HttpRequest, HttpResponse, HttpServer, Responder,
|
||||
web::{self, Data},
|
||||
App, Error, HttpRequest, HttpResponse, HttpServer, Responder,
|
||||
};
|
||||
use actix_ws::{AggregatedMessage, CloseCode, Closed};
|
||||
use anyhow::Context;
|
||||
use futures_util::StreamExt;
|
||||
use serde_json::json;
|
||||
use std::{env, fs, num::ParseIntError};
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
|
||||
pub struct ServerConfig {
|
||||
pub upstream_mud: String,
|
||||
pub banner_to_mud: String,
|
||||
pub listen_port: u16,
|
||||
pub bind_address: String,
|
||||
pub startup_script_file: String,
|
||||
}
|
||||
|
||||
#[get("/ws")]
|
||||
async fn ws(req: HttpRequest, body: web::Payload) -> impl Responder {
|
||||
async fn ws(
|
||||
config_data: Data<ServerConfig>,
|
||||
req: HttpRequest,
|
||||
body: web::Payload,
|
||||
) -> impl Responder {
|
||||
let (response, mut session, stream) = actix_ws::handle(&req, body)?;
|
||||
let mut stream = stream.aggregate_continuations().max_continuation_size(1024);
|
||||
|
||||
let mut tcp_stream: TcpStream = TcpStream::connect("localhost:4000").await?;
|
||||
let mut tcp_stream: TcpStream = TcpStream::connect(&config_data.upstream_mud).await?;
|
||||
let subst_banner = config_data
|
||||
.banner_to_mud
|
||||
.replace(
|
||||
"%i",
|
||||
&req.peer_addr()
|
||||
.map(|a| a.to_string())
|
||||
.unwrap_or_else(|| "unknown".to_owned()),
|
||||
)
|
||||
.replace("%n", "\r\n");
|
||||
tcp_stream.write_all(subst_banner.as_bytes()).await?;
|
||||
|
||||
let script = fetch_startup_script(&config_data.startup_script_file)
|
||||
.map_err(|e| InternalError::new(e, StatusCode::INTERNAL_SERVER_ERROR))?;
|
||||
|
||||
rt::spawn(async move {
|
||||
if session
|
||||
.text(
|
||||
json!({
|
||||
"RunLua": script
|
||||
})
|
||||
.to_string(),
|
||||
)
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
let _ = session.close(Some(CloseCode::Normal.into())).await;
|
||||
return;
|
||||
}
|
||||
let mut readbuf: [u8; 1024] = [0; 1024];
|
||||
loop {
|
||||
tokio::select! {
|
||||
@ -56,14 +101,68 @@ async fn ws(req: HttpRequest, body: web::Payload) -> impl Responder {
|
||||
Ok::<HttpResponse, Error>(response)
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
env_logger::init();
|
||||
HttpServer::new(|| {
|
||||
let logger = Logger::default();
|
||||
App::new().wrap(logger).service(ws)
|
||||
fn extract_server_config_from_environment() -> anyhow::Result<ServerConfig> {
|
||||
Ok(ServerConfig {
|
||||
upstream_mud: env::var("UPSTREAM_MUD").map_err(|_| {
|
||||
anyhow::Error::msg(
|
||||
"Expected UPSTREAM_MUD environment variable specifying where to connect.",
|
||||
)
|
||||
})?,
|
||||
banner_to_mud: env::var("BANNER_TO_MUD").map_err(|_| {
|
||||
anyhow::Error::msg(
|
||||
"Expected BANNER_TO_MUD environment variable specifying message to send to MUD.",
|
||||
)
|
||||
})?,
|
||||
listen_port: env::var("LISTEN_PORT")
|
||||
.map_err(|_| {
|
||||
anyhow::Error::msg(
|
||||
"Expected LISTEN_PORT environment variable specifying port to listen on.",
|
||||
)
|
||||
})
|
||||
.and_then(|v| {
|
||||
v.parse::<u16>().map_err(|_e: ParseIntError| {
|
||||
anyhow::Error::msg("LISTEN_PORT should be a decimal port number")
|
||||
})
|
||||
})?,
|
||||
bind_address: env::var("BIND_ADDRESS").unwrap_or_else(|_| "::".to_owned()),
|
||||
startup_script_file: env::var("STARTUP_SCRIPT_FILE")
|
||||
.map_err(|_| {
|
||||
anyhow::Error::msg(
|
||||
"Expected STARTUP_SCRIPT_FILE environment variable containing filename of script to send to client.",
|
||||
)
|
||||
})?
|
||||
,
|
||||
})
|
||||
.bind(("127.0.0.1", 8124))?
|
||||
.run()
|
||||
.await
|
||||
}
|
||||
|
||||
// We load this on each connection so it can change.
|
||||
fn fetch_startup_script(filename: &str) -> anyhow::Result<String> {
|
||||
Ok(fs::read_to_string(filename)?)
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
env_logger::init();
|
||||
|
||||
let config = extract_server_config_from_environment()?;
|
||||
|
||||
let data = Data::new(config);
|
||||
let config = data.get_ref();
|
||||
|
||||
// Do this early so we fail fast if config is wrong.
|
||||
fetch_startup_script(&config.startup_script_file)
|
||||
.context("While checking STARTUP_SCRIPT_FILE can be read")?;
|
||||
|
||||
let server_data = data.clone();
|
||||
HttpServer::new(move || {
|
||||
let logger = Logger::default();
|
||||
App::new()
|
||||
.wrap(logger)
|
||||
.app_data(server_data.clone())
|
||||
.service(ws)
|
||||
})
|
||||
.bind((config.bind_address.clone(), config.listen_port))?
|
||||
.run()
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user