微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Rust (Bittorrent):宣布失败,响应“请求的下载未被授权用于此跟踪器”

如何解决Rust (Bittorrent):宣布失败,响应“请求的下载未被授权用于此跟踪器”

我正在尝试在 Bittorrent 网络中查找对等点,但收到响应“请求的下载未被授权用于此跟踪器”。我要下载的 torrent 文件是“Ubuntu 20.04.2.0 桌面(64 位)”,可以在 here 中找到。我已经检查过其他 Bittorrent 客户端,并确认 info_hash 是正确的。我倾向于认为我的错误可能是由于一些不正确的 url 编码,但我不确定。

代码的网络部分使用 reqwest 板条箱。为了对 info_hash 进行 url 编码,我使用了 urlencode 板条箱。下面是 url 编码和发送 GET 请求的代码

let client = reqwest::blocking::Client::new();
   
let info_hash_encoded = urlencoding::encode_binary(&torrent.info_hash).into_owned().to_uppercase();
let resp = client
    .get(&torrent.announce)
    .query(&[
        ("info_hash",info_hash_encoded.as_str()),("peer_id",PEER_ID),("port",PORT),("uploaded","0"),("downloaded",("compact","1"),("left",torrent.length.to_string().as_str()),])
    .send()?
    .text()?;

println!("{:?}",resp);

其中 torrent.info_hash 是作为字节向量 (Vec) 的信息哈希。

reqwest 响应实际上是这样的:

Response { url: Url { scheme: "https",cannot_be_a_base: false,username: "",password: None,host: Some(Domain("torrent.ubuntu.com")),port: None,path: "/announce",query: Some("info_hash=K%25A4%25FB%25F7%2523%251A%253AF%250E%2586%2589%2527%2507%25D2%255C%2513U3%25A1J&peer_id=-rqbt01-jsbckj94ksj3&port=5035&uploaded=0&downloaded=0&compact=1&left=2877227008"),fragment: None },status: 200,headers: {"date": "Sat,17 Jul 2021 17:05:25 GMT","server": "Apache/2.4.18 (Ubuntu)","content-length": "85","content-type": "text/plain","pragma": "no-cache","vary": "Accept-Encoding"} }

我最初认为问题可能是因为 info_hash_encoded 是小写的十六进制,但在将其大写后,我仍然收到相同的错误。顺便说一下,十六进制形式的信息哈希是:4ba4fbf7231a3a660e86892707d25c135533a16a

谢谢!

编辑:事实证明,哈希以某种方式被编码了两次,但即使在修复之后我仍然遇到同样的问题。有谁知道正确的 url 编码信息哈希是什么,以便我可以将它与我目前拥有的进行比较?我还尝试在 this spec 之后实现我自己的 url 编码,但我仍然收到相同的错误

解决方法

我有两个错误阻止了它的工作:

  1. info_hash 被编码两次,导致“%”字符被编码为“%25”。
  2. 每个非数字字节都应编码为 %,这意味着“%7”应为“%07”。我错过了前导零。

这对我有用:

use std::error::Error;
use std::fmt::Write;

pub fn url_encode_bytes(content: &[u8]) -> Result<String,Box<dyn Error>> {
    let mut out: String = String::new();

    for byte in content.iter() {
        match *byte as char {
            '0'..='9' | 'a'..='z' | 'A'..='Z' | '.' | '-' | '_' | '~' => out.push(*byte as char),_ => write!(&mut out,"%{:02X}",byte)?,};
    }

    Ok(out)
}

我还没有找到解决双重编码问题的好方法,但目前我只是像这样手动创建 info_hash 查询:

let url_builder = ureq::get(&torrent.announce)
    .query("peer_id",PEER_ID)
    .query("port",PORT)
    .query("uploaded","0")
    .query("downloaded","0")
    .query("compact","1")
    .query("left",LENGTH);

let url = format!(
    "{}{}",url_builder.url(),format!("&info_hash={}",url_encode_bytes(&torrent.info_hash)?)
);

我也从 reqwest 板条箱切换到 ureq 板条箱。
正确的 url 编码哈希(据我所知)是:K%A4%FB%F7%23%1A%3Af%0E%86%89%27%07%D2%5C%13U3%A1j

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。