add support for magnet file download links

This commit is contained in:
kaso17
2017-11-09 13:28:15 +01:00
parent 6d53e486c5
commit a6b5401c0b
7 changed files with 45 additions and 9 deletions

View File

@@ -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")

View File

@@ -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; }

View File

@@ -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";

View File

@@ -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;
} }

View File

@@ -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);

View 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);

View 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;