diff --git a/Cargo.lock b/Cargo.lock index 2cac7ab137..63204c12af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3384,9 +3384,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ae70283aba8d2a8b411c695c437fe25b8b5e44e23e780662002fc72fb47a82" +checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ "async-compression", "bitflags 2.3.3", diff --git a/Cargo.toml b/Cargo.toml index c751c131c5..fae1a344db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,7 +57,7 @@ tempfile = "3.2.0" tokio = { version = "1.17.0", features = ["rt-multi-thread"] } tokio-stream = "0.1.9" tokio-util = {version = "0.7.3", features = ["compat"] } -tower-http = { version = "0.4.0", features = ["compression-br", "compression-gzip", "cors", "set-header"] } +tower-http = { version = "0.4.0", features = ["compression-br", "compression-gzip", "cors", "set-header", "timeout"] } rdkafka = { version = "0.33.2" } axum-jrpc = { version = "0.5.1", features = ["serde_json", "anyhow_error"] } diff --git a/src/block_rarity.rs b/src/block_rarity.rs index eb454971f3..c323791317 100644 --- a/src/block_rarity.rs +++ b/src/block_rarity.rs @@ -100,7 +100,7 @@ impl<'de> Deserialize<'de> for BlockRarity { pub(crate) fn is_palindrome(n: &u64) -> bool { let s = n.to_string(); - if s.chars().nth(0) != s.chars().last() { + if s.chars().next() != s.chars().last() { return false; } let reversed = s.chars().rev().collect::(); diff --git a/src/subcommand/server.rs b/src/subcommand/server.rs index 863aca1e46..af32409d81 100644 --- a/src/subcommand/server.rs +++ b/src/subcommand/server.rs @@ -37,6 +37,7 @@ use { compression::CompressionLayer, cors::{Any, CorsLayer}, set_header::SetResponseHeaderLayer, + timeout::TimeoutLayer, }, }; @@ -132,6 +133,11 @@ pub(crate) struct Server { https: bool, #[clap(long, help = "Redirect HTTP traffic to HTTPS.")] redirect_http_to_https: bool, + #[clap( + long, + help = "Timeout requests after seconds. Default: 30 seconds." + )] + timeout: Option, } impl Server { @@ -214,6 +220,7 @@ impl Server { .allow_origin(Any), ) .layer(CompressionLayer::new()) + .layer(TimeoutLayer::new(Duration::from_secs(self.timeout.unwrap_or(30)))) .with_state(server_config); match (self.http_port(), self.https_port()) { @@ -1112,6 +1119,10 @@ mod tests { Self::new_with_args(&["--index-sats"], &[]) } + fn new_with_timeout() -> Self { + Self::new_with_args(&[], &["--timeout", "1"]) + } + fn new_with_args(ord_args: &[&str], server_args: &[&str]) -> Self { Self::new_server(test_bitcoincore_rpc::spawn(), None, ord_args, server_args) } @@ -1770,6 +1781,15 @@ mod tests { ); } + #[test] + fn output_with_timeout() { + TestServer::new_with_timeout().assert_response_regex( + "/block/0", + StatusCode::OK, + ".*Block 0.*

Block 0

.*", + ); + } + #[test] fn output_without_sat_index() { let txid = "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b";