diff --git a/aquatic_ws/src/config.rs b/aquatic_ws/src/config.rs index 7f051a1..9a061c7 100644 --- a/aquatic_ws/src/config.rs +++ b/aquatic_ws/src/config.rs @@ -67,6 +67,10 @@ pub struct NetworkConfig { pub websocket_max_message_size: usize, pub websocket_max_frame_size: usize, + + /// Return a HTTP 200 Ok response when request is GET /health over plain + /// HTTP (no TLS!) + pub enable_http_health_check: bool, } impl Default for NetworkConfig { @@ -81,6 +85,8 @@ impl Default for NetworkConfig { websocket_max_message_size: 64 * 1024, websocket_max_frame_size: 16 * 1024, + + enable_http_health_check: false, } } } diff --git a/aquatic_ws/src/workers/socket.rs b/aquatic_ws/src/workers/socket.rs index e21a72d..f90cada 100644 --- a/aquatic_ws/src/workers/socket.rs +++ b/aquatic_ws/src/workers/socket.rs @@ -14,7 +14,7 @@ use aquatic_common::{CanonicalSocketAddr, PanicSentinel}; use aquatic_ws_protocol::*; use async_tungstenite::WebSocketStream; use futures::stream::{SplitSink, SplitStream}; -use futures::StreamExt; +use futures::{AsyncWriteExt, StreamExt}; use futures_lite::future::race; use futures_rustls::server::TlsStream; use futures_rustls::TlsAcceptor; @@ -157,7 +157,7 @@ pub async fn run_socket_worker( stream, peer_addr, ).await { - ::log::debug!("Connection::run() error: {:?}", err); + ::log::debug!("Connection::run() error: {:#}", err); } // Remove reference in separate statement to avoid @@ -269,9 +269,32 @@ async fn run_connection( out_message_consumer_id: ConsumerId, connection_id: ConnectionId, tls_config: Arc, - stream: TcpStream, + mut stream: TcpStream, peer_addr: CanonicalSocketAddr, ) -> anyhow::Result<()> { + if config.network.enable_http_health_check { + let mut peek_buf = [0u8; 11]; + + stream + .peek(&mut peek_buf) + .await + .map_err(|err| anyhow::anyhow!("error peeking: {:#}", err))?; + + if &peek_buf == b"GET /health" { + stream + .write_all(b"HTTP/1.1 200 Ok\r\nContent-Length: 2\r\n\r\nOk") + .await + .map_err(|err| anyhow::anyhow!("error sending health check response: {:#}", err))?; + stream.flush().await.map_err(|err| { + anyhow::anyhow!("error flushing health check response: {:#}", err) + })?; + + return Err(anyhow::anyhow!( + "client requested health check, skipping websocket negotiation" + )); + } + } + let tls_acceptor: TlsAcceptor = tls_config.into(); let stream = tls_acceptor.accept(stream).await?;