chore: formatting
This commit is contained in:
+336
-290
@@ -1,27 +1,27 @@
|
||||
use crate::actor::server_actor::{PeerAddress, ServerActor, ServerMessage};
|
||||
use crate::actor::ActorHandle;
|
||||
use crate::actor::server_actor::{PeerAddress, ServerActor, ServerMessage};
|
||||
use crate::types::DownloadStatus;
|
||||
use crate::utils::logger;
|
||||
use crate::{
|
||||
actor::{peer_registry::PeerRegistry, ActorSystem},
|
||||
Transfer,
|
||||
actor::{ActorSystem, peer_registry::PeerRegistry},
|
||||
error::{Result, SoulseekRs},
|
||||
peer::{listen::Listen, ConnectionType, DownloadPeer, NewPeer, Peer},
|
||||
peer::{ConnectionType, DownloadPeer, NewPeer, Peer, listen::Listen},
|
||||
types::{Download, Search, SearchResult},
|
||||
utils::{md5, thread_pool::ThreadPool},
|
||||
Transfer,
|
||||
};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
net::TcpStream,
|
||||
sync::{
|
||||
RwLock,
|
||||
atomic::{AtomicBool, Ordering},
|
||||
mpsc::{Receiver, Sender},
|
||||
RwLock,
|
||||
},
|
||||
thread::{self, sleep},
|
||||
};
|
||||
use std::{
|
||||
sync::{mpsc, Arc},
|
||||
sync::{Arc, mpsc},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
@@ -286,9 +286,10 @@ impl Client {
|
||||
pub fn remove_peer(&self, username: &str) {
|
||||
let context = self.context.read().unwrap();
|
||||
if let Some(ref registry) = context.peer_registry
|
||||
&& let Some(handle) = registry.remove_peer(username) {
|
||||
let _ = handle.stop();
|
||||
}
|
||||
&& let Some(handle) = registry.remove_peer(username)
|
||||
{
|
||||
let _ = handle.stop();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn search(
|
||||
@@ -334,10 +335,11 @@ impl Client {
|
||||
|
||||
// Check if cancelled
|
||||
if let Some(ref flag) = cancel_flag
|
||||
&& flag.load(Ordering::Relaxed) {
|
||||
info!("Search cancelled by user");
|
||||
break;
|
||||
}
|
||||
&& flag.load(Ordering::Relaxed)
|
||||
{
|
||||
info!("Search cancelled by user");
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if timeout reached
|
||||
if start.elapsed() >= timeout {
|
||||
@@ -470,225 +472,12 @@ impl Client {
|
||||
client_context: Arc<RwLock<ClientContext>>,
|
||||
own_username: String,
|
||||
) {
|
||||
thread::spawn(move || loop {
|
||||
match reader.recv() {
|
||||
Ok(operation) => {
|
||||
match operation {
|
||||
ClientOperation::ConnectToPeer(peer) => {
|
||||
let client_context_clone = client_context.clone();
|
||||
let own_username_clone = own_username.clone();
|
||||
|
||||
thread::spawn(move || {
|
||||
Self::connect_to_peer(
|
||||
peer,
|
||||
client_context_clone,
|
||||
own_username_clone,
|
||||
None,
|
||||
);
|
||||
});
|
||||
}
|
||||
ClientOperation::SearchResult(search_result) => {
|
||||
trace!("[client] SearchResult {:?}", search_result);
|
||||
let mut context = client_context.write().unwrap();
|
||||
let result_token = search_result.token;
|
||||
|
||||
// Find the search with matching token
|
||||
for search in context.searches.values_mut() {
|
||||
if search.token == result_token {
|
||||
search.results.push(search_result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ClientOperation::PeerDisconnected(username, error) => {
|
||||
let context = client_context.read().unwrap();
|
||||
if let Some(ref registry) = context.peer_registry
|
||||
&& let Some(handle) =
|
||||
registry.remove_peer(&username)
|
||||
{
|
||||
let _ = handle.stop();
|
||||
}
|
||||
if let Some(error) = error {
|
||||
warn!(
|
||||
"[client] Peer {} disconnected with error: {:?}",
|
||||
username, error
|
||||
);
|
||||
Self::process_failed_uploads(
|
||||
client_context.clone(),
|
||||
&username,
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
ClientOperation::PierceFireWall(peer) => {
|
||||
Self::pierce_firewall(
|
||||
peer,
|
||||
client_context.clone(),
|
||||
own_username.clone(),
|
||||
);
|
||||
}
|
||||
ClientOperation::DownloadFromPeer(
|
||||
token,
|
||||
peer,
|
||||
allowed,
|
||||
) => {
|
||||
let maybe_download = {
|
||||
let client_context =
|
||||
client_context.read().unwrap();
|
||||
client_context
|
||||
.get_download_by_token(token)
|
||||
.cloned()
|
||||
};
|
||||
let own_username = own_username.clone();
|
||||
let client_context_clone = client_context.clone();
|
||||
|
||||
trace!(
|
||||
"[client] DownloadFromPeer token: {} peer: {:?}",
|
||||
token,
|
||||
peer
|
||||
);
|
||||
match maybe_download {
|
||||
Some(download) => {
|
||||
thread::spawn(move || {
|
||||
let download_peer = DownloadPeer::new(
|
||||
download.username.clone(),
|
||||
peer.host.clone(),
|
||||
peer.port,
|
||||
token,
|
||||
allowed,
|
||||
own_username,
|
||||
);
|
||||
let filename: Option<&str> = download
|
||||
.filename
|
||||
.split('\\')
|
||||
.next_back();
|
||||
match filename {
|
||||
Some(filename) => {
|
||||
match download_peer.download_file(
|
||||
client_context_clone.clone(),
|
||||
Some(download.clone()),
|
||||
None
|
||||
) {
|
||||
Ok((download, filename)) => {
|
||||
let _ = download.sender.send(DownloadStatus::Completed);
|
||||
client_context_clone.write().unwrap().update_download_with_status(download.token, DownloadStatus::Completed);
|
||||
info!("Successfully downloaded {} bytes to {}", download.size, filename);
|
||||
}
|
||||
Err(e) => {
|
||||
let _ = download.sender.send(DownloadStatus::Failed);
|
||||
client_context_clone.write().unwrap().update_download_with_status(download.token, DownloadStatus::Failed);
|
||||
error!(
|
||||
"Failed to download file '{}' from {}:{} (token: {}) - Error: {}",
|
||||
filename, peer.host, peer.port, download.token, e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
None => error!("Cant find filename to save download: {:?}", download.filename),
|
||||
}
|
||||
});
|
||||
}
|
||||
None => {
|
||||
error!(
|
||||
"Can't find download with token {:?}",
|
||||
token
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
ClientOperation::NewPeer(new_peer) => {
|
||||
let peer_exists = client_context
|
||||
.read()
|
||||
.unwrap()
|
||||
.peer_registry
|
||||
.as_ref()
|
||||
.map(|r| r.contains(&new_peer.username))
|
||||
.unwrap_or(false);
|
||||
|
||||
if peer_exists {
|
||||
debug!(
|
||||
"Already connected to {}",
|
||||
new_peer.username
|
||||
);
|
||||
} else if let Some(server_sender) =
|
||||
&client_context.read().unwrap().server_sender
|
||||
{
|
||||
server_sender
|
||||
.send(ServerMessage::GetPeerAddress(
|
||||
new_peer.username.clone(),
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let addr = new_peer.tcp_stream.peer_addr().unwrap();
|
||||
let host = addr.ip().to_string();
|
||||
let port: u32 = addr.port().into();
|
||||
|
||||
let peer = Peer {
|
||||
username: new_peer.username.clone(),
|
||||
connection_type: new_peer.connection_type,
|
||||
host,
|
||||
port,
|
||||
token: Some(new_peer.token),
|
||||
privileged: None,
|
||||
obfuscated_port: None,
|
||||
unknown: None,
|
||||
};
|
||||
|
||||
Self::connect_to_peer(
|
||||
peer,
|
||||
client_context.clone(),
|
||||
own_username.clone(),
|
||||
Some(new_peer.tcp_stream),
|
||||
);
|
||||
}
|
||||
ClientOperation::GetPeerAddressResponse {
|
||||
username,
|
||||
host,
|
||||
port,
|
||||
obfuscation_type,
|
||||
obfuscated_port,
|
||||
} => {
|
||||
debug!(
|
||||
"Received peer address for {}: {}:{} (obf_type: {}, obf_port: {})",
|
||||
username, host, port, obfuscation_type, obfuscated_port
|
||||
);
|
||||
|
||||
let peer_exists = client_context
|
||||
.read()
|
||||
.unwrap()
|
||||
.peer_registry
|
||||
.as_ref()
|
||||
.map(|r| r.contains(&username))
|
||||
.unwrap_or(false);
|
||||
|
||||
if peer_exists {
|
||||
// don't know if i should update? and or reconnect the peer
|
||||
// debug!(
|
||||
// "existing peer: {:?}, new peer details:
|
||||
// username: {},
|
||||
// host: {},
|
||||
// port: {}
|
||||
// obfuscation_type: {}
|
||||
// obfuscated_port: {}",
|
||||
// peer,
|
||||
// username,
|
||||
// host,
|
||||
// port,
|
||||
// obfuscation_type,
|
||||
// obfuscated_port,
|
||||
// );
|
||||
} else {
|
||||
let peer = Peer::new(
|
||||
username,
|
||||
ConnectionType::P,
|
||||
host,
|
||||
port,
|
||||
None,
|
||||
0,
|
||||
obfuscation_type.try_into().unwrap(),
|
||||
obfuscated_port.try_into().unwrap(),
|
||||
);
|
||||
thread::spawn(move || {
|
||||
loop {
|
||||
match reader.recv() {
|
||||
Ok(operation) => {
|
||||
match operation {
|
||||
ClientOperation::ConnectToPeer(peer) => {
|
||||
let client_context_clone =
|
||||
client_context.clone();
|
||||
let own_username_clone = own_username.clone();
|
||||
@@ -702,62 +491,319 @@ impl Client {
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
ClientOperation::UpdateDownloadTokens(
|
||||
transfer,
|
||||
username,
|
||||
) => {
|
||||
let mut context = client_context.write().unwrap();
|
||||
|
||||
let download_to_update =
|
||||
context.get_downloads().iter().find_map(|d| {
|
||||
if d.username == username
|
||||
&& d.filename == transfer.filename
|
||||
{
|
||||
Some((d.token, d.clone()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
if let Some((old_token, download)) =
|
||||
download_to_update
|
||||
{
|
||||
ClientOperation::SearchResult(search_result) => {
|
||||
trace!(
|
||||
"[client] UpdateDownloadTokens found {old_token}, transfer: {:?}",
|
||||
transfer
|
||||
);
|
||||
"[client] SearchResult {:?}",
|
||||
search_result
|
||||
);
|
||||
let mut context =
|
||||
client_context.write().unwrap();
|
||||
let result_token = search_result.token;
|
||||
|
||||
context.add_download(Download {
|
||||
username: username.clone(),
|
||||
filename: transfer.filename,
|
||||
token: transfer.token,
|
||||
size: transfer.size,
|
||||
download_directory: download
|
||||
.download_directory,
|
||||
status: download.status.clone(),
|
||||
sender: download.sender.clone(),
|
||||
});
|
||||
context.remove_download(old_token);
|
||||
// Find the search with matching token
|
||||
for search in context.searches.values_mut() {
|
||||
if search.token == result_token {
|
||||
search.results.push(search_result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ClientOperation::PeerDisconnected(
|
||||
username,
|
||||
error,
|
||||
) => {
|
||||
let context = client_context.read().unwrap();
|
||||
if let Some(ref registry) =
|
||||
context.peer_registry
|
||||
&& let Some(handle) =
|
||||
registry.remove_peer(&username)
|
||||
{
|
||||
let _ = handle.stop();
|
||||
}
|
||||
if let Some(error) = error {
|
||||
warn!(
|
||||
"[client] Peer {} disconnected with error: {:?}",
|
||||
username, error
|
||||
);
|
||||
Self::process_failed_uploads(
|
||||
client_context.clone(),
|
||||
&username,
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
ClientOperation::PierceFireWall(peer) => {
|
||||
Self::pierce_firewall(
|
||||
peer,
|
||||
client_context.clone(),
|
||||
own_username.clone(),
|
||||
);
|
||||
}
|
||||
ClientOperation::DownloadFromPeer(
|
||||
token,
|
||||
peer,
|
||||
allowed,
|
||||
) => {
|
||||
let maybe_download = {
|
||||
let client_context =
|
||||
client_context.read().unwrap();
|
||||
client_context
|
||||
.get_download_by_token(token)
|
||||
.cloned()
|
||||
};
|
||||
let own_username = own_username.clone();
|
||||
let client_context_clone =
|
||||
client_context.clone();
|
||||
|
||||
trace!(
|
||||
"[client] DownloadFromPeer token: {} peer: {:?}",
|
||||
token, peer
|
||||
);
|
||||
match maybe_download {
|
||||
Some(download) => {
|
||||
thread::spawn(move || {
|
||||
let download_peer =
|
||||
DownloadPeer::new(
|
||||
download.username.clone(),
|
||||
peer.host.clone(),
|
||||
peer.port,
|
||||
token,
|
||||
allowed,
|
||||
own_username,
|
||||
);
|
||||
let filename: Option<&str> =
|
||||
download
|
||||
.filename
|
||||
.split('\\')
|
||||
.next_back();
|
||||
match filename {
|
||||
Some(filename) => {
|
||||
match download_peer
|
||||
.download_file(
|
||||
client_context_clone
|
||||
.clone(),
|
||||
Some(download.clone()),
|
||||
None,
|
||||
) {
|
||||
Ok((
|
||||
download,
|
||||
filename,
|
||||
)) => {
|
||||
let _ = download.sender.send(DownloadStatus::Completed);
|
||||
client_context_clone.write().unwrap().update_download_with_status(download.token, DownloadStatus::Completed);
|
||||
info!(
|
||||
"Successfully downloaded {} bytes to {}",
|
||||
download.size,
|
||||
filename
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
let _ = download.sender.send(DownloadStatus::Failed);
|
||||
client_context_clone.write().unwrap().update_download_with_status(download.token, DownloadStatus::Failed);
|
||||
error!(
|
||||
"Failed to download file '{}' from {}:{} (token: {}) - Error: {}",
|
||||
filename,
|
||||
peer.host,
|
||||
peer.port,
|
||||
download.token,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
None => error!(
|
||||
"Cant find filename to save download: {:?}",
|
||||
download.filename
|
||||
),
|
||||
}
|
||||
});
|
||||
}
|
||||
None => {
|
||||
error!(
|
||||
"Can't find download with token {:?}",
|
||||
token
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
ClientOperation::NewPeer(new_peer) => {
|
||||
let peer_exists = client_context
|
||||
.read()
|
||||
.unwrap()
|
||||
.peer_registry
|
||||
.as_ref()
|
||||
.map(|r| r.contains(&new_peer.username))
|
||||
.unwrap_or(false);
|
||||
|
||||
if peer_exists {
|
||||
debug!(
|
||||
"Already connected to {}",
|
||||
new_peer.username
|
||||
);
|
||||
} else if let Some(server_sender) =
|
||||
&client_context
|
||||
.read()
|
||||
.unwrap()
|
||||
.server_sender
|
||||
{
|
||||
server_sender
|
||||
.send(ServerMessage::GetPeerAddress(
|
||||
new_peer.username.clone(),
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let addr =
|
||||
new_peer.tcp_stream.peer_addr().unwrap();
|
||||
let host = addr.ip().to_string();
|
||||
let port: u32 = addr.port().into();
|
||||
|
||||
let peer = Peer {
|
||||
username: new_peer.username.clone(),
|
||||
connection_type: new_peer.connection_type,
|
||||
host,
|
||||
port,
|
||||
token: Some(new_peer.token),
|
||||
privileged: None,
|
||||
obfuscated_port: None,
|
||||
unknown: None,
|
||||
};
|
||||
|
||||
Self::connect_to_peer(
|
||||
peer,
|
||||
client_context.clone(),
|
||||
own_username.clone(),
|
||||
Some(new_peer.tcp_stream),
|
||||
);
|
||||
}
|
||||
ClientOperation::GetPeerAddressResponse {
|
||||
username,
|
||||
host,
|
||||
port,
|
||||
obfuscation_type,
|
||||
obfuscated_port,
|
||||
} => {
|
||||
debug!(
|
||||
"Received peer address for {}: {}:{} (obf_type: {}, obf_port: {})",
|
||||
username,
|
||||
host,
|
||||
port,
|
||||
obfuscation_type,
|
||||
obfuscated_port
|
||||
);
|
||||
|
||||
let peer_exists = client_context
|
||||
.read()
|
||||
.unwrap()
|
||||
.peer_registry
|
||||
.as_ref()
|
||||
.map(|r| r.contains(&username))
|
||||
.unwrap_or(false);
|
||||
|
||||
if peer_exists {
|
||||
// don't know if i should update? and or reconnect the peer
|
||||
// debug!(
|
||||
// "existing peer: {:?}, new peer details:
|
||||
// username: {},
|
||||
// host: {},
|
||||
// port: {}
|
||||
// obfuscation_type: {}
|
||||
// obfuscated_port: {}",
|
||||
// peer,
|
||||
// username,
|
||||
// host,
|
||||
// port,
|
||||
// obfuscation_type,
|
||||
// obfuscated_port,
|
||||
// );
|
||||
} else {
|
||||
let peer = Peer::new(
|
||||
username,
|
||||
ConnectionType::P,
|
||||
host,
|
||||
port,
|
||||
None,
|
||||
0,
|
||||
obfuscation_type.try_into().unwrap(),
|
||||
obfuscated_port.try_into().unwrap(),
|
||||
);
|
||||
let client_context_clone =
|
||||
client_context.clone();
|
||||
let own_username_clone =
|
||||
own_username.clone();
|
||||
|
||||
thread::spawn(move || {
|
||||
Self::connect_to_peer(
|
||||
peer,
|
||||
client_context_clone,
|
||||
own_username_clone,
|
||||
None,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
ClientOperation::UpdateDownloadTokens(
|
||||
transfer,
|
||||
username,
|
||||
) => {
|
||||
let mut context =
|
||||
client_context.write().unwrap();
|
||||
|
||||
let download_to_update = context
|
||||
.get_downloads()
|
||||
.iter()
|
||||
.find_map(|d| {
|
||||
if d.username == username
|
||||
&& d.filename == transfer.filename
|
||||
{
|
||||
Some((d.token, d.clone()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
if let Some((old_token, download)) =
|
||||
download_to_update
|
||||
{
|
||||
trace!(
|
||||
"[client] UpdateDownloadTokens found {old_token}, transfer: {:?}",
|
||||
transfer
|
||||
);
|
||||
|
||||
context.add_download(Download {
|
||||
username: username.clone(),
|
||||
filename: transfer.filename,
|
||||
token: transfer.token,
|
||||
size: transfer.size,
|
||||
download_directory: download
|
||||
.download_directory,
|
||||
status: download.status.clone(),
|
||||
sender: download.sender.clone(),
|
||||
});
|
||||
context.remove_download(old_token);
|
||||
}
|
||||
}
|
||||
ClientOperation::UploadFailed(
|
||||
username,
|
||||
filename,
|
||||
) => {
|
||||
Self::process_failed_uploads(
|
||||
client_context.clone(),
|
||||
&username,
|
||||
Some(&filename),
|
||||
);
|
||||
}
|
||||
ClientOperation::SetServerSender(sender) => {
|
||||
client_context.write().unwrap().server_sender =
|
||||
Some(sender);
|
||||
debug!("[client] Server sender initialized");
|
||||
}
|
||||
}
|
||||
ClientOperation::UploadFailed(username, filename) => {
|
||||
Self::process_failed_uploads(
|
||||
client_context.clone(),
|
||||
&username,
|
||||
Some(&filename),
|
||||
);
|
||||
}
|
||||
ClientOperation::SetServerSender(sender) => {
|
||||
client_context.write().unwrap().server_sender =
|
||||
Some(sender);
|
||||
debug!("[client] Server sender initialized");
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("[client] Channel recv error: {:?}", e);
|
||||
break;
|
||||
Err(e) => {
|
||||
error!("[client] Channel recv error: {:?}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -772,7 +818,10 @@ impl Client {
|
||||
let client_context = client_context.clone();
|
||||
|
||||
let peer_clone = peer.clone();
|
||||
trace!("[client] connecting to {}, with connection_type: {}, and token {:?}", peer.username, peer.connection_type, peer.token);
|
||||
trace!(
|
||||
"[client] connecting to {}, with connection_type: {}, and token {:?}",
|
||||
peer.username, peer.connection_type, peer.token
|
||||
);
|
||||
match peer.connection_type {
|
||||
ConnectionType::P => {
|
||||
let username = peer.username.clone();
|
||||
@@ -784,8 +833,7 @@ impl Client {
|
||||
Err(e) => {
|
||||
trace!(
|
||||
"Failed to spawn peer actor for {:?}: {:?}",
|
||||
username,
|
||||
e
|
||||
username, e
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -797,8 +845,7 @@ impl Client {
|
||||
ConnectionType::F => {
|
||||
trace!(
|
||||
"[client] downloading from: {}, {:?}",
|
||||
peer.username,
|
||||
peer.token
|
||||
peer.username, peer.token
|
||||
);
|
||||
let download_peer = DownloadPeer::new(
|
||||
peer.username,
|
||||
@@ -817,8 +864,7 @@ impl Client {
|
||||
Ok((download, filename)) => {
|
||||
trace!(
|
||||
"[client] downloaded {} bytes {:?} ",
|
||||
filename,
|
||||
download.size
|
||||
filename, download.size
|
||||
);
|
||||
let _ = download.sender.send(DownloadStatus::Completed);
|
||||
client_context
|
||||
|
||||
Reference in New Issue
Block a user