mirror of
https://github.com/YGGverse/aquatic.git
synced 2026-03-31 17:55:36 +00:00
Merge pull request #180 from greatest-ape/work-2023-01-29
protocol crates: rename some methods, minor improvements
This commit is contained in:
commit
1807c4a1e9
21 changed files with 103 additions and 82 deletions
|
|
@ -389,7 +389,7 @@ where
|
|||
let mut position = RESPONSE_HEADER.len();
|
||||
|
||||
let body_len = response
|
||||
.write(&mut &mut self.response_buffer[position..])
|
||||
.write_bytes(&mut &mut self.response_buffer[position..])
|
||||
.map_err(ConnectionError::ResponseBufferWrite)?;
|
||||
|
||||
position += body_len;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ pub fn parse_request(
|
|||
match http_request.parse(buffer).with_context(|| "httparse")? {
|
||||
httparse::Status::Complete(_) => {
|
||||
let path = http_request.path.ok_or(anyhow::anyhow!("no http path"))?;
|
||||
let request = Request::from_http_get_path(path)?;
|
||||
let request = Request::parse_http_get_path(path)?;
|
||||
|
||||
let opt_peer_ip = if config.network.runs_behind_reverse_proxy {
|
||||
let header_name = &config.network.reverse_proxy_ip_header_name;
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ where
|
|||
}
|
||||
|
||||
if let Some(body_start_index) = opt_body_start_index {
|
||||
match Response::from_bytes(&interesting_bytes[body_start_index..]) {
|
||||
match Response::parse_bytes(&interesting_bytes[body_start_index..]) {
|
||||
Ok(response) => {
|
||||
match response {
|
||||
Response::Announce(_) => {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ pub fn bench(c: &mut Criterion) {
|
|||
b.iter(|| {
|
||||
buffer.set_position(0);
|
||||
|
||||
Response::write(black_box(&response), black_box(&mut buffer)).unwrap();
|
||||
Response::write_bytes(black_box(&response), black_box(&mut buffer)).unwrap();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ static INPUT: &[u8] = b"GET /announce?info_hash=%04%0bkV%3f%5cr%14%a6%b7%98%adC%
|
|||
|
||||
pub fn bench(c: &mut Criterion) {
|
||||
c.bench_function("request-from-bytes", |b| {
|
||||
b.iter(|| Request::from_bytes(black_box(INPUT)))
|
||||
b.iter(|| Request::parse_bytes(black_box(INPUT)))
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ pub struct AnnounceRequest {
|
|||
}
|
||||
|
||||
impl AnnounceRequest {
|
||||
fn write<W: Write>(&self, output: &mut W, url_suffix: &[u8]) -> ::std::io::Result<()> {
|
||||
fn write_bytes<W: Write>(&self, output: &mut W, url_suffix: &[u8]) -> ::std::io::Result<()> {
|
||||
output.write_all(b"GET /announce")?;
|
||||
output.write_all(url_suffix)?;
|
||||
output.write_all(b"?info_hash=")?;
|
||||
|
|
@ -67,7 +67,7 @@ impl AnnounceRequest {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn from_query_string(query_string: &str) -> anyhow::Result<Self> {
|
||||
pub fn parse_query_string(query_string: &str) -> anyhow::Result<Self> {
|
||||
// -- Parse key-value pairs
|
||||
|
||||
let mut opt_info_hash = None;
|
||||
|
|
@ -173,7 +173,7 @@ pub struct ScrapeRequest {
|
|||
}
|
||||
|
||||
impl ScrapeRequest {
|
||||
fn write<W: Write>(&self, output: &mut W, url_suffix: &[u8]) -> ::std::io::Result<()> {
|
||||
fn write_bytes<W: Write>(&self, output: &mut W, url_suffix: &[u8]) -> ::std::io::Result<()> {
|
||||
output.write_all(b"GET /scrape")?;
|
||||
output.write_all(url_suffix)?;
|
||||
output.write_all(b"?")?;
|
||||
|
|
@ -196,7 +196,7 @@ impl ScrapeRequest {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn from_query_string(query_string: &str) -> anyhow::Result<Self> {
|
||||
pub fn parse_query_string(query_string: &str) -> anyhow::Result<Self> {
|
||||
// -- Parse key-value pairs
|
||||
|
||||
let mut info_hashes = Vec::new();
|
||||
|
|
@ -252,14 +252,14 @@ pub enum Request {
|
|||
|
||||
impl Request {
|
||||
/// Parse Request from HTTP request bytes
|
||||
pub fn from_bytes(bytes: &[u8]) -> anyhow::Result<Option<Self>> {
|
||||
pub fn parse_bytes(bytes: &[u8]) -> anyhow::Result<Option<Self>> {
|
||||
let mut headers = [httparse::EMPTY_HEADER; 16];
|
||||
let mut http_request = httparse::Request::new(&mut headers);
|
||||
|
||||
match http_request.parse(bytes) {
|
||||
Ok(httparse::Status::Complete(_)) => {
|
||||
if let Some(path) = http_request.path {
|
||||
Self::from_http_get_path(path).map(Some)
|
||||
Self::parse_http_get_path(path).map(Some)
|
||||
} else {
|
||||
Err(anyhow::anyhow!("no http path"))
|
||||
}
|
||||
|
|
@ -282,7 +282,7 @@ impl Request {
|
|||
/// UTF-8 string, meaning that non-ascii bytes are invalid characters.
|
||||
/// Therefore, these bytes must be converted to their equivalent multi-byte
|
||||
/// UTF-8 encodings.
|
||||
pub fn from_http_get_path(path: &str) -> anyhow::Result<Self> {
|
||||
pub fn parse_http_get_path(path: &str) -> anyhow::Result<Self> {
|
||||
::log::debug!("request GET path: {}", path);
|
||||
|
||||
let mut split_parts = path.splitn(2, '?');
|
||||
|
|
@ -291,11 +291,11 @@ impl Request {
|
|||
let query_string = split_parts.next().with_context(|| "no query string")?;
|
||||
|
||||
if location == "/announce" {
|
||||
Ok(Request::Announce(AnnounceRequest::from_query_string(
|
||||
Ok(Request::Announce(AnnounceRequest::parse_query_string(
|
||||
query_string,
|
||||
)?))
|
||||
} else if location == "/scrape" {
|
||||
Ok(Request::Scrape(ScrapeRequest::from_query_string(
|
||||
Ok(Request::Scrape(ScrapeRequest::parse_query_string(
|
||||
query_string,
|
||||
)?))
|
||||
} else {
|
||||
|
|
@ -305,8 +305,8 @@ impl Request {
|
|||
|
||||
pub fn write<W: Write>(&self, output: &mut W, url_suffix: &[u8]) -> ::std::io::Result<()> {
|
||||
match self {
|
||||
Self::Announce(r) => r.write(output, url_suffix),
|
||||
Self::Scrape(r) => r.write(output, url_suffix),
|
||||
Self::Announce(r) => r.write_bytes(output, url_suffix),
|
||||
Self::Scrape(r) => r.write_bytes(output, url_suffix),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -351,7 +351,7 @@ mod tests {
|
|||
bytes.extend_from_slice(ANNOUNCE_REQUEST_PATH.as_bytes());
|
||||
bytes.extend_from_slice(b" HTTP/1.1\r\n\r\n");
|
||||
|
||||
let parsed_request = Request::from_bytes(&bytes[..]).unwrap().unwrap();
|
||||
let parsed_request = Request::parse_bytes(&bytes[..]).unwrap().unwrap();
|
||||
let reference_request = get_reference_announce_request();
|
||||
|
||||
assert_eq!(parsed_request, reference_request);
|
||||
|
|
@ -365,7 +365,7 @@ mod tests {
|
|||
bytes.extend_from_slice(SCRAPE_REQUEST_PATH.as_bytes());
|
||||
bytes.extend_from_slice(b" HTTP/1.1\r\n\r\n");
|
||||
|
||||
let parsed_request = Request::from_bytes(&bytes[..]).unwrap().unwrap();
|
||||
let parsed_request = Request::parse_bytes(&bytes[..]).unwrap().unwrap();
|
||||
let reference_request = Request::Scrape(ScrapeRequest {
|
||||
info_hashes: vec![InfoHash(REFERENCE_INFO_HASH)],
|
||||
});
|
||||
|
|
@ -432,7 +432,7 @@ mod tests {
|
|||
|
||||
request.write(&mut bytes, &[]).unwrap();
|
||||
|
||||
let parsed_request = Request::from_bytes(&bytes[..]).unwrap().unwrap();
|
||||
let parsed_request = Request::parse_bytes(&bytes[..]).unwrap().unwrap();
|
||||
|
||||
let success = request == parsed_request;
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ pub struct AnnounceResponse {
|
|||
}
|
||||
|
||||
impl AnnounceResponse {
|
||||
pub fn write<W: Write>(&self, output: &mut W) -> ::std::io::Result<usize> {
|
||||
pub fn write_bytes<W: Write>(&self, output: &mut W) -> ::std::io::Result<usize> {
|
||||
let mut bytes_written = 0usize;
|
||||
|
||||
bytes_written += output.write(b"d8:completei")?;
|
||||
|
|
@ -124,7 +124,7 @@ pub struct ScrapeResponse {
|
|||
}
|
||||
|
||||
impl ScrapeResponse {
|
||||
pub fn write<W: Write>(&self, output: &mut W) -> ::std::io::Result<usize> {
|
||||
pub fn write_bytes<W: Write>(&self, output: &mut W) -> ::std::io::Result<usize> {
|
||||
let mut bytes_written = 0usize;
|
||||
|
||||
bytes_written += output.write(b"d5:filesd")?;
|
||||
|
|
@ -160,7 +160,7 @@ impl FailureResponse {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn write<W: Write>(&self, output: &mut W) -> ::std::io::Result<usize> {
|
||||
pub fn write_bytes<W: Write>(&self, output: &mut W) -> ::std::io::Result<usize> {
|
||||
let mut bytes_written = 0usize;
|
||||
|
||||
let reason_bytes = self.failure_reason.as_bytes();
|
||||
|
|
@ -184,14 +184,14 @@ pub enum Response {
|
|||
}
|
||||
|
||||
impl Response {
|
||||
pub fn write<W: Write>(&self, output: &mut W) -> ::std::io::Result<usize> {
|
||||
pub fn write_bytes<W: Write>(&self, output: &mut W) -> ::std::io::Result<usize> {
|
||||
match self {
|
||||
Response::Announce(r) => r.write(output),
|
||||
Response::Failure(r) => r.write(output),
|
||||
Response::Scrape(r) => r.write(output),
|
||||
Response::Announce(r) => r.write_bytes(output),
|
||||
Response::Failure(r) => r.write_bytes(output),
|
||||
Response::Scrape(r) => r.write_bytes(output),
|
||||
}
|
||||
}
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, ::serde_bencode::Error> {
|
||||
pub fn parse_bytes(bytes: &[u8]) -> Result<Self, ::serde_bencode::Error> {
|
||||
::serde_bencode::from_bytes(bytes)
|
||||
}
|
||||
}
|
||||
|
|
@ -285,7 +285,7 @@ mod tests {
|
|||
|
||||
let mut hand_written = Vec::new();
|
||||
|
||||
response.write(&mut hand_written).unwrap();
|
||||
response.write_bytes(&mut hand_written).unwrap();
|
||||
|
||||
let success = hand_written == reference;
|
||||
|
||||
|
|
@ -303,7 +303,7 @@ mod tests {
|
|||
|
||||
let mut hand_written = Vec::new();
|
||||
|
||||
response.write(&mut hand_written).unwrap();
|
||||
response.write_bytes(&mut hand_written).unwrap();
|
||||
|
||||
let success = hand_written == reference;
|
||||
|
||||
|
|
@ -321,7 +321,7 @@ mod tests {
|
|||
|
||||
let mut hand_written = Vec::new();
|
||||
|
||||
response.write(&mut hand_written).unwrap();
|
||||
response.write_bytes(&mut hand_written).unwrap();
|
||||
|
||||
let success = hand_written == reference;
|
||||
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ mod tests {
|
|||
|
||||
let mut buf = Vec::new();
|
||||
|
||||
response.write(&mut buf).unwrap();
|
||||
response.write_bytes(&mut buf).unwrap();
|
||||
|
||||
println!("Buffer len: {}", buf.len());
|
||||
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ impl SocketWorker {
|
|||
}
|
||||
|
||||
let src = CanonicalSocketAddr::new(src);
|
||||
let request_parsable = match Request::from_bytes(
|
||||
let request_parsable = match Request::parse_bytes(
|
||||
&self.buffer[..bytes_read],
|
||||
self.config.protocol.max_scrape_torrents,
|
||||
) {
|
||||
|
|
@ -431,7 +431,7 @@ impl SocketWorker {
|
|||
) {
|
||||
let mut buffer = Cursor::new(&mut buffer[..]);
|
||||
|
||||
if let Err(err) = response.write(&mut buffer) {
|
||||
if let Err(err) = response.write_bytes(&mut buffer) {
|
||||
::log::error!("failed writing response to buffer: {:#}", err);
|
||||
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ impl RecvHelper {
|
|||
|
||||
let addr = CanonicalSocketAddr::new(addr);
|
||||
|
||||
let request = Request::from_bytes(msg.payload_data(), self.max_scrape_torrents)
|
||||
let request = Request::parse_bytes(msg.payload_data(), self.max_scrape_torrents)
|
||||
.map_err(|err| Error::RequestParseError(err, addr))?;
|
||||
|
||||
Ok((request, addr))
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ impl SendBuffer {
|
|||
|
||||
let mut cursor = Cursor::new(&mut self.bytes[..]);
|
||||
|
||||
match response.write(&mut cursor) {
|
||||
match response.write_bytes(&mut cursor) {
|
||||
Ok(()) => {
|
||||
self.iovec.iov_len = cursor.position() as usize;
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ pub fn request_and_response(
|
|||
let mut buffer = Cursor::new(&mut buffer[..]);
|
||||
|
||||
request
|
||||
.write(&mut buffer)
|
||||
.write_bytes(&mut buffer)
|
||||
.with_context(|| "write request")?;
|
||||
|
||||
let bytes_written = buffer.position() as usize;
|
||||
|
|
@ -119,6 +119,6 @@ pub fn request_and_response(
|
|||
.recv_from(&mut buffer)
|
||||
.with_context(|| "recv response")?;
|
||||
|
||||
Response::from_bytes(&buffer[..bytes_read], true).with_context(|| "parse response")
|
||||
Response::parse_bytes(&buffer[..bytes_read], true).with_context(|| "parse response")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ fn no_response(
|
|||
let mut buffer = Cursor::new(&mut buffer[..]);
|
||||
|
||||
request
|
||||
.write(&mut buffer)
|
||||
.write_bytes(&mut buffer)
|
||||
.with_context(|| "write request")?;
|
||||
|
||||
let bytes_written = buffer.position() as usize;
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ impl Worker {
|
|||
|
||||
for _ in events.iter() {
|
||||
while let Ok(amt) = self.socket.recv(&mut self.buffer) {
|
||||
match Response::from_bytes(&self.buffer[0..amt], self.addr.is_ipv4()) {
|
||||
match Response::parse_bytes(&self.buffer[0..amt], self.addr.is_ipv4()) {
|
||||
Ok(response) => {
|
||||
if let Some(request) = self.process_response(response) {
|
||||
self.send_request(request);
|
||||
|
|
@ -288,7 +288,7 @@ impl Worker {
|
|||
fn send_request(&mut self, request: Request) {
|
||||
let mut cursor = Cursor::new(self.buffer);
|
||||
|
||||
match request.write(&mut cursor) {
|
||||
match request.write_bytes(&mut cursor) {
|
||||
Ok(()) => {
|
||||
let position = cursor.position() as usize;
|
||||
let inner = cursor.get_ref();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
# aquatic_udp_protocol: UDP BitTorrent tracker protocol
|
||||
|
||||
[UDP BitTorrent](https://www.bittorrent.org/beps/bep_0015.html) tracker
|
||||
message parsing and serialization.
|
||||
UDP BitTorrent tracker message parsing and serialization.
|
||||
|
||||
Implements [BEP 015](https://www.bittorrent.org/beps/bep_0015.html) ([more details](https://libtorrent.org/udp_tracker_protocol.html)).
|
||||
|
|
|
|||
|
|
@ -19,30 +19,15 @@ pub enum Request {
|
|||
}
|
||||
|
||||
impl Request {
|
||||
pub fn write(self, bytes: &mut impl Write) -> Result<(), io::Error> {
|
||||
pub fn write_bytes(&self, bytes: &mut impl Write) -> Result<(), io::Error> {
|
||||
match self {
|
||||
Request::Connect(r) => {
|
||||
bytes.write_i64::<NetworkEndian>(PROTOCOL_IDENTIFIER)?;
|
||||
bytes.write_i32::<NetworkEndian>(0)?;
|
||||
bytes.write_all(r.transaction_id.as_bytes())?;
|
||||
}
|
||||
|
||||
Request::Announce(r) => {
|
||||
bytes.write_all(r.as_bytes())?;
|
||||
}
|
||||
|
||||
Request::Scrape(r) => {
|
||||
bytes.write_all(r.connection_id.as_bytes())?;
|
||||
bytes.write_i32::<NetworkEndian>(2)?;
|
||||
bytes.write_all(r.transaction_id.as_bytes())?;
|
||||
bytes.write_all((*r.info_hashes.as_slice()).as_bytes())?;
|
||||
Request::Connect(r) => r.write_bytes(bytes),
|
||||
Request::Announce(r) => r.write_bytes(bytes),
|
||||
Request::Scrape(r) => r.write_bytes(bytes),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8], max_scrape_torrents: u8) -> Result<Self, RequestParseError> {
|
||||
pub fn parse_bytes(bytes: &[u8], max_scrape_torrents: u8) -> Result<Self, RequestParseError> {
|
||||
let action = bytes
|
||||
.get(8..12)
|
||||
.map(|bytes| I32::from_bytes(bytes.try_into().unwrap()))
|
||||
|
|
@ -145,12 +130,22 @@ impl From<ScrapeRequest> for Request {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
pub struct ConnectRequest {
|
||||
pub transaction_id: TransactionId,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Debug, AsBytes, FromBytes, FromZeroes)]
|
||||
impl ConnectRequest {
|
||||
pub fn write_bytes(&self, bytes: &mut impl Write) -> Result<(), io::Error> {
|
||||
bytes.write_i64::<NetworkEndian>(PROTOCOL_IDENTIFIER)?;
|
||||
bytes.write_i32::<NetworkEndian>(0)?;
|
||||
bytes.write_all(self.transaction_id.as_bytes())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug, AsBytes, FromBytes, FromZeroes)]
|
||||
#[repr(C, packed)]
|
||||
pub struct AnnounceRequest {
|
||||
pub connection_id: ConnectionId,
|
||||
|
|
@ -170,6 +165,12 @@ pub struct AnnounceRequest {
|
|||
pub port: Port,
|
||||
}
|
||||
|
||||
impl AnnounceRequest {
|
||||
pub fn write_bytes(&self, bytes: &mut impl Write) -> Result<(), io::Error> {
|
||||
bytes.write_all(self.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
/// Note: Request::from_bytes only creates this struct with value 1
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug, AsBytes, FromBytes, FromZeroes)]
|
||||
#[repr(transparent)]
|
||||
|
|
@ -223,6 +224,17 @@ pub struct ScrapeRequest {
|
|||
pub info_hashes: Vec<InfoHash>,
|
||||
}
|
||||
|
||||
impl ScrapeRequest {
|
||||
pub fn write_bytes(&self, bytes: &mut impl Write) -> Result<(), io::Error> {
|
||||
bytes.write_all(self.connection_id.as_bytes())?;
|
||||
bytes.write_i32::<NetworkEndian>(2)?;
|
||||
bytes.write_all(self.transaction_id.as_bytes())?;
|
||||
bytes.write_all((*self.info_hashes.as_slice()).as_bytes())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RequestParseError {
|
||||
Sendable {
|
||||
|
|
@ -323,8 +335,8 @@ mod tests {
|
|||
fn same_after_conversion(request: Request) -> bool {
|
||||
let mut buf = Vec::new();
|
||||
|
||||
request.clone().write(&mut buf).unwrap();
|
||||
let r2 = Request::from_bytes(&buf[..], ::std::u8::MAX).unwrap();
|
||||
request.clone().write_bytes(&mut buf).unwrap();
|
||||
let r2 = Request::parse_bytes(&buf[..], ::std::u8::MAX).unwrap();
|
||||
|
||||
let success = request == r2;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,18 +18,18 @@ pub enum Response {
|
|||
|
||||
impl Response {
|
||||
#[inline]
|
||||
pub fn write(&self, bytes: &mut impl Write) -> Result<(), io::Error> {
|
||||
pub fn write_bytes(&self, bytes: &mut impl Write) -> Result<(), io::Error> {
|
||||
match self {
|
||||
Response::Connect(r) => r.write(bytes),
|
||||
Response::AnnounceIpv4(r) => r.write(bytes),
|
||||
Response::AnnounceIpv6(r) => r.write(bytes),
|
||||
Response::Scrape(r) => r.write(bytes),
|
||||
Response::Error(r) => r.write(bytes),
|
||||
Response::Connect(r) => r.write_bytes(bytes),
|
||||
Response::AnnounceIpv4(r) => r.write_bytes(bytes),
|
||||
Response::AnnounceIpv6(r) => r.write_bytes(bytes),
|
||||
Response::Scrape(r) => r.write_bytes(bytes),
|
||||
Response::Error(r) => r.write_bytes(bytes),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_bytes(mut bytes: &[u8], ipv4: bool) -> Result<Self, io::Error> {
|
||||
pub fn parse_bytes(mut bytes: &[u8], ipv4: bool) -> Result<Self, io::Error> {
|
||||
let action = read_i32_ne(&mut bytes)?;
|
||||
|
||||
match action.get() {
|
||||
|
|
@ -128,7 +128,7 @@ impl From<ErrorResponse> for Response {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Debug, AsBytes, FromBytes, FromZeroes)]
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug, AsBytes, FromBytes, FromZeroes)]
|
||||
#[repr(C, packed)]
|
||||
pub struct ConnectResponse {
|
||||
pub transaction_id: TransactionId,
|
||||
|
|
@ -137,7 +137,7 @@ pub struct ConnectResponse {
|
|||
|
||||
impl ConnectResponse {
|
||||
#[inline]
|
||||
pub fn write(&self, bytes: &mut impl Write) -> Result<(), io::Error> {
|
||||
pub fn write_bytes(&self, bytes: &mut impl Write) -> Result<(), io::Error> {
|
||||
bytes.write_i32::<NetworkEndian>(0)?;
|
||||
bytes.write_all(self.as_bytes())?;
|
||||
|
||||
|
|
@ -160,7 +160,7 @@ impl<I: Ip> AnnounceResponse<I> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn write(&self, bytes: &mut impl Write) -> Result<(), io::Error> {
|
||||
pub fn write_bytes(&self, bytes: &mut impl Write) -> Result<(), io::Error> {
|
||||
bytes.write_i32::<NetworkEndian>(1)?;
|
||||
bytes.write_all(self.fixed.as_bytes())?;
|
||||
bytes.write_all((*self.peers.as_slice()).as_bytes())?;
|
||||
|
|
@ -169,7 +169,7 @@ impl<I: Ip> AnnounceResponse<I> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Debug, AsBytes, FromBytes, FromZeroes)]
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug, AsBytes, FromBytes, FromZeroes)]
|
||||
#[repr(C, packed)]
|
||||
pub struct AnnounceResponseFixedData {
|
||||
pub transaction_id: TransactionId,
|
||||
|
|
@ -186,7 +186,7 @@ pub struct ScrapeResponse {
|
|||
|
||||
impl ScrapeResponse {
|
||||
#[inline]
|
||||
pub fn write(&self, bytes: &mut impl Write) -> Result<(), io::Error> {
|
||||
pub fn write_bytes(&self, bytes: &mut impl Write) -> Result<(), io::Error> {
|
||||
bytes.write_i32::<NetworkEndian>(2)?;
|
||||
bytes.write_all(self.transaction_id.as_bytes())?;
|
||||
bytes.write_all((*self.torrent_stats.as_slice()).as_bytes())?;
|
||||
|
|
@ -211,7 +211,7 @@ pub struct ErrorResponse {
|
|||
|
||||
impl ErrorResponse {
|
||||
#[inline]
|
||||
pub fn write(&self, bytes: &mut impl Write) -> Result<(), io::Error> {
|
||||
pub fn write_bytes(&self, bytes: &mut impl Write) -> Result<(), io::Error> {
|
||||
bytes.write_i32::<NetworkEndian>(3)?;
|
||||
bytes.write_all(self.transaction_id.as_bytes())?;
|
||||
bytes.write_all(self.message.as_bytes())?;
|
||||
|
|
@ -304,8 +304,8 @@ mod tests {
|
|||
fn same_after_conversion(response: Response, ipv4: bool) -> bool {
|
||||
let mut buf = Vec::new();
|
||||
|
||||
response.clone().write(&mut buf).unwrap();
|
||||
let r2 = Response::from_bytes(&buf[..], ipv4).unwrap();
|
||||
response.clone().write_bytes(&mut buf).unwrap();
|
||||
let r2 = Response::parse_bytes(&buf[..], ipv4).unwrap();
|
||||
|
||||
let success = response == r2;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@ rust-version.workspace = true
|
|||
|
||||
readme = "./README.md"
|
||||
|
||||
[features]
|
||||
default = ["tungstenite"]
|
||||
tungstenite = ["dep:tungstenite"]
|
||||
|
||||
[lib]
|
||||
name = "aquatic_ws_protocol"
|
||||
|
||||
|
|
@ -26,7 +30,7 @@ hashbrown = { version = "0.14", features = ["serde"] }
|
|||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
simd-json = "0.13"
|
||||
tungstenite = "0.21"
|
||||
tungstenite = { version = "0.21", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.5"
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ pub enum InMessage {
|
|||
ScrapeRequest(ScrapeRequest),
|
||||
}
|
||||
|
||||
#[cfg(feature = "tungstenite")]
|
||||
impl InMessage {
|
||||
#[inline]
|
||||
pub fn to_ws_message(&self) -> ::tungstenite::Message {
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tungstenite")]
|
||||
#[quickcheck]
|
||||
fn quickcheck_serde_identity_in_message(in_message_1: InMessage) -> bool {
|
||||
let ws_message = in_message_1.to_ws_message();
|
||||
|
|
@ -246,6 +247,7 @@ mod tests {
|
|||
success
|
||||
}
|
||||
|
||||
#[cfg(feature = "tungstenite")]
|
||||
#[quickcheck]
|
||||
fn quickcheck_serde_identity_out_message(out_message_1: OutMessage) -> bool {
|
||||
let ws_message = out_message_1.to_ws_message();
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ pub enum OutMessage {
|
|||
ErrorResponse(ErrorResponse),
|
||||
}
|
||||
|
||||
#[cfg(feature = "tungstenite")]
|
||||
impl OutMessage {
|
||||
#[inline]
|
||||
pub fn to_ws_message(&self) -> tungstenite::Message {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue