Fixed: Indexers returning relative urls for grabs.
This commit is contained in:
parent
38c57ce73a
commit
211863d55d
|
@ -1,31 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<!DOCTYPE torrent PUBLIC "-//bitTorrent//DTD torrent 0.1//EN" "http://xmlns.ezrss.it/0.1/dtd/">
|
|
||||||
<rss version="2.0">
|
|
||||||
<channel>
|
|
||||||
<title>ezRSS - Latest torrent releases</title>
|
|
||||||
<ttl>15</ttl>
|
|
||||||
<link>http://ezrss.it/feed/</link>
|
|
||||||
<image>
|
|
||||||
<title>ezRSS - Latest torrent releases</title>
|
|
||||||
<url>http://ezrss.it/images/ezrssit.png</url>
|
|
||||||
<link>http://ezrss.it/feed/</link>
|
|
||||||
</image>
|
|
||||||
<description>The latest 30 torrent releases.</description>
|
|
||||||
<item>
|
|
||||||
<title><![CDATA[Andy McNabs Tour Of Duty Series 1 - Courage Under Fire 1x6 [DVDRIP - MVGROUP]]]></title>
|
|
||||||
<link>invalid.url</link>
|
|
||||||
<category domain="http://eztv.it/shows/187/mv-group-documentaries/"><![CDATA[TV Show / MV Group Documentaries]]></category>
|
|
||||||
<pubDate>Mon, 15 Sep 2014 13:04:21 -0500</pubDate>
|
|
||||||
<description><![CDATA[Show Name: Andy McNabs Tour Of Duty Series 1; Episode Title: Courage Under Fire; Season: 1; Episode: 6]]></description>
|
|
||||||
<enclosure url="invalid.url" length="698999946" type="application/x-bittorrent" />
|
|
||||||
<comments>http://eztv.it/forum/discuss/58438/</comments>
|
|
||||||
<guid>http://eztv.it/ep/58438/andy-mcnabs-tour-of-duty-series-1-6of6-courage-under-fire-dvdrip-x264-mvgroup/</guid>
|
|
||||||
<torrent xmlns="http://xmlns.ezrss.it/0.1/">
|
|
||||||
<fileName><![CDATA[Andy.McNabs.Tour.Of.Duty.Series.1.6of6.Courage.Under.Fire.DVDRip.x264-MVGroup.[MVGroup.org].torrent]]></fileName>
|
|
||||||
<contentLength>698999946</contentLength>
|
|
||||||
<infoHash>AAA2038BED9EBCA2C312D1C9C3E8E024D0EB414E</infoHash>
|
|
||||||
<magnetURI><![CDATA[magnet:?xt=urn:btih:VKRAHC7NT26KFQYS2HE4H2HAETIOWQKO&dn=Andy.McNabs.Tour.Of.Duty.Series.1.6of6.Courage.Under.Fire.DVDRip.x264-MVGroup]]></magnetURI>
|
|
||||||
</torrent>
|
|
||||||
</item>
|
|
||||||
</channel>
|
|
||||||
</rss>
|
|
|
@ -25,7 +25,7 @@
|
||||||
<br />
|
<br />
|
||||||
<div style="text-align: center;"><span id="lazyload"><span id="350237944_80b24e6a90a69f7bb9b39a6b3f99e4bb">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/195.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/195.jpg" border="0" alt="" onload="TSResizeImage(this, '350237944_80b24e6a90a69f7bb9b39a6b3f99e4bb');" /></a></span></div>
|
<div style="text-align: center;"><span id="lazyload"><span id="350237944_80b24e6a90a69f7bb9b39a6b3f99e4bb">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/195.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/195.jpg" border="0" alt="" onload="TSResizeImage(this, '350237944_80b24e6a90a69f7bb9b39a6b3f99e4bb');" /></a></span></div>
|
||||||
</description>
|
</description>
|
||||||
<link>invalid.url</link>
|
<link></link>
|
||||||
<author>Anonymous</author>
|
<author>Anonymous</author>
|
||||||
<category>TV - High Definition</category>
|
<category>TV - High Definition</category>
|
||||||
<pubDate>2015-02-06 13:32:26</pubDate>
|
<pubDate>2015-02-06 13:32:26</pubDate>
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<rss version="2.0">
|
||||||
|
|
||||||
|
<channel>
|
||||||
|
|
||||||
|
<item>
|
||||||
|
<title>Real.Time.With.Bill.Maher.2015.08.07.720p.HDTV.x264-BATV </title>
|
||||||
|
<guid isPermaLink="true">details/123</guid>
|
||||||
|
<link>getnzb/123.nzb&i=782&r=123</link>
|
||||||
|
<comments>details/123#comments</comments>
|
||||||
|
<pubDate>Sat, 08 Aug 2015 14:27:16 +0100</pubDate>
|
||||||
|
<category>TV > HD</category>
|
||||||
|
<description>Real.Time.With.Bill.Maher.2015.08.07.720p.HDTV.x264-BATV </description>
|
||||||
|
<enclosure url="getnzb/123.nzb&i=123&r=123" length="1230000000" type="application/x-nzb"/>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</channel>
|
||||||
|
</rss>
|
|
@ -1,5 +1,8 @@
|
||||||
using FluentAssertions;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
@ -34,5 +37,25 @@ namespace NzbDrone.Core.Test.IndexerTests
|
||||||
result.Should().Be(0);
|
result.Should().Be(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IndexerResponse CreateResponse(string url, string content)
|
||||||
|
{
|
||||||
|
var httpRequest = new HttpRequest(url);
|
||||||
|
var httpResponse = new HttpResponse(httpRequest, new HttpHeader(), Encoding.UTF8.GetBytes(content));
|
||||||
|
|
||||||
|
return new IndexerResponse(new IndexerRequest(httpRequest), httpResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_handle_relative_url()
|
||||||
|
{
|
||||||
|
var xml = ReadAllText("Files", "Indexers", "relative_urls.xml");
|
||||||
|
|
||||||
|
var result = Subject.ParseResponse(CreateResponse("http://my.indexer.com/api?q=My+Favourite+Show", xml));
|
||||||
|
|
||||||
|
result.Should().HaveCount(1);
|
||||||
|
|
||||||
|
result.First().CommentUrl.Should().Be("http://my.indexer.com/details/123#comments");
|
||||||
|
result.First().DownloadUrl.Should().Be("http://my.indexer.com/getnzb/123.nzb&i=782&r=123");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -194,7 +194,6 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||||
settings.Should().NotBeNull();
|
settings.Should().NotBeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("TorrentRss/invalid/Eztv_InvalidDownloadUrl.xml")]
|
|
||||||
[TestCase("TorrentRss/invalid/ImmortalSeed_InvalidDownloadUrl.xml")]
|
[TestCase("TorrentRss/invalid/ImmortalSeed_InvalidDownloadUrl.xml")]
|
||||||
public void should_reject_recent_feed_with_invalid_downloadurl(string rssXmlFile)
|
public void should_reject_recent_feed_with_invalid_downloadurl(string rssXmlFile)
|
||||||
{
|
{
|
||||||
|
|
|
@ -403,6 +403,9 @@
|
||||||
<Content Include="Files\emptyfile.txt">
|
<Content Include="Files\emptyfile.txt">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="Files\Indexers\relative_urls.xml">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="Files\Indexers\TorrentRss\Doki.xml">
|
<Content Include="Files\Indexers\TorrentRss\Doki.xml">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
@ -410,10 +413,6 @@
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="Files\Indexers\TorrentRss\invalid\Eztv_InvalidDownloadUrl.xml">
|
|
||||||
<SubType>Designer</SubType>
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Files\Indexers\Fanzub\fanzub.xml">
|
<Content Include="Files\Indexers\Fanzub\fanzub.xml">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
|
|
@ -47,12 +47,12 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||||
|
|
||||||
protected override String GetInfoUrl(XElement item)
|
protected override String GetInfoUrl(XElement item)
|
||||||
{
|
{
|
||||||
return item.TryGetValue("comments").TrimEnd("#comments");
|
return ParseUrl(item.TryGetValue("comments").TrimEnd("#comments"));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override String GetCommentUrl(XElement item)
|
protected override String GetCommentUrl(XElement item)
|
||||||
{
|
{
|
||||||
return item.TryGetValue("comments");
|
return ParseUrl(item.TryGetValue("comments"));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Int64 GetSize(XElement item)
|
protected override Int64 GetSize(XElement item)
|
||||||
|
@ -87,7 +87,7 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||||
|
|
||||||
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
|
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
|
||||||
{
|
{
|
||||||
url = item.Element("enclosure").Attribute("url").Value;
|
url = ParseUrl((string)item.Element("enclosure").Attribute("url"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
|
|
|
@ -28,6 +28,8 @@ namespace NzbDrone.Core.Indexers
|
||||||
// Parse "Size: 1.3 GB" or "1.3 GB" parts in the description element and use that as Size.
|
// Parse "Size: 1.3 GB" or "1.3 GB" parts in the description element and use that as Size.
|
||||||
public Boolean ParseSizeInDescription { get; set; }
|
public Boolean ParseSizeInDescription { get; set; }
|
||||||
|
|
||||||
|
private IndexerResponse _indexerResponse;
|
||||||
|
|
||||||
public RssParser()
|
public RssParser()
|
||||||
{
|
{
|
||||||
_logger = NzbDroneLogger.GetLogger(this);
|
_logger = NzbDroneLogger.GetLogger(this);
|
||||||
|
@ -35,6 +37,8 @@ namespace NzbDrone.Core.Indexers
|
||||||
|
|
||||||
public virtual IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
|
public virtual IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
|
||||||
{
|
{
|
||||||
|
_indexerResponse = indexerResponse;
|
||||||
|
|
||||||
var releases = new List<ReleaseInfo>();
|
var releases = new List<ReleaseInfo>();
|
||||||
|
|
||||||
if (!PreProcess(indexerResponse))
|
if (!PreProcess(indexerResponse))
|
||||||
|
@ -168,25 +172,25 @@ namespace NzbDrone.Core.Indexers
|
||||||
{
|
{
|
||||||
if (UseEnclosureUrl)
|
if (UseEnclosureUrl)
|
||||||
{
|
{
|
||||||
return item.Element("enclosure").Attribute("url").Value;
|
return ParseUrl((string)item.Element("enclosure").Attribute("url"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return item.Element("link").Value;
|
return ParseUrl((string)item.Element("link"));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual string GetInfoUrl(XElement item)
|
protected virtual string GetInfoUrl(XElement item)
|
||||||
{
|
{
|
||||||
if (UseGuidInfoUrl)
|
if (UseGuidInfoUrl)
|
||||||
{
|
{
|
||||||
return (String)item.Element("guid");
|
return ParseUrl((string)item.Element("guid"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return String.Empty;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual string GetCommentUrl(XElement item)
|
protected virtual string GetCommentUrl(XElement item)
|
||||||
{
|
{
|
||||||
return (String)item.Element("comments");
|
return ParseUrl((string)item.Element("comments"));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual long GetSize(XElement item)
|
protected virtual long GetSize(XElement item)
|
||||||
|
@ -234,6 +238,31 @@ namespace NzbDrone.Core.Indexers
|
||||||
return channel.Elements("item");
|
return channel.Elements("item");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual string ParseUrl(string value)
|
||||||
|
{
|
||||||
|
if (value.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var uri = new Uri(value, UriKind.RelativeOrAbsolute);
|
||||||
|
|
||||||
|
if (!uri.IsAbsoluteUri)
|
||||||
|
{
|
||||||
|
uri = new Uri(_indexerResponse.HttpRequest.Url, uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
return uri.AbsoluteUri;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.DebugException(string.Format("Failed to parse Uri {0}, ignoring.", value), ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static readonly Regex ParseSizeRegex = new Regex(@"(?<value>(?:\d+,)*\d+(?:\.\d{1,2})?)\W?(?<unit>[KMG]i?B)(?![\w/])",
|
private static readonly Regex ParseSizeRegex = new Regex(@"(?<value>(?:\d+,)*\d+(?:\.\d{1,2})?)\W?(?<unit>[KMG]i?B)(?![\w/])",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
protected virtual String GetMagnetUrl(XElement item)
|
protected virtual String GetMagnetUrl(XElement item)
|
||||||
{
|
{
|
||||||
var downloadUrl = GetDownloadUrl(item);
|
var downloadUrl = GetDownloadUrl(item);
|
||||||
if (downloadUrl.StartsWith("magnet:"))
|
if (downloadUrl.IsNotNullOrWhiteSpace() && downloadUrl.StartsWith("magnet:"))
|
||||||
{
|
{
|
||||||
return downloadUrl;
|
return downloadUrl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,12 +59,12 @@ namespace NzbDrone.Core.Indexers.Torznab
|
||||||
|
|
||||||
protected override String GetInfoUrl(XElement item)
|
protected override String GetInfoUrl(XElement item)
|
||||||
{
|
{
|
||||||
return item.TryGetValue("comments").TrimEnd("#comments");
|
return ParseUrl(item.TryGetValue("comments").TrimEnd("#comments"));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override String GetCommentUrl(XElement item)
|
protected override String GetCommentUrl(XElement item)
|
||||||
{
|
{
|
||||||
return item.TryGetValue("comments");
|
return ParseUrl(item.TryGetValue("comments"));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Int64 GetSize(XElement item)
|
protected override Int64 GetSize(XElement item)
|
||||||
|
@ -93,7 +93,7 @@ namespace NzbDrone.Core.Indexers.Torznab
|
||||||
|
|
||||||
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
|
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
|
||||||
{
|
{
|
||||||
url = item.Element("enclosure").Attribute("url").Value;
|
url = ParseUrl((string)item.Element("enclosure").Attribute("url"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
|
|
Loading…
Reference in New Issue