feat(shares): serve queued files to peers over F connections
Implement the upload path so a peer can download our shared files: - fix the mis-coded PlaceInQueueResponse (43 -> 44) and add a real QueueUpload handler (code 43) -> PeerMessage::IncomingQueueUpload; - the peer actor forwards it as ClientOperation::QueueUpload; the client looks the file up in its shares, mints an upload token (high half of the token space, disjoint from md5 download tokens), and offers it via ServeUpload -> build_upload_transfer_request (peer code 40, direction=upload); - a TransferResponse for one of our serving tokens is handled by a surgical early-return that emits StartUpload, leaving the download path untouched; - StartUpload resolves the downloader's address (GetPeerAddress, cached) and streams the file via a new peer::upload_peer::serve_file over an F connection. Tested: build_upload_transfer_request decodes via the production Transfer parser; serve_file streams a file correctly over a loopback F connection.
This commit is contained in:
@@ -142,6 +142,23 @@ impl MessageFactory {
|
||||
.write_string(filename)
|
||||
.clone()
|
||||
}
|
||||
/// A TransferRequest (peer code 40) initiating an *upload*: we offer a file
|
||||
/// to a peer who queued it, quoting our transfer token and its size.
|
||||
#[must_use]
|
||||
pub fn build_upload_transfer_request(
|
||||
filename: &str,
|
||||
token: u32,
|
||||
size: u64,
|
||||
) -> Message {
|
||||
Message::new()
|
||||
.write_int32(40)
|
||||
.write_int32(1) // direction: upload
|
||||
.write_int32(token)
|
||||
.write_string(filename)
|
||||
.write_int64(size)
|
||||
.clone()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn build_transfer_response_message(transfer: Transfer) -> Message {
|
||||
Message::new()
|
||||
@@ -199,6 +216,21 @@ fn test_build_login_message() {
|
||||
assert_eq!(expect, message.get_data());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_upload_transfer_request() {
|
||||
use crate::types::Transfer;
|
||||
let message =
|
||||
MessageFactory::build_upload_transfer_request("song.mp3", 555, 4096);
|
||||
// Decode via the production Transfer parser (dispatcher starts at offset 8).
|
||||
let mut decoded = Message::new_with_data(message.get_buffer());
|
||||
decoded.set_pointer(8);
|
||||
let transfer = Transfer::new_from_message(&mut decoded);
|
||||
assert_eq!(transfer.direction, 1); // upload
|
||||
assert_eq!(transfer.token, 555);
|
||||
assert_eq!(transfer.filename, "song.mp3");
|
||||
assert_eq!(transfer.size, 4096);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_peer_init_message() {
|
||||
use crate::peer::ConnectionType;
|
||||
|
||||
Reference in New Issue
Block a user