diff --git a/Cargo.toml b/Cargo.toml index db273d1..d3015a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ regex = "1" trust-dns-client = "0.23" tokio = { version = "1", features = ["fs", "net", "time", "io-util"], optional = true } +encoding_rs = "0.8.34" [dev-dependencies] tokio = { version = "1", features = ["macros", "rt"] } diff --git a/src/who_is.rs b/src/who_is.rs index 3769e33..f5a732f 100644 --- a/src/who_is.rs +++ b/src/who_is.rs @@ -8,6 +8,7 @@ use std::{ time::Duration, }; +use encoding_rs::{UTF_8, WINDOWS_1252}; use once_cell::sync::Lazy; use regex::Regex; use serde_json::{Map, Value}; @@ -243,9 +244,19 @@ impl WhoIs { client.flush()?; - let mut query_result = String::new(); + let mut buf = vec![]; + client.read_to_end(&mut buf)?; - client.read_to_string(&mut query_result)?; + let decoders = [UTF_8, WINDOWS_1252]; + + for decoder in &decoders { + let (cow, _encoding_used, had_errors) = decoder.decode(&buf); + if !had_errors { + return Ok((addr, cow.into_owned())); + } + } + + let query_result = String::from_utf8_lossy(&buf).into_owned(); Ok((addr, query_result)) } diff --git a/tests/test.rs b/tests/test.rs index 252b07f..74d4379 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -21,6 +21,17 @@ fn test_srv() { println!("{}", result); } +#[test] +fn test_non_utf8_responses() { + let who = WhoIs::from_host("whois.arin.net").unwrap(); + + let result = who.lookup(WhoIsLookupOptions::from_string("178.202.0.0").unwrap()).unwrap(); + println!("{}", result); + + let result = who.lookup(WhoIsLookupOptions::from_string("185.73.124.0").unwrap()).unwrap(); + println!("{}", result); +} + #[cfg(feature = "tokio")] #[tokio::test] async fn test_async() {