mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
Fixing parse socket address function (#1990)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
@ -623,6 +623,7 @@ async fn run_network_until_shutdown<C>(
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use std::net::IpAddr;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_help_node_command() {
|
fn parse_help_node_command() {
|
||||||
@ -651,4 +652,16 @@ mod tests {
|
|||||||
assert_eq!(cmd.network.discovery.port, Some(300));
|
assert_eq!(cmd.network.discovery.port, Some(300));
|
||||||
assert_eq!(cmd.network.port, Some(99));
|
assert_eq!(cmd.network.port, Some(99));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_metrics_port() {
|
||||||
|
let cmd = Command::try_parse_from(["reth", "--metrics", "9000"]).unwrap();
|
||||||
|
assert_eq!(cmd.metrics, Some(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 9000)));
|
||||||
|
|
||||||
|
let cmd = Command::try_parse_from(["reth", "--metrics", ":9000"]).unwrap();
|
||||||
|
assert_eq!(cmd.metrics, Some(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 9000)));
|
||||||
|
|
||||||
|
let cmd = Command::try_parse_from(["reth", "--metrics", "localhost:9000"]).unwrap();
|
||||||
|
assert_eq!(cmd.metrics, Some(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 9000)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
use reth_primitives::{BlockHashOrNumber, H256};
|
use reth_primitives::{BlockHashOrNumber, H256};
|
||||||
use std::{
|
use std::{
|
||||||
env::VarError,
|
env::VarError,
|
||||||
net::{SocketAddr, ToSocketAddrs},
|
net::{IpAddr, Ipv4Addr, SocketAddr, ToSocketAddrs},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
@ -38,6 +38,23 @@ pub fn hash_or_num_value_parser(value: &str) -> Result<BlockHashOrNumber, eyre::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Error thrown while parsing a socket address.
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
pub enum SocketAddressParsingError {
|
||||||
|
/// Failed to convert the string into a socket addr
|
||||||
|
#[error("Cannot parse socket address: {0}")]
|
||||||
|
Io(#[from] std::io::Error),
|
||||||
|
/// Input must not be empty
|
||||||
|
#[error("Cannot parse socket address from empty string")]
|
||||||
|
Empty,
|
||||||
|
/// Failed to parse the address
|
||||||
|
#[error("Could not parse socket address from {0}")]
|
||||||
|
Parse(String),
|
||||||
|
/// Failed to parse port
|
||||||
|
#[error("Could not parse port: {0}")]
|
||||||
|
Port(#[from] std::num::ParseIntError),
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse a [SocketAddr] from a `str`.
|
/// Parse a [SocketAddr] from a `str`.
|
||||||
///
|
///
|
||||||
/// The following formats are checked:
|
/// The following formats are checked:
|
||||||
@ -48,29 +65,32 @@ pub fn hash_or_num_value_parser(value: &str) -> Result<BlockHashOrNumber, eyre::
|
|||||||
/// - Otherwise it is assumed to be a hostname
|
/// - Otherwise it is assumed to be a hostname
|
||||||
///
|
///
|
||||||
/// An error is returned if the value is empty.
|
/// An error is returned if the value is empty.
|
||||||
pub fn parse_socket_address(value: &str) -> Result<SocketAddr, eyre::Error> {
|
pub fn parse_socket_address(value: &str) -> Result<SocketAddr, SocketAddressParsingError> {
|
||||||
if value.is_empty() {
|
if value.is_empty() {
|
||||||
eyre::bail!("Cannot parse socket address from an empty string");
|
return Err(SocketAddressParsingError::Empty)
|
||||||
}
|
}
|
||||||
|
|
||||||
if value.starts_with(':') || value.parse::<u16>().is_ok() {
|
if let Some(port) = value.strip_prefix(':').or_else(|| value.strip_prefix("localhost:")) {
|
||||||
("localhost", 9000).to_socket_addrs()
|
let port: u16 = port.parse()?;
|
||||||
} else if value.contains(':') {
|
return Ok(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), port))
|
||||||
value.to_socket_addrs()
|
}
|
||||||
} else {
|
if let Ok(port) = value.parse::<u16>() {
|
||||||
(value, 9000).to_socket_addrs()
|
return Ok(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), port))
|
||||||
}?
|
}
|
||||||
.next()
|
value
|
||||||
.ok_or_else(|| eyre::eyre!("Could not parse socket address from {}", value))
|
.to_socket_addrs()?
|
||||||
|
.next()
|
||||||
|
.ok_or_else(|| SocketAddressParsingError::Parse(value.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use rand::{thread_rng, Rng};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_socket_addresses() {
|
fn parse_socket_addresses() {
|
||||||
for value in ["localhost:9000", ":9000", "9000", "localhost"] {
|
for value in ["localhost:9000", ":9000", "9000"] {
|
||||||
let socket_addr = parse_socket_address(value)
|
let socket_addr = parse_socket_address(value)
|
||||||
.unwrap_or_else(|_| panic!("could not parse socket address: {value}"));
|
.unwrap_or_else(|_| panic!("could not parse socket address: {value}"));
|
||||||
|
|
||||||
@ -78,4 +98,17 @@ mod tests {
|
|||||||
assert_eq!(socket_addr.port(), 9000);
|
assert_eq!(socket_addr.port(), 9000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_socket_address_random() {
|
||||||
|
let port: u16 = thread_rng().gen();
|
||||||
|
|
||||||
|
for value in [format!("localhost:{port}"), format!(":{port}"), port.to_string()] {
|
||||||
|
let socket_addr = parse_socket_address(&value)
|
||||||
|
.unwrap_or_else(|_| panic!("could not parse socket address: {value}"));
|
||||||
|
|
||||||
|
assert!(socket_addr.ip().is_loopback());
|
||||||
|
assert_eq!(socket_addr.port(), port);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user