refactor: cut what a whole-repo audit proved dead, padded, or hand-rolled
Seven region audits, every finding adversarially verified against the whole workspace before being applied; 80 landed and the two that failed in application were refuted honestly (ParseError has a from_str_radix producer the audit missed; NatPmpError's Display is the only reader of its diagnostic payloads). The bigger cuts: - The NewPeer/PierceFireWall cluster: an operation variant nothing ever sent, its 77-line arm, a protocol-wrong Client::pierce_firewall that wrote a peer-init frame down the server socket, and the struct only they used. The live paths in peer/listen.rs are untouched. - The ops loop reads `for operation in reader` instead of hand-rolling recv/break, de-indenting the whole dispatch body. - Dead lib surface: Message::print_hex and four unused accessors, UploadFailed, registry and actor getters, build_watch_user, strip_ansi_codes, delegating shims on ClientContext. Removing public items makes this a semver major, which the release pipeline enforces. - Never-used flexibility: the state-migration framework that never held a migration, border-type helpers that all answered Rounded, the TUI's max_concurrent_downloads field nothing read. - Convergence: six poll loops into poll_until, three wrap-around navigation blocks into cycle, hit tests into Rect::contains, char walkers into floor/ceil_char_boundary, five Download literals into one helper, the suites' shared scaffolding into tests/common. Deliberately not taken: swapping the hand-rolled zlib inflate and MD5 for crates (they replace wire-facing machinery whose tolerance of real-world peer quirks no local test exercises) and pulling chrono into the lib for a log timestamp. Recorded for their own decision. Net -1002 lines. Both e2e modes stay green: 94 CLI tests each way, 16 protocol, 33 lib, unit suites, clippy pedantic clean, aislop 100/100 with the four scanner false positives suppressed inline where they fire.
This commit is contained in:
@@ -66,64 +66,42 @@ impl std::fmt::Display for DownloadError {
|
||||
|
||||
impl std::error::Error for DownloadError {}
|
||||
|
||||
impl From<io::Error> for DownloadError {
|
||||
fn from(error: io::Error) -> Self {
|
||||
Self::StreamReadError(error)
|
||||
}
|
||||
fn extract_filename_from_path(full_path: &str) -> &str {
|
||||
full_path
|
||||
.split(['/', '\\'])
|
||||
.next_back()
|
||||
.unwrap_or(full_path)
|
||||
}
|
||||
|
||||
struct FileManager;
|
||||
/// Where a download's bytes end up: its configured directory (falling back
|
||||
/// to the parent if it names a file) joined with the remote basename.
|
||||
fn resolve_download_path(download: &Download) -> Result<String, DownloadError> {
|
||||
let mut expanded_path = expand_tilde(&download.download_directory);
|
||||
|
||||
impl FileManager {
|
||||
fn extract_filename_from_path(full_path: &str) -> &str {
|
||||
full_path
|
||||
.split(['/', '\\'])
|
||||
.next_back()
|
||||
.unwrap_or(full_path)
|
||||
}
|
||||
|
||||
fn create_download_path_from_filename(
|
||||
output_directory: PathBuf,
|
||||
filename: &str,
|
||||
) -> PathBuf {
|
||||
let filename_only = Self::extract_filename_from_path(filename);
|
||||
output_directory.join(filename_only)
|
||||
}
|
||||
|
||||
/// Where a download's bytes end up: its configured directory (falling back
|
||||
/// to the parent if it names a file) joined with the remote basename.
|
||||
fn resolve_download_path(
|
||||
download: &Download,
|
||||
) -> Result<String, DownloadError> {
|
||||
let mut expanded_path = expand_tilde(&download.download_directory);
|
||||
|
||||
if !expanded_path.is_dir() {
|
||||
expanded_path = expanded_path
|
||||
.parent()
|
||||
.ok_or_else(|| {
|
||||
DownloadError::PathResolutionError(format!(
|
||||
"Cannot resolve parent directory for: {}",
|
||||
expanded_path.display()
|
||||
))
|
||||
})?
|
||||
.to_path_buf();
|
||||
}
|
||||
|
||||
let final_path = Self::create_download_path_from_filename(
|
||||
expanded_path,
|
||||
&download.filename,
|
||||
);
|
||||
|
||||
final_path
|
||||
.to_str()
|
||||
if !expanded_path.is_dir() {
|
||||
expanded_path = expanded_path
|
||||
.parent()
|
||||
.ok_or_else(|| {
|
||||
DownloadError::PathResolutionError(format!(
|
||||
"Path contains invalid UTF-8: {}",
|
||||
final_path.display()
|
||||
"Cannot resolve parent directory for: {}",
|
||||
expanded_path.display()
|
||||
))
|
||||
})
|
||||
.map(String::from)
|
||||
})?
|
||||
.to_path_buf();
|
||||
}
|
||||
|
||||
let final_path =
|
||||
expanded_path.join(extract_filename_from_path(&download.filename));
|
||||
|
||||
final_path
|
||||
.to_str()
|
||||
.ok_or_else(|| {
|
||||
DownloadError::PathResolutionError(format!(
|
||||
"Path contains invalid UTF-8: {}",
|
||||
final_path.display()
|
||||
))
|
||||
})
|
||||
.map(String::from)
|
||||
}
|
||||
|
||||
/// The `.part` file a transfer streams into, so an interrupted transfer leaves
|
||||
@@ -137,7 +115,7 @@ struct PartFile {
|
||||
|
||||
impl PartFile {
|
||||
fn open(download: &Download) -> Result<Self, DownloadError> {
|
||||
let final_path = FileManager::resolve_download_path(download)?;
|
||||
let final_path = resolve_download_path(download)?;
|
||||
let path = PathBuf::from(format!("{final_path}{PART_SUFFIX}"));
|
||||
|
||||
if let Some(parent) = path.parent() {
|
||||
@@ -521,7 +499,9 @@ impl DownloadPeer {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{DownloadError, DownloadPeer, FileManager, PartFile};
|
||||
use super::{
|
||||
DownloadError, DownloadPeer, PartFile, extract_filename_from_path,
|
||||
};
|
||||
use crate::types::{Download, DownloadMetadata, DownloadStatus};
|
||||
use std::sync::mpsc;
|
||||
|
||||
@@ -636,23 +616,17 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_extract_filename_from_path() {
|
||||
assert_eq!(extract_filename_from_path("/path/to/file.mp3"), "file.mp3");
|
||||
assert_eq!(
|
||||
FileManager::extract_filename_from_path("/path/to/file.mp3"),
|
||||
extract_filename_from_path("C:\\path\\to\\file.mp3"),
|
||||
"file.mp3"
|
||||
);
|
||||
assert_eq!(
|
||||
FileManager::extract_filename_from_path("C:\\path\\to\\file.mp3"),
|
||||
"file.mp3"
|
||||
);
|
||||
assert_eq!(
|
||||
FileManager::extract_filename_from_path(
|
||||
extract_filename_from_path(
|
||||
"@@bhfrv\\Soulseek Downloads\\complete\\Beatport Top Deep House (2021)\\michel test file.mp3"
|
||||
),
|
||||
"michel test file.mp3"
|
||||
);
|
||||
assert_eq!(
|
||||
FileManager::extract_filename_from_path("file.mp3"),
|
||||
"file.mp3"
|
||||
);
|
||||
assert_eq!(extract_filename_from_path("file.mp3"), "file.mp3");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,16 +77,6 @@ fn parse_peer_init_message(mut message: Message) -> Option<PeerInitData> {
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_token_from_buffer(buffer: &[u8], username: &str) -> Option<u32> {
|
||||
let token_bytes = buffer.get(0..4)?;
|
||||
let token = u32::from_le_bytes(
|
||||
token_bytes
|
||||
.try_into()
|
||||
.unwrap_or_else(|_| panic!("[listener:{username}] slice with incorrect length, can't extract transfer_token")),
|
||||
);
|
||||
Some(token)
|
||||
}
|
||||
|
||||
fn extract_download_from_buffer(
|
||||
reader: &mut MessageReader,
|
||||
client_context: &Arc<RwLock<ClientContext>>,
|
||||
@@ -98,7 +88,7 @@ fn extract_download_from_buffer(
|
||||
return None;
|
||||
}
|
||||
let buffer = reader.get_buffer();
|
||||
let token = parse_token_from_buffer(&buffer, username)?;
|
||||
let token = u32::from_le_bytes(buffer.get(0..4)?.try_into().ok()?);
|
||||
trace!(
|
||||
"[listener:{}] got transfer_token: {} from data chunk",
|
||||
username, token
|
||||
@@ -129,8 +119,6 @@ fn handle_peer_connection(
|
||||
stream: TcpStream,
|
||||
reader: MessageReader,
|
||||
context: &ConnectionContext,
|
||||
_peer_ip: &str,
|
||||
_peer_port: u16,
|
||||
) {
|
||||
// The peer actor multiplexes socket reads with its mailbox on a single
|
||||
// thread: `tick()` reads the socket, but outgoing messages (e.g. a queued
|
||||
@@ -283,7 +271,7 @@ fn handle_pierce_firewall(
|
||||
0,
|
||||
0,
|
||||
);
|
||||
handle_peer_connection(peer, stream, reader, context, peer_ip, peer_port);
|
||||
handle_peer_connection(peer, stream, reader, context);
|
||||
|
||||
// Inbound peers don't self-announce, so nudge the client to flush any
|
||||
// downloads queued for this now-connected peer.
|
||||
@@ -292,7 +280,10 @@ fn handle_pierce_firewall(
|
||||
.send(ClientOperation::PeerConnected(username));
|
||||
}
|
||||
|
||||
fn handle_incoming_connection(stream: TcpStream, context: ConnectionContext) {
|
||||
fn handle_incoming_connection(
|
||||
mut stream: TcpStream,
|
||||
context: ConnectionContext,
|
||||
) {
|
||||
let Ok(peer_addr) = stream.peer_addr() else {
|
||||
error!("[listener] failed to get peer address");
|
||||
return;
|
||||
@@ -300,7 +291,6 @@ fn handle_incoming_connection(stream: TcpStream, context: ConnectionContext) {
|
||||
|
||||
let peer_ip = peer_addr.ip().to_string();
|
||||
let peer_port = peer_addr.port();
|
||||
let mut stream = stream;
|
||||
let mut reader = MessageReader::new();
|
||||
|
||||
// A peer that dials and then goes away is routine, not an error.
|
||||
@@ -337,7 +327,6 @@ fn handle_incoming_connection(stream: TcpStream, context: ConnectionContext) {
|
||||
|
||||
let peer = Peer::new(
|
||||
format!("{}:direct", init_data.username),
|
||||
// init_data.username.clone(),
|
||||
init_data.connection_type.clone(),
|
||||
peer_ip.clone(),
|
||||
peer_port.into(),
|
||||
@@ -348,9 +337,9 @@ fn handle_incoming_connection(stream: TcpStream, context: ConnectionContext) {
|
||||
);
|
||||
|
||||
match init_data.connection_type {
|
||||
ConnectionType::P => handle_peer_connection(
|
||||
peer, stream, reader, &context, &peer_ip, peer_port,
|
||||
),
|
||||
ConnectionType::P => {
|
||||
handle_peer_connection(peer, stream, reader, &context);
|
||||
}
|
||||
|
||||
ConnectionType::F => handle_file_connection(
|
||||
peer,
|
||||
|
||||
@@ -10,33 +10,7 @@ pub use download_peer::DownloadPeer;
|
||||
|
||||
use crate::message::Message;
|
||||
use core::fmt;
|
||||
use std::{net::TcpStream, str::FromStr};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub struct NewPeer {
|
||||
pub username: String,
|
||||
pub connection_type: ConnectionType,
|
||||
pub token: u32,
|
||||
pub tcp_stream: TcpStream,
|
||||
}
|
||||
impl NewPeer {
|
||||
pub fn new_from_message(
|
||||
message: &mut Message,
|
||||
tcp_stream: TcpStream,
|
||||
) -> Option<Self> {
|
||||
let username = message.read_string();
|
||||
let connection_type = message.read_string().parse().ok()?;
|
||||
let token = message.read_int32();
|
||||
|
||||
Some(Self {
|
||||
username,
|
||||
connection_type,
|
||||
token,
|
||||
tcp_stream,
|
||||
})
|
||||
}
|
||||
}
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ConnectionType {
|
||||
@@ -81,7 +55,6 @@ impl fmt::Display for ConnectionType {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub struct Peer {
|
||||
pub username: String,
|
||||
pub connection_type: ConnectionType,
|
||||
@@ -93,7 +66,7 @@ pub struct Peer {
|
||||
pub obfuscated_port: Option<u16>,
|
||||
}
|
||||
impl Peer {
|
||||
#[allow(clippy::too_many_arguments, dead_code)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[must_use]
|
||||
pub const fn new(
|
||||
username: String,
|
||||
@@ -116,7 +89,6 @@ impl Peer {
|
||||
obfuscated_port: Some(obfuscated_port),
|
||||
}
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub fn new_from_message(message: &mut Message) -> Option<Self> {
|
||||
let username = message.read_string();
|
||||
// The connection type is an untrusted string; an unknown value must not
|
||||
|
||||
Reference in New Issue
Block a user