[feature] support 40-byte infohash (not a magnet) as a way to add torrents
This commit is contained in:
parent
8d2aa93a78
commit
95f5a322f6
3 changed files with 23 additions and 2 deletions
|
|
@ -10,6 +10,7 @@ use futures::{FutureExt, TryStreamExt};
|
||||||
use http::{HeaderMap, HeaderValue, StatusCode};
|
use http::{HeaderMap, HeaderValue, StatusCode};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
use librqbit_core::magnet::Magnet;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::io::SeekFrom;
|
use std::io::SeekFrom;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
@ -118,6 +119,12 @@ impl HttpApi {
|
||||||
let is_url = params.is_url;
|
let is_url = params.is_url;
|
||||||
let opts = params.into_add_torrent_options();
|
let opts = params.into_add_torrent_options();
|
||||||
let data = data.to_vec();
|
let data = data.to_vec();
|
||||||
|
let maybe_magnet = |data: &[u8]| -> bool {
|
||||||
|
std::str::from_utf8(data)
|
||||||
|
.ok()
|
||||||
|
.and_then(|s| Magnet::parse(s).ok())
|
||||||
|
.is_some()
|
||||||
|
};
|
||||||
let add = match is_url {
|
let add = match is_url {
|
||||||
Some(true) => AddTorrent::Url(
|
Some(true) => AddTorrent::Url(
|
||||||
String::from_utf8(data)
|
String::from_utf8(data)
|
||||||
|
|
@ -129,7 +136,8 @@ impl HttpApi {
|
||||||
// Guess the format.
|
// Guess the format.
|
||||||
None if SUPPORTED_SCHEMES
|
None if SUPPORTED_SCHEMES
|
||||||
.iter()
|
.iter()
|
||||||
.any(|s| data.starts_with(s.as_bytes())) =>
|
.any(|s| data.starts_with(s.as_bytes()))
|
||||||
|
|| maybe_magnet(&data) =>
|
||||||
{
|
{
|
||||||
AddTorrent::Url(
|
AddTorrent::Url(
|
||||||
String::from_utf8(data)
|
String::from_utf8(data)
|
||||||
|
|
|
||||||
|
|
@ -334,6 +334,9 @@ impl<'a> AddTorrent<'a> {
|
||||||
if SUPPORTED_SCHEMES.iter().any(|s| path.starts_with(s)) {
|
if SUPPORTED_SCHEMES.iter().any(|s| path.starts_with(s)) {
|
||||||
return Ok(Self::Url(Cow::Borrowed(path)));
|
return Ok(Self::Url(Cow::Borrowed(path)));
|
||||||
}
|
}
|
||||||
|
if path.len() == 40 && !Path::new(path).exists() && Magnet::parse(path).is_ok() {
|
||||||
|
return Ok(Self::Url(Cow::Borrowed(path)));
|
||||||
|
}
|
||||||
Self::from_local_filename(path)
|
Self::from_local_filename(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -884,7 +887,7 @@ impl Session {
|
||||||
// So we must discover at least one peer and connect to it to be able to proceed further.
|
// So we must discover at least one peer and connect to it to be able to proceed further.
|
||||||
|
|
||||||
let add_res = match add {
|
let add_res = match add {
|
||||||
AddTorrent::Url(magnet) if magnet.starts_with("magnet:") => {
|
AddTorrent::Url(magnet) if magnet.starts_with("magnet:") || magnet.len() == 40 => {
|
||||||
let magnet = Magnet::parse(&magnet)
|
let magnet = Magnet::parse(&magnet)
|
||||||
.context("provided path is not a valid magnet URL")?;
|
.context("provided path is not a valid magnet URL")?;
|
||||||
let info_hash = magnet
|
let info_hash = magnet
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,16 @@ impl Magnet {
|
||||||
|
|
||||||
/// Parse a magnet link.
|
/// Parse a magnet link.
|
||||||
pub fn parse(url: &str) -> anyhow::Result<Magnet> {
|
pub fn parse(url: &str) -> anyhow::Result<Magnet> {
|
||||||
|
if url.len() == 40 {
|
||||||
|
if let Ok(id20) = Id20::from_str(url) {
|
||||||
|
return Ok(Magnet {
|
||||||
|
id20: Some(id20),
|
||||||
|
id32: None,
|
||||||
|
trackers: vec![],
|
||||||
|
select_only: None,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
let url = url::Url::parse(url).context("magnet link must be a valid URL")?;
|
let url = url::Url::parse(url).context("magnet link must be a valid URL")?;
|
||||||
if url.scheme() != "magnet" {
|
if url.scheme() != "magnet" {
|
||||||
anyhow::bail!("expected scheme magnet");
|
anyhow::bail!("expected scheme magnet");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue