From 1cd56d953ef084a19c6013eeffe34030d6230ef7 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Fri, 10 May 2024 22:01:47 +0100 Subject: [PATCH] feat(server): allow specifying id address and port to bind to Closes kemitix/git-next#44 --- server-default.toml | 6 +++++- src/server/actors/server.rs | 8 ++++++-- src/server/actors/webhook/mod.rs | 8 ++++++-- src/server/actors/webhook/server.rs | 11 ++++++++--- src/server/config/mod.rs | 24 ++++++++++++++++++++++++ src/server/config/tests.rs | 8 ++++++++ 6 files changed, 57 insertions(+), 8 deletions(-) diff --git a/server-default.toml b/server-default.toml index a08cdb0f..885881eb 100644 --- a/server-default.toml +++ b/server-default.toml @@ -1,5 +1,9 @@ +[http] +addr = "0.0.0.0" +port = 8080 + [webhook] -url = "https://localhost:8080/webhook" +url = "https://localhost:8080" [storage] path = "./data" diff --git a/src/server/actors/server.rs b/src/server/actors/server.rs index bf829624..becabfcd 100644 --- a/src/server/actors/server.rs +++ b/src/server/actors/server.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use actix::prelude::*; use kxio::{fs::FileSystem, network::Network}; -use tracing::{error, info}; +use tracing::{error, info, warn}; use crate::server::{ actors::{ @@ -62,6 +62,10 @@ impl Handler for Server { #[allow(clippy::cognitive_complexity)] // TODO: (#75) reduce complexity fn handle(&mut self, msg: ServerConfig, _ctx: &mut Self::Context) -> Self::Result { + let Ok(socket_addr) = msg.http() else { + warn!("Unable to parse http.addr"); + return; + }; if let Some(webhook) = self.webhook.take() { webhook.do_send(ShutdownWebhook); } @@ -103,7 +107,7 @@ impl Handler for Server { .for_each(|msg| webhook_router.do_send(msg)); } - let webhook = WebhookActor::new(webhook_router.recipient()).start(); + let webhook = WebhookActor::new(socket_addr, webhook_router.recipient()).start(); self.webhook.replace(webhook); } } diff --git a/src/server/actors/webhook/mod.rs b/src/server/actors/webhook/mod.rs index 37f256d5..4a76cbbf 100644 --- a/src/server/actors/webhook/mod.rs +++ b/src/server/actors/webhook/mod.rs @@ -4,6 +4,8 @@ mod message; mod router; mod server; +use std::net::SocketAddr; + use actix::prelude::*; pub use message::WebhookMessage; @@ -13,14 +15,16 @@ use tracing::Instrument; #[derive(Debug)] pub struct WebhookActor { + socket_addr: SocketAddr, span: tracing::Span, spawn_handle: Option, message_receiver: Recipient, } impl WebhookActor { - pub fn new(message_receiver: Recipient) -> Self { + pub fn new(socket_addr: SocketAddr, message_receiver: Recipient) -> Self { let span = tracing::info_span!("WebhookActor"); Self { + socket_addr, span, message_receiver, spawn_handle: None, @@ -32,7 +36,7 @@ impl Actor for WebhookActor { fn started(&mut self, ctx: &mut Self::Context) { let _gaurd = self.span.enter(); let address: Recipient = self.message_receiver.clone(); - let server = server::start(address); + let server = server::start(self.socket_addr, address); let spawn_handle = ctx.spawn(server.in_current_span().into_actor(self)); self.spawn_handle.replace(spawn_handle); } diff --git a/src/server/actors/webhook/server.rs b/src/server/actors/webhook/server.rs index 19733933..90cc07c1 100644 --- a/src/server/actors/webhook/server.rs +++ b/src/server/actors/webhook/server.rs @@ -1,10 +1,15 @@ +use std::net::SocketAddr; + use actix::prelude::*; use tracing::{debug, info}; use crate::server::actors::webhook::message::WebhookMessage; -pub async fn start(address: actix::prelude::Recipient) { +pub async fn start( + socket_addr: SocketAddr, + address: actix::prelude::Recipient, +) { // start webhook server use warp::Filter; // Define the Warp route to handle incoming HTTP requests @@ -49,6 +54,6 @@ pub async fn start(address: actix::prelude::Recipient = core::result::Result; #[derive(Debug, PartialEq, Eq, Deserialize, Message)] #[rtype(result = "()")] pub struct ServerConfig { + http: Http, webhook: Webhook, storage: ServerStorage, forge: HashMap, @@ -56,9 +60,29 @@ impl ServerConfig { pub const fn webhook(&self) -> &Webhook { &self.webhook } + + pub fn http(&self) -> Result { + self.http.socket_addr() + } +} + +/// Defines the port the server will listen to for incoming webhooks messages +#[derive(Clone, Debug, PartialEq, Eq, Deserialize)] +pub struct Http { + addr: String, + port: u16, +} +impl Http { + fn socket_addr(&self) -> Result { + Ok(SocketAddr::from_str(&format!( + "{}:{}", + self.addr, self.port + ))?) + } } /// Defines the Webhook Forges should send updates to +/// Must be an address that is accessible from the remote forge #[derive(Clone, Debug, PartialEq, Eq, Deserialize)] pub struct Webhook { url: String, diff --git a/src/server/config/tests.rs b/src/server/config/tests.rs index c449a613..36b0b7f8 100644 --- a/src/server/config/tests.rs +++ b/src/server/config/tests.rs @@ -16,6 +16,10 @@ fn load_should_parse_server_config() -> Result<()> { fs.file_write( &fs.base().join("git-next-server.toml"), r#" + [http] + addr = "0.0.0.0" + port = 8080 + [webhook] url = "http://localhost:9909/webhook" @@ -43,6 +47,10 @@ fn load_should_parse_server_config() -> Result<()> { ?; let_assert!(Ok(config) = ServerConfig::load(&fs)); let expected = ServerConfig { + http: Http { + addr: "0.0.0.0".to_string(), + port: 8080, + }, webhook: Webhook { url: "http://localhost:9909/webhook".to_string(), },