Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support decoding an initial bencode structure and retrieving the remaining bytes #63

Open
jwodder opened this issue Jun 11, 2023 · 2 comments

Comments

@jwodder
Copy link

jwodder commented Jun 11, 2023

BEP 9 (the protocol for resolving magnet URIs) defines a data packet that consists of a bencoded dictionary followed by arbitrary data (actually a slice of a torrent's info dict), and I would like to parse such a packet using bendy. The best way I've figured out to do this so far is to create a Decoder, call next_object(), retrieve the DictDecoder, iterate through & massage the dict's fields, call DictDecoder::into_raw() after handling all fields, get the length of the raw dict, and use that length as an offset to slice the original payload. This is rather unwieldy, and I believe this could be simplified by just giving Decoder a remaining(self) -> &'ser [u8] method for retrieving all remaining bytes of the payload after doing next_object() + FromBencode::decode_bencode_object().

@gabrieldemian
Copy link

I'm also trying to implement this exact feature, would be great if this could be supported by bendy

@gabrieldemian
Copy link

I'm doing a workaround. info_begin is the length of your payload - the length of the metadata. It is still using Bendy, we just split the buffer at the right spot and decode both sides, assuming both of them implements FromBencode.

pub struct Info {
    // .....
}
pub struct Metadata {
    pub msg_type: u8,
    pub piece: u32,
    pub total_size: u32,
}

impl Metadata {
    /// Tries to extract Info from the given buffer, which is the payload of the extended metadata "data" message.
    pub fn extract(mut buf: Vec<u8>, info_begin: usize) -> Result<(Self, Info), error::Error> {
        let info_buf: Vec<u8> = buf.drain(info_begin..).collect();

        let info = Info::from_bencode(&info_buf).unwrap();
        let metadata = Metadata::from_bencode(&buf).unwrap();

        Ok((metadata, info))
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants