From 0789f7ec3b0dec1e700f5d82a747718e4a8b6097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Frosteg=C3=A5rd?= Date: Mon, 30 Oct 2023 19:03:28 +0100 Subject: [PATCH] improve ws protocol struct naming and documentation --- crates/ws/src/workers/socket.rs | 4 +- crates/ws/src/workers/swarm.rs | 16 ++-- crates/ws_load_test/src/network.rs | 18 +++-- crates/ws_load_test/src/utils.rs | 12 +-- .../bench_deserialize_announce_request.rs | 12 ++- crates/ws_protocol/src/common.rs | 17 +++- crates/ws_protocol/src/incoming/announce.rs | 80 +++++++++++++++++++ .../src/{request => incoming}/mod.rs | 0 .../src/{request => incoming}/scrape.rs | 23 +++--- crates/ws_protocol/src/lib.rs | 41 ++++++---- .../src/{response => outgoing}/announce.rs | 1 + .../src/{response => outgoing}/answer.rs | 11 +-- .../src/{response => outgoing}/error.rs | 14 ++-- .../src/{response => outgoing}/mod.rs | 4 +- .../src/{response => outgoing}/offer.rs | 15 ++-- .../src/{response => outgoing}/scrape.rs | 2 +- crates/ws_protocol/src/request/announce.rs | 60 -------------- 17 files changed, 193 insertions(+), 137 deletions(-) create mode 100644 crates/ws_protocol/src/incoming/announce.rs rename crates/ws_protocol/src/{request => incoming}/mod.rs (100%) rename crates/ws_protocol/src/{request => incoming}/scrape.rs (74%) rename crates/ws_protocol/src/{response => outgoing}/announce.rs (91%) rename crates/ws_protocol/src/{response => outgoing}/answer.rs (55%) rename crates/ws_protocol/src/{response => outgoing}/error.rs (100%) rename crates/ws_protocol/src/{response => outgoing}/mod.rs (93%) rename crates/ws_protocol/src/{response => outgoing}/offer.rs (53%) rename crates/ws_protocol/src/{response => outgoing}/scrape.rs (87%) delete mode 100644 crates/ws_protocol/src/request/announce.rs diff --git a/crates/ws/src/workers/socket.rs b/crates/ws/src/workers/socket.rs index ff3797a..419800d 100644 --- a/crates/ws/src/workers/socket.rs +++ b/crates/ws/src/workers/socket.rs @@ -906,8 +906,8 @@ impl ConnectionWriter { #[cfg(feature = "metrics")] { let out_message_type = match &out_message { - OutMessage::Offer(_) => "offer", - OutMessage::Answer(_) => "offer_answer", + OutMessage::OfferOutMessage(_) => "offer", + OutMessage::AnswerOutMessage(_) => "offer_answer", OutMessage::AnnounceResponse(_) => "announce", OutMessage::ScrapeResponse(_) => "scrape", OutMessage::ErrorResponse(_) => "error", diff --git a/crates/ws/src/workers/swarm.rs b/crates/ws/src/workers/swarm.rs index d852044..b973f87 100644 --- a/crates/ws/src/workers/swarm.rs +++ b/crates/ws/src/workers/swarm.rs @@ -443,7 +443,7 @@ fn handle_announce_request( ); for (offer, offer_receiver) in offers.into_iter().zip(offer_receivers) { - let middleman_offer = MiddlemanOfferToPeer { + let offer_out_message = OfferOutMessage { action: AnnounceAction, info_hash: request.info_hash, peer_id: request.peer_id, @@ -457,17 +457,19 @@ fn handle_announce_request( pending_scrape_id: None, }; - out_messages.push((meta, OutMessage::Offer(middleman_offer))); + out_messages.push((meta, OutMessage::OfferOutMessage(offer_out_message))); ::log::trace!("sending middleman offer to {:?}", meta); } } // If peer sent answer, send it on to relevant peer - if let (Some(answer), Some(answer_receiver_id), Some(offer_id)) = - (request.answer, request.to_peer_id, request.offer_id) - { + if let (Some(answer), Some(answer_receiver_id), Some(offer_id)) = ( + request.answer, + request.answer_to_peer_id, + request.answer_offer_id, + ) { if let Some(answer_receiver) = torrent_data.peers.get(&answer_receiver_id) { - let middleman_answer = MiddlemanAnswerToPeer { + let answer_out_message = AnswerOutMessage { action: AnnounceAction, peer_id: request.peer_id, info_hash: request.info_hash, @@ -481,7 +483,7 @@ fn handle_announce_request( pending_scrape_id: None, }; - out_messages.push((meta, OutMessage::Answer(middleman_answer))); + out_messages.push((meta, OutMessage::AnswerOutMessage(answer_out_message))); ::log::trace!("sending middleman answer to {:?}", meta); } } diff --git a/crates/ws_load_test/src/network.rs b/crates/ws_load_test/src/network.rs index e6ef638..ef8f553 100644 --- a/crates/ws_load_test/src/network.rs +++ b/crates/ws_load_test/src/network.rs @@ -6,7 +6,7 @@ use std::{ time::Duration, }; -use aquatic_ws_protocol::{InMessage, JsonValue, OfferId, OutMessage, PeerId}; +use aquatic_ws_protocol::{InMessage, OfferId, OutMessage, PeerId, RtcAnswer}; use async_tungstenite::{client_async, WebSocketStream}; use futures::{SinkExt, StreamExt}; use futures_rustls::{client::TlsStream, TlsConnector}; @@ -131,11 +131,13 @@ impl Connection { // the request an offer answer let request = if let InMessage::AnnounceRequest(mut r) = request { if let Some((peer_id, offer_id)) = self.send_answer { - r.to_peer_id = Some(peer_id); - r.offer_id = Some(offer_id); - r.answer = Some(JsonValue(::serde_json::json!( - {"sdp": "abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-"} - ))); + r.answer_to_peer_id = Some(peer_id); + r.answer_offer_id = Some(offer_id); + r.answer = Some(RtcAnswer { + sdp: ::serde_json::json!( + {"sdp": "abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-"} + ), + }); r.event = None; r.offers = None; } @@ -182,7 +184,7 @@ impl Connection { }; match OutMessage::from_ws_message(message) { - Ok(OutMessage::Offer(offer)) => { + Ok(OutMessage::OfferOutMessage(offer)) => { self.load_test_state .statistics .responses_offer @@ -192,7 +194,7 @@ impl Connection { self.can_send = true; } - Ok(OutMessage::Answer(_)) => { + Ok(OutMessage::AnswerOutMessage(_)) => { self.load_test_state .statistics .responses_answer diff --git a/crates/ws_load_test/src/utils.rs b/crates/ws_load_test/src/utils.rs index 74646b1..b42d84a 100644 --- a/crates/ws_load_test/src/utils.rs +++ b/crates/ws_load_test/src/utils.rs @@ -50,9 +50,11 @@ fn create_announce_request( for _ in 0..config.torrents.offers_per_request { offers.push(AnnounceRequestOffer { offer_id: OfferId(rng.gen()), - offer: JsonValue(::serde_json::json!( - {"sdp": "abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-"} - )), + offer: RtcOffer { + sdp: ::serde_json::json!( + {"sdp": "abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-abcdefg-"} + ) + }, }) } @@ -65,8 +67,8 @@ fn create_announce_request( numwant: Some(offers.len()), offers: Some(offers), answer: None, - to_peer_id: None, - offer_id: None, + answer_to_peer_id: None, + answer_offer_id: None, }) } diff --git a/crates/ws_protocol/benches/bench_deserialize_announce_request.rs b/crates/ws_protocol/benches/bench_deserialize_announce_request.rs index d9b9ae7..d6998b9 100644 --- a/crates/ws_protocol/benches/bench_deserialize_announce_request.rs +++ b/crates/ws_protocol/benches/bench_deserialize_announce_request.rs @@ -15,7 +15,9 @@ pub fn bench(c: &mut Criterion) { offer_id.0[i] = i as u8; AnnounceRequestOffer { - offer: JsonValue(::serde_json::json!({ "sdp": "abcdef" })), + offer: RtcOffer { + sdp: ::serde_json::json!({ "sdp": "abcdef" }), + }, offer_id, } }) @@ -30,9 +32,11 @@ pub fn bench(c: &mut Criterion) { event: Some(AnnounceEvent::Started), offers: Some(offers), numwant: Some(offers_len), - answer: Some(JsonValue(::serde_json::json!({ "sdp": "abcdef" }))), - to_peer_id: Some(peer_id), - offer_id: Some(OfferId(info_hash.0)), + answer: Some(RtcAnswer { + sdp: ::serde_json::json!({ "sdp": "abcdef" }), + }), + answer_to_peer_id: Some(peer_id), + answer_offer_id: Some(OfferId(info_hash.0)), }); let ws_message = request.to_ws_message(); diff --git a/crates/ws_protocol/src/common.rs b/crates/ws_protocol/src/common.rs index a1fdb1e..859ffc0 100644 --- a/crates/ws_protocol/src/common.rs +++ b/crates/ws_protocol/src/common.rs @@ -30,10 +30,21 @@ pub struct OfferId( pub [u8; 20], ); -/// Some kind of nested structure from https://www.npmjs.com/package/simple-peer +/// Nested structure with SDP offer from https://www.npmjs.com/package/simple-peer +/// +/// Created using https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createOffer #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[serde(transparent)] -pub struct JsonValue(pub ::serde_json::Value); +pub struct RtcOffer { + pub sdp: ::serde_json::Value, +} + +/// Nested structure with SDP answer from https://www.npmjs.com/package/simple-peer +/// +/// Created using https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createAnswer +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct RtcAnswer { + pub sdp: ::serde_json::Value, +} #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AnnounceAction; diff --git a/crates/ws_protocol/src/incoming/announce.rs b/crates/ws_protocol/src/incoming/announce.rs new file mode 100644 index 0000000..3a93eb9 --- /dev/null +++ b/crates/ws_protocol/src/incoming/announce.rs @@ -0,0 +1,80 @@ +use serde::{Deserialize, Serialize}; + +use crate::common::*; + +/// Announce request +/// +/// Can optionally contain: +/// - A number of WebRTC offers to be sent on to other peers. In this case, +/// fields 'offers' and 'numwant' are set +/// - An answer to a WebRTC offer from another peer. In this case, fields +/// 'answer', 'to_peer_id' and 'offer_id' are set. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct AnnounceRequest { + /// Always "announce" + pub action: AnnounceAction, + pub info_hash: InfoHash, + pub peer_id: PeerId, + /// Bytes left + /// + /// Just called "left" in protocol. Is set to None in some cases, such as + /// when opening a magnet link + #[serde(rename = "left")] + pub bytes_left: Option, + /// Can be empty. Then, default is "update" + #[serde(skip_serializing_if = "Option::is_none")] + pub event: Option, + + /// WebRTC offers (with offer id's) that peer wants sent on to random other peers + /// + /// Notes from reference implementation: + /// - Only when this is an array offers are sent to other peers + /// - Length of this is number of peers wanted? + /// - Max length of this is 10 in reference client code + /// - Not sent when announce event is stopped or completed + pub offers: Option>, + /// Number of peers wanted + /// + /// Notes from reference implementation: + /// - Seems to only get sent by client when sending offers, and is also + /// same as length of offers vector (or at least never smaller) + /// - Max length of this is 10 in reference client code + /// - Could probably be ignored, `offers.len()` should provide needed info + pub numwant: Option, + + /// WebRTC answer to previous offer from other peer, to be passed on to it + /// + /// Notes from reference implementation: + /// - If empty, send response before sending offers (or possibly "skip + /// sending update back"?) + /// - Else, send AnswerOutMessage to peer with "to_peer_id" as peer_id + pub answer: Option, + /// Which peer to send answer to + #[serde(rename = "to_peer_id")] + pub answer_to_peer_id: Option, + /// OfferID of offer this is an answer to + #[serde(rename = "offer_id")] + pub answer_offer_id: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum AnnounceEvent { + Started, + Stopped, + Completed, + Update, +} + +impl Default for AnnounceEvent { + fn default() -> Self { + Self::Update + } +} + +/// Element of AnnounceRequest.offers +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct AnnounceRequestOffer { + pub offer: RtcOffer, + pub offer_id: OfferId, +} diff --git a/crates/ws_protocol/src/request/mod.rs b/crates/ws_protocol/src/incoming/mod.rs similarity index 100% rename from crates/ws_protocol/src/request/mod.rs rename to crates/ws_protocol/src/incoming/mod.rs diff --git a/crates/ws_protocol/src/request/scrape.rs b/crates/ws_protocol/src/incoming/scrape.rs similarity index 74% rename from crates/ws_protocol/src/request/scrape.rs rename to crates/ws_protocol/src/incoming/scrape.rs index d016c82..aa9a3d5 100644 --- a/crates/ws_protocol/src/request/scrape.rs +++ b/crates/ws_protocol/src/incoming/scrape.rs @@ -2,6 +2,19 @@ use serde::{Deserialize, Serialize}; use crate::common::*; +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct ScrapeRequest { + /// Always "scrape" + pub action: ScrapeAction, + /// Info hash or info hashes + /// + /// Notes from reference implementation: + /// - If omitted, scrape for all torrents, apparently + /// - Accepts a single info hash or an array of info hashes + #[serde(rename = "info_hash")] + pub info_hashes: Option, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(untagged)] pub enum ScrapeRequestInfoHashes { @@ -17,13 +30,3 @@ impl ScrapeRequestInfoHashes { } } } - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct ScrapeRequest { - pub action: ScrapeAction, - // If omitted, scrape for all torrents, apparently - // There is some kind of parsing here too which accepts a single info hash - // and puts it into a vector - #[serde(rename = "info_hash")] - pub info_hashes: Option, -} diff --git a/crates/ws_protocol/src/lib.rs b/crates/ws_protocol/src/lib.rs index 5772307..28bde42 100644 --- a/crates/ws_protocol/src/lib.rs +++ b/crates/ws_protocol/src/lib.rs @@ -11,12 +11,12 @@ //! - Peer sends scrape request and receives scrape response pub mod common; -pub mod request; -pub mod response; +pub mod incoming; +pub mod outgoing; pub use common::*; -pub use request::*; -pub use response::*; +pub use incoming::*; +pub use outgoing::*; #[cfg(test)] mod tests { @@ -35,8 +35,15 @@ mod tests { bytes } - fn sdp_json_value() -> JsonValue { - JsonValue(::serde_json::json!({ "sdp": "test" })) + fn rtc_offer() -> RtcOffer { + RtcOffer { + sdp: ::serde_json::json!({ "sdp": "test" }), + } + } + fn rtc_answer() -> RtcAnswer { + RtcAnswer { + sdp: ::serde_json::json!({ "sdp": "test" }), + } } impl Arbitrary for InfoHash { @@ -68,26 +75,26 @@ mod tests { } } - impl Arbitrary for MiddlemanOfferToPeer { + impl Arbitrary for OfferOutMessage { fn arbitrary(g: &mut quickcheck::Gen) -> Self { Self { action: AnnounceAction, peer_id: Arbitrary::arbitrary(g), info_hash: Arbitrary::arbitrary(g), offer_id: Arbitrary::arbitrary(g), - offer: sdp_json_value(), + offer: rtc_offer(), } } } - impl Arbitrary for MiddlemanAnswerToPeer { + impl Arbitrary for AnswerOutMessage { fn arbitrary(g: &mut quickcheck::Gen) -> Self { Self { action: AnnounceAction, peer_id: Arbitrary::arbitrary(g), info_hash: Arbitrary::arbitrary(g), offer_id: Arbitrary::arbitrary(g), - answer: sdp_json_value(), + answer: rtc_answer(), } } } @@ -96,7 +103,7 @@ mod tests { fn arbitrary(g: &mut quickcheck::Gen) -> Self { Self { offer_id: Arbitrary::arbitrary(g), - offer: sdp_json_value(), + offer: rtc_offer(), } } } @@ -106,7 +113,7 @@ mod tests { let has_offers_or_answer_or_neither: Option = Arbitrary::arbitrary(g); let mut offers: Option> = None; - let mut answer: Option = None; + let mut answer: Option = None; let mut to_peer_id: Option = None; let mut offer_id: Option = None; @@ -115,7 +122,7 @@ mod tests { offers = Some(Arbitrary::arbitrary(g)); } Some(false) => { - answer = Some(sdp_json_value()); + answer = Some(rtc_answer()); to_peer_id = Some(Arbitrary::arbitrary(g)); offer_id = Some(Arbitrary::arbitrary(g)); } @@ -133,8 +140,8 @@ mod tests { offers, numwant, answer, - to_peer_id, - offer_id, + answer_to_peer_id: to_peer_id, + answer_offer_id: offer_id, } } } @@ -206,8 +213,8 @@ mod tests { match (Arbitrary::arbitrary(g), Arbitrary::arbitrary(g)) { (false, false) => Self::AnnounceResponse(Arbitrary::arbitrary(g)), (true, false) => Self::ScrapeResponse(Arbitrary::arbitrary(g)), - (false, true) => Self::Offer(Arbitrary::arbitrary(g)), - (true, true) => Self::Answer(Arbitrary::arbitrary(g)), + (false, true) => Self::OfferOutMessage(Arbitrary::arbitrary(g)), + (true, true) => Self::AnswerOutMessage(Arbitrary::arbitrary(g)), } } } diff --git a/crates/ws_protocol/src/response/announce.rs b/crates/ws_protocol/src/outgoing/announce.rs similarity index 91% rename from crates/ws_protocol/src/response/announce.rs rename to crates/ws_protocol/src/outgoing/announce.rs index 25d4b9e..25d0693 100644 --- a/crates/ws_protocol/src/response/announce.rs +++ b/crates/ws_protocol/src/outgoing/announce.rs @@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::common::*; +/// Plain response to an AnnounceRequest #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct AnnounceResponse { pub action: AnnounceAction, diff --git a/crates/ws_protocol/src/response/answer.rs b/crates/ws_protocol/src/outgoing/answer.rs similarity index 55% rename from crates/ws_protocol/src/response/answer.rs rename to crates/ws_protocol/src/outgoing/answer.rs index 3846c7e..751ba31 100644 --- a/crates/ws_protocol/src/response/answer.rs +++ b/crates/ws_protocol/src/outgoing/answer.rs @@ -2,15 +2,16 @@ use serde::{Deserialize, Serialize}; use crate::common::*; -/// If announce request has answer = true, send this to peer with -/// peer id == "to_peer_id" field -/// Action field should be 'announce' +/// Message sent to peer when other peer has replied to its WebRTC offer +/// +/// Sent if fields answer, to_peer_id and offer_id are set in announce request #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct MiddlemanAnswerToPeer { +pub struct AnswerOutMessage { + /// Always "announce" pub action: AnnounceAction, /// Note: if equal to client peer_id, client ignores answer pub peer_id: PeerId, pub info_hash: InfoHash, - pub answer: JsonValue, + pub answer: RtcAnswer, pub offer_id: OfferId, } diff --git a/crates/ws_protocol/src/response/error.rs b/crates/ws_protocol/src/outgoing/error.rs similarity index 100% rename from crates/ws_protocol/src/response/error.rs rename to crates/ws_protocol/src/outgoing/error.rs index c5be603..1293daa 100644 --- a/crates/ws_protocol/src/response/error.rs +++ b/crates/ws_protocol/src/outgoing/error.rs @@ -4,13 +4,6 @@ use serde::{Deserialize, Serialize}; use crate::common::*; -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "lowercase")] -pub enum ErrorResponseAction { - Announce, - Scrape, -} - #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct ErrorResponse { #[serde(rename = "failure reason")] @@ -22,3 +15,10 @@ pub struct ErrorResponse { #[serde(skip_serializing_if = "Option::is_none")] pub info_hash: Option, } + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum ErrorResponseAction { + Announce, + Scrape, +} diff --git a/crates/ws_protocol/src/response/mod.rs b/crates/ws_protocol/src/outgoing/mod.rs similarity index 93% rename from crates/ws_protocol/src/response/mod.rs rename to crates/ws_protocol/src/outgoing/mod.rs index 8885221..c2fbaab 100644 --- a/crates/ws_protocol/src/response/mod.rs +++ b/crates/ws_protocol/src/outgoing/mod.rs @@ -16,8 +16,8 @@ pub use scrape::*; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(untagged)] pub enum OutMessage { - Offer(MiddlemanOfferToPeer), - Answer(MiddlemanAnswerToPeer), + OfferOutMessage(OfferOutMessage), + AnswerOutMessage(AnswerOutMessage), AnnounceResponse(AnnounceResponse), ScrapeResponse(ScrapeResponse), ErrorResponse(ErrorResponse), diff --git a/crates/ws_protocol/src/response/offer.rs b/crates/ws_protocol/src/outgoing/offer.rs similarity index 53% rename from crates/ws_protocol/src/response/offer.rs rename to crates/ws_protocol/src/outgoing/offer.rs index 2c47abc..9cbe6b9 100644 --- a/crates/ws_protocol/src/response/offer.rs +++ b/crates/ws_protocol/src/outgoing/offer.rs @@ -2,18 +2,21 @@ use serde::{Deserialize, Serialize}; use crate::common::*; -/// Apparently, these are sent to a number of peers when they are set -/// in an AnnounceRequest -/// action = "announce" +/// Message sent to peer when other peer wants to initiate a WebRTC connection +/// +/// One is sent for each offer in an announce request #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct MiddlemanOfferToPeer { +pub struct OfferOutMessage { + /// Always "announce" pub action: AnnounceAction, /// Peer id of peer sending offer - /// Note: if equal to client peer_id, client ignores offer + /// + /// Note: if equal to client peer_id, reference client ignores offer pub peer_id: PeerId, + /// Torrent info hash pub info_hash: InfoHash, /// Gets copied from AnnounceRequestOffer - pub offer: JsonValue, + pub offer: RtcOffer, /// Gets copied from AnnounceRequestOffer pub offer_id: OfferId, } diff --git a/crates/ws_protocol/src/response/scrape.rs b/crates/ws_protocol/src/outgoing/scrape.rs similarity index 87% rename from crates/ws_protocol/src/response/scrape.rs rename to crates/ws_protocol/src/outgoing/scrape.rs index d7ace9f..5ac2051 100644 --- a/crates/ws_protocol/src/response/scrape.rs +++ b/crates/ws_protocol/src/outgoing/scrape.rs @@ -7,7 +7,7 @@ use crate::common::*; pub struct ScrapeResponse { pub action: ScrapeAction, pub files: HashMap, - // Looks like `flags` field is ignored in reference client + // It looks like `flags` field is ignored in reference client // pub flags: HashMap, } diff --git a/crates/ws_protocol/src/request/announce.rs b/crates/ws_protocol/src/request/announce.rs deleted file mode 100644 index 5634ca3..0000000 --- a/crates/ws_protocol/src/request/announce.rs +++ /dev/null @@ -1,60 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use crate::common::*; - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "lowercase")] -pub enum AnnounceEvent { - Started, - Stopped, - Completed, - Update, -} - -impl Default for AnnounceEvent { - fn default() -> Self { - Self::Update - } -} - -/// Element of AnnounceRequest.offers -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct AnnounceRequestOffer { - pub offer: JsonValue, - pub offer_id: OfferId, -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct AnnounceRequest { - pub action: AnnounceAction, - pub info_hash: InfoHash, - pub peer_id: PeerId, - /// Just called "left" in protocol. Is set to None in some cases, such as - /// when opening a magnet link - #[serde(rename = "left")] - pub bytes_left: Option, - /// Can be empty. Then, default is "update" - #[serde(skip_serializing_if = "Option::is_none")] - pub event: Option, - - /// Only when this is an array offers are sent to random peers - /// Length of this is number of peers wanted? - /// Max length of this is 10 in reference client code - /// Not sent when announce event is stopped or completed - pub offers: Option>, - /// Seems to only get sent by client when sending offers, and is also same - /// as length of offers vector (or at least never less) - /// Max length of this is 10 in reference client code - /// Could probably be ignored, `offers.len()` should provide needed info - pub numwant: Option, - - /// If empty, send response before sending offers (or possibly "skip sending update back"?) - /// Else, send MiddlemanAnswerToPeer to peer with "to_peer_id" as peer_id. - /// I think using Option is good, it seems like this isn't always set - /// (same as `offers`) - pub answer: Option, - /// Likely undefined if !(answer == true) - pub to_peer_id: Option, - /// Sent if answer is set - pub offer_id: Option, -}