mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-04-08 03:01:12 -04:00
fix(ethstats): WSS Handling (#21595)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de> Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -13,15 +13,23 @@ pub(crate) struct EthstatsCredentials {
|
||||
pub secret: String,
|
||||
/// Host address of the `EthStats` server
|
||||
pub host: String,
|
||||
/// Whether to use secure `WebSocket` (`WSS`) connection
|
||||
pub use_tls: bool,
|
||||
}
|
||||
|
||||
impl FromStr for EthstatsCredentials {
|
||||
type Err = EthStatsError;
|
||||
|
||||
/// Parse credentials from a string in the format "`node_id:secret@host`"
|
||||
/// Parse credentials from a string in the format "`node_id:secret@host`" or
|
||||
/// "`node_id:secret@wss://host`"
|
||||
///
|
||||
/// Supports the following formats:
|
||||
/// - `node_id:secret@host` - Uses plain `WebSocket` (`ws://`)
|
||||
/// - `node_id:secret@ws://host` - Explicitly use plain `WebSocket`
|
||||
/// - `node_id:secret@wss://host` - Use secure `WebSocket` (`WSS`)
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `s` - String containing credentials in the format "`node_id:secret@host`"
|
||||
/// * `s` - String containing credentials
|
||||
///
|
||||
/// # Returns
|
||||
/// * `Ok(EthstatsCredentials)` - Successfully parsed credentials
|
||||
@@ -32,7 +40,7 @@ impl FromStr for EthstatsCredentials {
|
||||
return Err(EthStatsError::InvalidUrl("Missing '@' separator".to_string()));
|
||||
}
|
||||
let creds = parts[0];
|
||||
let host = parts[1].to_string();
|
||||
let mut host = parts[1].to_string();
|
||||
let creds_parts: Vec<&str> = creds.split(':').collect();
|
||||
if creds_parts.len() != 2 {
|
||||
return Err(EthStatsError::InvalidUrl(
|
||||
@@ -42,6 +50,16 @@ impl FromStr for EthstatsCredentials {
|
||||
let node_id = creds_parts[0].to_string();
|
||||
let secret = creds_parts[1].to_string();
|
||||
|
||||
Ok(Self { node_id, secret, host })
|
||||
// Detect and strip protocol prefix if present
|
||||
let mut use_tls = false;
|
||||
if let Some(stripped) = host.strip_prefix("wss://") {
|
||||
use_tls = true;
|
||||
host = stripped.to_string();
|
||||
} else if let Some(stripped) = host.strip_prefix("ws://") {
|
||||
use_tls = false;
|
||||
host = stripped.to_string();
|
||||
}
|
||||
|
||||
Ok(Self { node_id, secret, host, use_tls })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,13 +102,15 @@ where
|
||||
/// Establish `WebSocket` connection to the `EthStats` server
|
||||
///
|
||||
/// Attempts to connect to the server using the credentials and handles
|
||||
/// connection timeouts and errors.
|
||||
/// connection timeouts and errors. Uses either `ws://` or `wss://` based
|
||||
/// on the credentials configuration.
|
||||
async fn connect(&self) -> Result<(), EthStatsError> {
|
||||
debug!(
|
||||
target: "ethstats",
|
||||
"Attempting to connect to EthStats server at {}", self.credentials.host
|
||||
);
|
||||
let full_url = format!("ws://{}/api", self.credentials.host);
|
||||
let protocol = if self.credentials.use_tls { "wss" } else { "ws" };
|
||||
let full_url = format!("{}://{}/api", protocol, self.credentials.host);
|
||||
let url = Url::parse(&full_url).map_err(EthStatsError::Url)?;
|
||||
|
||||
match timeout(CONNECT_TIMEOUT, connect_async(url.as_str())).await {
|
||||
|
||||
Reference in New Issue
Block a user