mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-17 17:34:09 +02:00
add support for magnet file download links
This commit is contained in:
@@ -286,6 +286,10 @@ namespace Jackett.Indexers
|
|||||||
|
|
||||||
protected async Task<byte[]> Download(Uri link, RequestType method)
|
protected async Task<byte[]> Download(Uri link, RequestType method)
|
||||||
{
|
{
|
||||||
|
// return magnet link
|
||||||
|
if (link.Scheme == "magnet")
|
||||||
|
return Encoding.UTF8.GetBytes(link.OriginalString);
|
||||||
|
|
||||||
// do some extra escaping, needed for HD-Torrents
|
// do some extra escaping, needed for HD-Torrents
|
||||||
var requestLink = link.ToString()
|
var requestLink = link.ToString()
|
||||||
.Replace("(", "%28")
|
.Replace("(", "%28")
|
||||||
|
@@ -10,7 +10,7 @@ namespace Jackett.Services.Interfaces
|
|||||||
void Start();
|
void Start();
|
||||||
void Stop();
|
void Stop();
|
||||||
void ReserveUrls(bool doInstall = true);
|
void ReserveUrls(bool doInstall = true);
|
||||||
Uri ConvertToProxyLink(Uri link, string serverUrl, string indexerId, string action = "dl", string file = "t.torrent");
|
Uri ConvertToProxyLink(Uri link, string serverUrl, string indexerId, string action = "dl", string file = "t");
|
||||||
string BasePath();
|
string BasePath();
|
||||||
string GetServerUrl(HttpRequestMessage Request);
|
string GetServerUrl(HttpRequestMessage Request);
|
||||||
List<string> notices { get; }
|
List<string> notices { get; }
|
||||||
|
@@ -50,8 +50,23 @@ namespace Jackett.Controllers
|
|||||||
path = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(path));
|
path = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(path));
|
||||||
path = protectionService.UnProtect(path);
|
path = protectionService.UnProtect(path);
|
||||||
var remoteFile = new Uri(path, UriKind.RelativeOrAbsolute);
|
var remoteFile = new Uri(path, UriKind.RelativeOrAbsolute);
|
||||||
|
var fileExtension = ".torrent";
|
||||||
var downloadBytes = await indexer.Download(remoteFile);
|
var downloadBytes = await indexer.Download(remoteFile);
|
||||||
|
|
||||||
|
// handle magnet URLs
|
||||||
|
if (downloadBytes.Length >= 7
|
||||||
|
&& downloadBytes[0] == 0x6d // m
|
||||||
|
&& downloadBytes[1] == 0x61 // a
|
||||||
|
&& downloadBytes[2] == 0x67 // g
|
||||||
|
&& downloadBytes[3] == 0x6e // n
|
||||||
|
&& downloadBytes[4] == 0x65 // e
|
||||||
|
&& downloadBytes[5] == 0x74 // t
|
||||||
|
&& downloadBytes[6] == 0x3a // :
|
||||||
|
)
|
||||||
|
{
|
||||||
|
fileExtension = ".magnet";
|
||||||
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(serverConfig.BlackholeDir))
|
if (string.IsNullOrWhiteSpace(serverConfig.BlackholeDir))
|
||||||
{
|
{
|
||||||
throw new Exception("Blackhole directory not set!");
|
throw new Exception("Blackhole directory not set!");
|
||||||
@@ -64,9 +79,9 @@ namespace Jackett.Controllers
|
|||||||
|
|
||||||
var fileName = DateTime.Now.Ticks.ToString() + "-" + StringUtil.MakeValidFileName(indexer.DisplayName, '_', false);
|
var fileName = DateTime.Now.Ticks.ToString() + "-" + StringUtil.MakeValidFileName(indexer.DisplayName, '_', false);
|
||||||
if (string.IsNullOrWhiteSpace(file))
|
if (string.IsNullOrWhiteSpace(file))
|
||||||
fileName += ".torrent";
|
fileName += fileExtension;
|
||||||
else
|
else
|
||||||
fileName += "-"+StringUtil.MakeValidFileName(file, '_', false); // call MakeValidFileName() again to avoid any possibility of path traversal attacks
|
fileName += "-"+StringUtil.MakeValidFileName(file + fileExtension, '_', false); // call MakeValidFileName() again to avoid any possibility of path traversal attacks
|
||||||
|
|
||||||
File.WriteAllBytes(Path.Combine(serverConfig.BlackholeDir, fileName), downloadBytes);
|
File.WriteAllBytes(Path.Combine(serverConfig.BlackholeDir, fileName), downloadBytes);
|
||||||
jsonReply["result"] = "success";
|
jsonReply["result"] = "success";
|
||||||
|
@@ -53,6 +53,23 @@ namespace Jackett.Controllers
|
|||||||
var target = new Uri(path, UriKind.RelativeOrAbsolute);
|
var target = new Uri(path, UriKind.RelativeOrAbsolute);
|
||||||
var downloadBytes = await indexer.Download(target);
|
var downloadBytes = await indexer.Download(target);
|
||||||
|
|
||||||
|
// handle magnet URLs
|
||||||
|
if (downloadBytes.Length >= 7
|
||||||
|
&& downloadBytes[0] == 0x6d // m
|
||||||
|
&& downloadBytes[1] == 0x61 // a
|
||||||
|
&& downloadBytes[2] == 0x67 // g
|
||||||
|
&& downloadBytes[3] == 0x6e // n
|
||||||
|
&& downloadBytes[4] == 0x65 // e
|
||||||
|
&& downloadBytes[5] == 0x74 // t
|
||||||
|
&& downloadBytes[6] == 0x3a // :
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var magneturi = Encoding.UTF8.GetString(downloadBytes);
|
||||||
|
var response = Request.CreateResponse(HttpStatusCode.Moved);
|
||||||
|
response.Headers.Location = new Uri(magneturi);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
// This will fix torrents where the keys are not sorted, and thereby not supported by Sonarr.
|
// This will fix torrents where the keys are not sorted, and thereby not supported by Sonarr.
|
||||||
var parser = new BencodeParser();
|
var parser = new BencodeParser();
|
||||||
var torrentDictionary = parser.Parse(downloadBytes);
|
var torrentDictionary = parser.Parse(downloadBytes);
|
||||||
@@ -63,7 +80,7 @@ namespace Jackett.Controllers
|
|||||||
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-bittorrent");
|
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-bittorrent");
|
||||||
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
|
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
|
||||||
{
|
{
|
||||||
FileName = StringUtil.MakeValidFileName(file, '_', false) // call MakeValidFileName again to avoid any kind of injection attack
|
FileName = StringUtil.MakeValidFileName(file, '_', false) + ".torrent" // call MakeValidFileName again to avoid any kind of injection attack
|
||||||
};
|
};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@@ -156,7 +156,7 @@ namespace Jackett.Controllers.V20
|
|||||||
foreach (var result in results)
|
foreach (var result in results)
|
||||||
{
|
{
|
||||||
var link = result.Link;
|
var link = result.Link;
|
||||||
var file = StringUtil.MakeValidFileName(result.Title, '_', false) + ".torrent";
|
var file = StringUtil.MakeValidFileName(result.Title, '_', false);
|
||||||
result.Link = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "dl", file);
|
result.Link = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "dl", file);
|
||||||
if (result.Link != null && result.Link.Scheme != "magnet" && !string.IsNullOrWhiteSpace(Engine.ServerConfig.BlackholeDir))
|
if (result.Link != null && result.Link.Scheme != "magnet" && !string.IsNullOrWhiteSpace(Engine.ServerConfig.BlackholeDir))
|
||||||
result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", file);
|
result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", file);
|
||||||
|
@@ -319,7 +319,7 @@ namespace Jackett.Controllers.V20
|
|||||||
|
|
||||||
var proxiedReleases = result.Releases.Select(r => AutoMapper.Mapper.Map<ReleaseInfo>(r)).Select(r =>
|
var proxiedReleases = result.Releases.Select(r => AutoMapper.Mapper.Map<ReleaseInfo>(r)).Select(r =>
|
||||||
{
|
{
|
||||||
r.Link = serverService.ConvertToProxyLink(r.Link, serverUrl, r.Origin.ID, "dl", r.Title + ".torrent");
|
r.Link = serverService.ConvertToProxyLink(r.Link, serverUrl, r.Origin.ID, "dl", r.Title);
|
||||||
return r;
|
return r;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -371,7 +371,7 @@ namespace Jackett.Controllers.V20
|
|||||||
var potatoReleases = result.Releases.Where(r => r.Link != null || r.MagnetUri != null).Select(r =>
|
var potatoReleases = result.Releases.Where(r => r.Link != null || r.MagnetUri != null).Select(r =>
|
||||||
{
|
{
|
||||||
var release = AutoMapper.Mapper.Map<ReleaseInfo>(r);
|
var release = AutoMapper.Mapper.Map<ReleaseInfo>(r);
|
||||||
release.Link = serverService.ConvertToProxyLink(release.Link, serverUrl, CurrentIndexer.ID, "dl", release.Title + ".torrent");
|
release.Link = serverService.ConvertToProxyLink(release.Link, serverUrl, CurrentIndexer.ID, "dl", release.Title);
|
||||||
var item = new Models.DTO.TorrentPotatoResponseItem()
|
var item = new Models.DTO.TorrentPotatoResponseItem()
|
||||||
{
|
{
|
||||||
release_name = release.Title + "[" + CurrentIndexer.DisplayName + "]", // Suffix the indexer so we can see which tracker we are using in CPS as it just says torrentpotato >.>
|
release_name = release.Title + "[" + CurrentIndexer.DisplayName + "]", // Suffix the indexer so we can see which tracker we are using in CPS as it just says torrentpotato >.>
|
||||||
@@ -403,7 +403,7 @@ namespace Jackett.Controllers.V20
|
|||||||
foreach (var result in results)
|
foreach (var result in results)
|
||||||
{
|
{
|
||||||
var link = result.Link;
|
var link = result.Link;
|
||||||
var file = StringUtil.MakeValidFileName(result.Title, '_', false) + ".torrent";
|
var file = StringUtil.MakeValidFileName(result.Title, '_', false);
|
||||||
result.Link = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "dl", file);
|
result.Link = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "dl", file);
|
||||||
if (result.Link != null && result.Link.Scheme != "magnet" && !string.IsNullOrWhiteSpace(Engine.ServerConfig.BlackholeDir))
|
if (result.Link != null && result.Link.Scheme != "magnet" && !string.IsNullOrWhiteSpace(Engine.ServerConfig.BlackholeDir))
|
||||||
result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", file);
|
result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", file);
|
||||||
|
@@ -59,7 +59,7 @@ namespace Jackett.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uri ConvertToProxyLink(Uri link, string serverUrl, string indexerId, string action = "dl", string file = "t.torrent")
|
public Uri ConvertToProxyLink(Uri link, string serverUrl, string indexerId, string action = "dl", string file = "t")
|
||||||
{
|
{
|
||||||
if (link == null || (link.IsAbsoluteUri && link.Scheme == "magnet"))
|
if (link == null || (link.IsAbsoluteUri && link.Scheme == "magnet"))
|
||||||
return link;
|
return link;
|
||||||
|
Reference in New Issue
Block a user