feat(shares): reply to browse requests with a SharedFileListResponse (code 5)

GetShareFileList (peer code 4) previously replied with a malformed message (a
server SharedFolders stats message over a peer connection). It now emits
ShareListRequested, and the client builds a real SharedFileListResponse
(code 5) from its shares grouped by directory. Adds a std-only code-5
encoder/decoder (build_shared_file_list / parse_shared_file_list) with a
roundtrip test, and Shares::directories() to group files. The decoder is the
foundation for the Browse feature.
This commit is contained in:
michel
2026-07-19 18:51:55 +02:00
parent 54d7d8f8a3
commit f3b24f34c0
6 changed files with 177 additions and 4 deletions
+37
View File
@@ -173,6 +173,10 @@ pub enum ClientOperation {
StartUpload {
token: u32,
},
/// A peer asked to browse our shared files; send our SharedFileListResponse.
ShareListRequested {
requester_key: String,
},
/// A direct outbound connection to this peer failed before it was
/// established — the peer is likely firewalled, so fall back to asking the
/// server to broker the connection. Carries the reporting actor's id.
@@ -1784,6 +1788,39 @@ impl Client {
}
}
}
ClientOperation::ShareListRequested {
requester_key,
} => {
// Reply with our full shared-file listing.
let (registry, message) = match client_context
.read_safe()
{
Ok(ctx) => {
let dirs = ctx
.shares
.directories()
.into_iter()
.map(|(name, files)| {
crate::message::peer::SharedDirectory {
name,
files,
}
})
.collect::<Vec<_>>();
(
ctx.peer_registry.clone(),
crate::message::peer::build_shared_file_list(&dirs),
)
}
Err(_) => continue,
};
if let Some(registry) = registry {
let _ = registry.send_to_peer(
&requester_key,
PeerMessage::SendMessage(message),
);
}
}
ClientOperation::PeerConnectFailed(
id,
username,