1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2024-12-14 11:23:42 +02:00

Replaced Uri with HttpUri.

This commit is contained in:
Taloth Saldono 2016-03-01 00:33:28 +01:00
parent 7c54fa70d7
commit 23871503a2
29 changed files with 356 additions and 111 deletions

View File

@ -1,5 +1,6 @@
using System;
using NzbDrone.Api.REST;
using NzbDrone.Common.Http;
using NzbDrone.Core.HealthCheck;
namespace NzbDrone.Api.Health
@ -8,6 +9,6 @@ public class HealthResource : RestResource
{
public HealthCheckResult Type { get; set; }
public string Message { get; set; }
public Uri WikiUrl { get; set; }
public HttpUri WikiUrl { get; set; }
}
}

View File

@ -58,7 +58,7 @@ public void should_execute_typed_get()
var response = Subject.Get<HttpBinResource>(request);
response.Resource.Url.Should().Be(request.Url.AbsoluteUri);
response.Resource.Url.Should().Be(request.Url.FullUri);
}
[Test]

View File

@ -34,7 +34,7 @@ public void should_remove_duplicated_slashes()
var request = builder.Resource("/v1/").Build();
request.Url.AbsoluteUri.Should().Be("http://domain/v1/");
request.Url.FullUri.Should().Be("http://domain/v1/");
}
}

View File

@ -65,7 +65,7 @@ public HttpResponse GetResponse(HttpRequest request, CookieContainer cookies)
return s * n;
};
curlEasy.Url = request.Url.AbsoluteUri;
curlEasy.Url = request.Url.FullUri;
switch (request.Method)
{
case HttpMethod.GET:
@ -98,7 +98,7 @@ public HttpResponse GetResponse(HttpRequest request, CookieContainer cookies)
if (cookies != null)
{
curlEasy.Cookie = cookies.GetCookieHeader(request.Url);
curlEasy.Cookie = cookies.GetCookieHeader((Uri)request.Url);
}
if (request.ContentData != null)
@ -179,7 +179,7 @@ private WebHeaderCollection ProcessHeaderStream(HttpRequest request, CookieConta
{
try
{
cookies.SetCookies(request.Url, FixSetCookieHeader(setCookie));
cookies.SetCookies((Uri)request.Url, FixSetCookieHeader(setCookie));
}
catch (CookieException ex)
{

View File

@ -8,7 +8,7 @@ public class ManagedHttpDispatcher : IHttpDispatcher
{
public HttpResponse GetResponse(HttpRequest request, CookieContainer cookies)
{
var webRequest = (HttpWebRequest)WebRequest.Create(request.Url);
var webRequest = (HttpWebRequest)WebRequest.Create((Uri)request.Url);
// Deflate is not a standard and could break depending on implementation.
// we should just stick with the more compatible Gzip

View File

@ -125,7 +125,7 @@ private CookieContainer PrepareRequestCookies(HttpRequest request)
}
}
var requestCookies = persistentCookieContainer.GetCookies(request.Url);
var requestCookies = persistentCookieContainer.GetCookies((Uri)request.Url);
var cookieContainer = new CookieContainer();
@ -146,7 +146,7 @@ private void HandleResponseCookies(HttpRequest request, CookieContainer cookieCo
{
var persistentCookieContainer = _cookieContainerCache.Get("container", () => new CookieContainer());
var cookies = cookieContainer.GetCookies(request.Url);
var cookies = cookieContainer.GetCookies((Uri)request.Url);
persistentCookieContainer.Add(cookies);
}

View File

@ -8,7 +8,7 @@ public class HttpException : Exception
public HttpResponse Response { get; private set; }
public HttpException(HttpRequest request, HttpResponse response)
: base(string.Format("HTTP request failed: [{0}:{1}] [{2}] at [{3}]", (int)response.StatusCode, response.StatusCode, request.Method, request.Url.AbsoluteUri))
: base(string.Format("HTTP request failed: [{0}:{1}] [{2}] at [{3}]", (int)response.StatusCode, response.StatusCode, request.Method, request.Url))
{
Request = request;
Response = response;

View File

@ -10,9 +10,9 @@ namespace NzbDrone.Common.Http
{
public class HttpRequest
{
public HttpRequest(string uri, HttpAccept httpAccept = null)
public HttpRequest(string url, HttpAccept httpAccept = null)
{
UrlBuilder = new UriBuilder(uri);
Url = new HttpUri(url);
Headers = new HttpHeader();
AllowAutoRedirect = true;
Cookies = new Dictionary<string, string>();
@ -28,8 +28,7 @@ public HttpRequest(string uri, HttpAccept httpAccept = null)
}
}
public UriBuilder UrlBuilder { get; private set; }
public Uri Url { get { return UrlBuilder.Uri; } }
public HttpUri Url { get; set; }
public HttpMethod Method { get; set; }
public HttpHeader Headers { get; set; }
public byte[] ContentData { get; set; }

View File

@ -12,7 +12,7 @@ public class HttpRequestBuilder
{
public HttpMethod Method { get; set; }
public HttpAccept HttpAccept { get; set; }
public Uri BaseUrl { get; private set; }
public HttpUri BaseUrl { get; private set; }
public string ResourceUrl { get; set; }
public List<KeyValuePair<string, string>> QueryParams { get; private set; }
public List<KeyValuePair<string, string>> SuffixQueryParams { get; private set; }
@ -28,7 +28,7 @@ public class HttpRequestBuilder
public HttpRequestBuilder(string baseUrl)
{
BaseUrl = new Uri(baseUrl);
BaseUrl = new HttpUri(baseUrl);
ResourceUrl = string.Empty;
Method = HttpMethod.GET;
QueryParams = new List<KeyValuePair<string, string>>();
@ -69,33 +69,28 @@ public virtual HttpRequestBuilder Clone()
return clone;
}
protected virtual Uri CreateUri()
protected virtual HttpUri CreateUri()
{
var builder = new UriBuilder(new Uri(BaseUrl, ResourceUrl));
var url = BaseUrl.CombinePath(ResourceUrl).AddQueryParams(QueryParams.Concat(SuffixQueryParams));
foreach (var queryParam in QueryParams.Concat(SuffixQueryParams))
{
builder.SetQueryParam(queryParam.Key, queryParam.Value);
}
if (Segments.Any())
{
var url = builder.Uri.ToString();
var fullUri = url.FullUri;
foreach (var segment in Segments)
{
url = url.Replace(segment.Key, segment.Value);
fullUri = fullUri.Replace(segment.Key, segment.Value);
}
builder = new UriBuilder(url);
url = new HttpUri(fullUri);
}
return builder.Uri;
return url;
}
protected virtual HttpRequest CreateRequest()
{
return new HttpRequest(CreateUri().ToString(), HttpAccept);
return new HttpRequest(CreateUri().FullUri, HttpAccept);
}
protected virtual void Apply(HttpRequest request)

View File

@ -0,0 +1,261 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using NzbDrone.Common.Extensions;
namespace NzbDrone.Common.Http
{
public class HttpUri : IEquatable<HttpUri>
{
private static readonly Regex RegexUri = new Regex(@"^(?:(?<scheme>[a-z]+):)?(?://(?<host>[-A-Z0-9.]+)(?::(?<port>[0-9]{1,5}))?)?(?<path>(?:(?:(?<=^)|/)[^/?#\r\n]+)+/?|/)?(?:\?(?<query>[^#\r\n]*))?(?:\#(?<fragment>.*))?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private readonly string _uri;
public string FullUri { get { return _uri; } }
public HttpUri(string uri)
{
_uri = uri ?? string.Empty;
Parse();
}
public HttpUri(string scheme, string host, int? port, string path, string query, string fragment)
{
StringBuilder builder = new StringBuilder();
if (scheme.IsNotNullOrWhiteSpace())
{
builder.Append(scheme);
builder.Append(":");
}
if (host.IsNotNullOrWhiteSpace())
{
builder.Append("//");
builder.Append(host);
if (port.HasValue)
{
builder.Append(":");
builder.Append(port);
}
}
if (path.IsNotNullOrWhiteSpace())
{
if (host.IsNotNullOrWhiteSpace() || path.StartsWith("/"))
{
builder.Append('/');
}
builder.Append(path.TrimStart('/'));
}
if (query.IsNotNullOrWhiteSpace())
{
builder.Append('?');
builder.Append(query);
}
if (fragment.IsNotNullOrWhiteSpace())
{
builder.Append('#');
builder.Append(fragment);
}
_uri = builder.ToString();
Parse();
}
private void Parse()
{
var match = RegexUri.Match(_uri);
var scheme = match.Groups["scheme"];
var host = match.Groups["host"];
var port = match.Groups["port"];
var path = match.Groups["path"];
var query = match.Groups["query"];
var fragment = match.Groups["fragment"];
if (!match.Success || scheme.Success && !host.Success && path.Success)
{
throw new ArgumentException("Uri didn't match expected pattern: " + _uri);
}
Scheme = scheme.Value;
Host = host.Value;
Port = port.Success ? (int?)int.Parse(port.Value) : null;
Path = path.Value;
Query = query.Value;
Fragment = fragment.Value;
}
public string Scheme { get; private set; }
public string Host { get; private set; }
public int? Port { get; private set; }
public string Path { get; private set; }
public string Query { get; private set; }
public string Fragment { get; private set; }
private IList<KeyValuePair<string, string>> _queryParams;
private IList<KeyValuePair<string, string>> QueryParams
{
get
{
if (_queryParams == null)
{
var dict = new List<KeyValuePair<string, string>>();
if (Query.IsNotNullOrWhiteSpace())
{
foreach (var pair in Query.Split('&'))
{
var split = pair.Split(new[] { '=' }, 2);
if (split.Length == 1)
{
dict.Add(new KeyValuePair<string, string>(Uri.UnescapeDataString(split[0]), null));
}
else
{
dict.Add(new KeyValuePair<string, string>(Uri.UnescapeDataString(split[0]), Uri.UnescapeDataString(split[1])));
}
}
}
_queryParams = dict.AsReadOnly();
}
return _queryParams;
}
}
public HttpUri CombinePath(string path)
{
return new HttpUri(Scheme, Host, Port, CombinePath(Path, path), Query, Fragment);
}
private static string CombinePath(string basePath, string relativePath)
{
if (relativePath.IsNullOrWhiteSpace())
{
return basePath;
}
var newPath = "/" + relativePath.TrimStart('/');
if (basePath != null && !relativePath.StartsWith("/"))
{
var baseSlashIndex = basePath.LastIndexOf('/');
if (baseSlashIndex == basePath.Length - 1)
{
newPath = basePath.TrimEnd('/') + newPath;
}
else if (baseSlashIndex != 0)
{
newPath = basePath.Substring(0, baseSlashIndex) + newPath;
}
}
return newPath;
}
public HttpUri SetQuery(string query)
{
return new HttpUri(Scheme, Host, Port, Path, query, Fragment);
}
public HttpUri AddQueryParam(string key, object value)
{
var newQuery = string.Concat(Uri.EscapeDataString(key), "=", Uri.EscapeDataString(value.ToString()));
if (Query.IsNotNullOrWhiteSpace())
{
newQuery = string.Concat(Query, "&", newQuery);
}
return SetQuery(newQuery);
}
public HttpUri AddQueryParams(IEnumerable<KeyValuePair<string, string>> queryParams)
{
var builder = new StringBuilder();
builder.Append(Query);
foreach (var pair in queryParams)
{
if (builder.Length != 0)
{
builder.Append("&");
}
builder.Append(Uri.EscapeDataString(pair.Key));
builder.Append("=");
builder.Append(Uri.EscapeDataString(pair.Value));
}
return SetQuery(builder.ToString());
}
public override int GetHashCode()
{
return _uri.GetHashCode();
}
public override string ToString()
{
return _uri;
}
public override bool Equals(object obj)
{
if (obj is string)
{
return _uri.Equals((string)obj);
}
else if (obj is Uri)
{
return _uri.Equals(((Uri)obj).OriginalString);
}
else
{
return Equals(obj as HttpUri);
}
}
public bool Equals(HttpUri other)
{
if (object.ReferenceEquals(other, null)) return false;
return _uri.Equals(other._uri);
}
public static explicit operator Uri(HttpUri url)
{
return new Uri(url.FullUri);
}
public static HttpUri operator +(HttpUri baseUrl, HttpUri relativeUrl)
{
if (relativeUrl.Scheme.IsNotNullOrWhiteSpace())
{
return relativeUrl;
}
if (relativeUrl.Host.IsNotNullOrWhiteSpace())
{
return new HttpUri(baseUrl.Scheme, relativeUrl.Host, relativeUrl.Port, relativeUrl.Path, relativeUrl.Query, relativeUrl.Fragment);
}
if (relativeUrl.Path.IsNotNullOrWhiteSpace())
{
return new HttpUri(baseUrl.Scheme, baseUrl.Host, baseUrl.Port, HttpUri.CombinePath(baseUrl.Path, relativeUrl.Path), relativeUrl.Query, relativeUrl.Fragment);
}
return new HttpUri(baseUrl.Scheme, baseUrl.Host, baseUrl.Port, baseUrl.Path, relativeUrl.Query, relativeUrl.Fragment);
}
}
}

View File

@ -1,20 +0,0 @@
using System;
using NzbDrone.Common.Extensions;
namespace NzbDrone.Common.Http
{
public static class UriExtensions
{
public static void SetQueryParam(this UriBuilder uriBuilder, string key, object value)
{
var query = uriBuilder.Query;
if (query.IsNotNullOrWhiteSpace())
{
query += "&";
}
uriBuilder.Query = query.Trim('?') + key + "=" + Uri.EscapeDataString(value.ToString());
}
}
}

View File

@ -162,6 +162,7 @@
<Compile Include="Http\HttpProvider.cs" />
<Compile Include="Http\HttpRequest.cs" />
<Compile Include="Http\HttpResponse.cs" />
<Compile Include="Http\HttpUri.cs" />
<Compile Include="Http\IHttpRequestInterceptor.cs" />
<Compile Include="Http\JsonRpcRequestBuilder.cs" />
<Compile Include="Http\JsonRpcResponse.cs" />
@ -171,7 +172,6 @@
<Compile Include="Http\HttpRequestBuilder.cs" />
<Compile Include="Http\HttpRequestBuilderFactory.cs" />
<Compile Include="Http\TooManyRequestsException.cs" />
<Compile Include="Http\UriExtensions.cs" />
<Compile Include="Extensions\IEnumerableExtensions.cs" />
<Compile Include="Http\UserAgentBuilder.cs" />
<Compile Include="Instrumentation\CleanseLogMessage.cs" />
@ -197,6 +197,7 @@
<Compile Include="Reflection\ReflectionExtensions.cs" />
<Compile Include="Extensions\ResourceExtensions.cs" />
<Compile Include="Security\X509CertificateValidationPolicy.cs" />
<Compile Include="Serializer\HttpUriConverter.cs" />
<Compile Include="Serializer\IntConverter.cs" />
<Compile Include="Serializer\Json.cs" />
<Compile Include="ServiceFactory.cs" />

View File

@ -0,0 +1,31 @@
using System;
using Newtonsoft.Json;
using NzbDrone.Common.Http;
namespace NzbDrone.Common.Serializer
{
public class HttpUriConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
}
else if (value is HttpUri)
{
writer.WriteValue((value as HttpUri).FullUri);
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return new HttpUri(reader.ReadAsString());
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(HttpUri);
}
}
}

View File

@ -26,6 +26,7 @@ static Json()
SerializerSetting.Converters.Add(new StringEnumConverter { CamelCaseText = true });
//SerializerSetting.Converters.Add(new IntConverter());
SerializerSetting.Converters.Add(new VersionConverter());
SerializerSetting.Converters.Add(new HttpUriConverter());
Serializer = JsonSerializer.Create(SerializerSetting);

View File

@ -112,7 +112,7 @@ public void Download_should_download_file_if_it_doesnt_exist()
Subject.Download(remoteEpisode);
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.AbsoluteUri == _downloadUrl)), Times.Once());
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_filePath), Times.Once());
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
}
@ -128,7 +128,7 @@ public void Download_should_replace_illegal_characters_in_title()
Subject.Download(remoteEpisode);
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.AbsoluteUri == _downloadUrl)), Times.Once());
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(expectedFilename), Times.Once());
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
}

View File

@ -93,7 +93,7 @@ public void Download_should_download_file_if_it_doesnt_exist()
Subject.Download(remoteEpisode);
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.AbsoluteUri == _downloadUrl)), Times.Once());
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_filePath), Times.Once());
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
}
@ -109,7 +109,7 @@ public void Download_should_replace_illegal_characters_in_title()
Subject.Download(remoteEpisode);
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.AbsoluteUri == _downloadUrl)), Times.Once());
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(expectedFilename), Times.Once());
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
}

View File

@ -53,7 +53,7 @@ protected void GivenRedirectToTorrent()
httpHeader["Location"] = "http://test.sonarr.tv/not-a-real-torrent.torrent";
Mocker.GetMock<IHttpClient>()
.Setup(s => s.Get(It.Is<HttpRequest>(h => h.Url.AbsoluteUri == _downloadUrl)))
.Setup(s => s.Get(It.Is<HttpRequest>(h => h.Url.FullUri == _downloadUrl)))
.Returns<HttpRequest>(r => new HttpResponse(r, httpHeader, new Byte[0], System.Net.HttpStatusCode.Found));
}

View File

@ -20,7 +20,7 @@ public void should_remove_query_params_from_torcache_request()
var newRequest = Subject.PreRequest(request);
newRequest.Url.AbsoluteUri.Should().Be("http://torcache.net/download/123.torrent");
newRequest.Url.FullUri.Should().Be("http://torcache.net/download/123.torrent");
}
[Test]
@ -41,7 +41,7 @@ public void should_not_remove_query_params_from_other_requests(string url)
var newRequest = Subject.PreRequest(request);
newRequest.Url.AbsoluteUri.Should().Be(url);
newRequest.Url.FullUri.Should().Be(url);
}
}
}

View File

@ -71,7 +71,7 @@ public void should_not_have_duplicate_categories()
var page = results.GetAllTiers().First().First();
page.Url.Query.Should().Contain("&cat=1,2,3,4&");
page.Url.FullUri.Should().Contain("&cat=1,2,3,4&");
}
[Test]
@ -83,7 +83,7 @@ public void should_use_only_anime_categories_for_anime_search()
var page = results.GetAllTiers().First().First();
page.Url.Query.Should().Contain("&cat=3,4&");
page.Url.FullUri.Should().Contain("&cat=3,4&");
}
[Test]
@ -95,7 +95,7 @@ public void should_use_mode_search_for_anime()
var page = results.GetAllTiers().First().First();
page.Url.Query.Should().Contain("?t=search&");
page.Url.FullUri.Should().Contain("?t=search&");
}
[Test]
@ -107,9 +107,9 @@ public void should_return_subsequent_pages()
var pages = results.GetAllTiers().First().Take(3).ToList();
pages[0].Url.Query.Should().Contain("&offset=0&");
pages[1].Url.Query.Should().Contain("&offset=100&");
pages[2].Url.Query.Should().Contain("&offset=200&");
pages[0].Url.FullUri.Should().Contain("&offset=0&");
pages[1].Url.FullUri.Should().Contain("&offset=100&");
pages[2].Url.FullUri.Should().Contain("&offset=200&");
}
[Test]

View File

@ -56,8 +56,8 @@ public void DownloadReport(RemoteEpisode remoteEpisode)
// Limit grabs to 2 per second.
if (remoteEpisode.Release.DownloadUrl.IsNotNullOrWhiteSpace() && !remoteEpisode.Release.DownloadUrl.StartsWith("magnet:"))
{
var uri = new Uri(remoteEpisode.Release.DownloadUrl);
_rateLimitService.WaitAndPulse(uri.Host, TimeSpan.FromSeconds(2));
var url = new HttpUri(remoteEpisode.Release.DownloadUrl);
_rateLimitService.WaitAndPulse(url.Host, TimeSpan.FromSeconds(2));
}
string downloadClientId;

View File

@ -1,5 +1,6 @@
using System;
using System.Text.RegularExpressions;
using NzbDrone.Common.Http;
using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.HealthCheck
@ -11,7 +12,7 @@ public class HealthCheck : ModelBase
public Type Source { get; set; }
public HealthCheckResult Type { get; set; }
public string Message { get; set; }
public Uri WikiUrl { get; set; }
public HttpUri WikiUrl { get; set; }
public HealthCheck(Type source)
{
@ -32,19 +33,9 @@ private static string MakeWikiFragment(string message)
return "#" + CleanFragmentRegex.Replace(message.ToLower(), string.Empty).Replace(' ', '-');
}
private static Uri MakeWikiUrl(string fragment)
private static HttpUri MakeWikiUrl(string fragment)
{
var rootUri = new Uri("https://github.com/Sonarr/Sonarr/wiki/Health-checks");
if (fragment.StartsWith("#"))
{ // Mono doesn't understand # and generates a different url than windows.
return new Uri(rootUri + fragment);
}
else
{
var fragmentUri = new Uri(fragment, UriKind.Relative);
return new Uri(rootUri, fragmentUri);
}
return new HttpUri("https://github.com/Sonarr/Sonarr/wiki/Health-checks") + new HttpUri(fragment);
}
}

View File

@ -13,9 +13,9 @@ public HttpRequest PreRequest(HttpRequest request)
{
// torcache behaves strangely when it has query params and/or no Referer or browser User-Agent.
// It's a bit vague, and we don't need the query params. So we remove the query params and set a Referer to be safe.
if (request.UrlBuilder.Host == "torcache.net")
if (request.Url.Host == "torcache.net")
{
request.UrlBuilder.Query = string.Empty;
request.Url = request.Url.SetQuery(string.Empty);
request.Headers.Add("Referer", request.Url.Scheme + @"://torcache.net/");
}

View File

@ -5,6 +5,7 @@
using System.Web;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NzbDrone.Common.Http;
using NzbDrone.Core.Indexers.Exceptions;
using NzbDrone.Core.Parser.Model;
@ -71,33 +72,22 @@ public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
private string GetDownloadUrl(long torrentId)
{
var args = new NameValueCollection(2);
args["id"] = torrentId.ToString();
args["passkey"] = _settings.ApiKey;
var url = new HttpUri(_settings.BaseUrl)
.CombinePath("/download.php")
.AddQueryParam("id", torrentId.ToString())
.AddQueryParam("passkey", _settings.ApiKey);
return BuildUrl("/download.php", args);
return url.FullUri;
}
private string GetInfoUrl(long torrentId)
{
var args = new NameValueCollection(1);
args["id"] = torrentId.ToString();
var url = new HttpUri(_settings.BaseUrl)
.CombinePath("/details.php")
.AddQueryParam("id", torrentId.ToString());
return BuildUrl("/details.php", args);
return url.FullUri;
}
private string BuildUrl(string path, NameValueCollection args)
{
var builder = new UriBuilder(_settings.BaseUrl);
builder.Path = path;
var queryString = HttpUtility.ParseQueryString("");
queryString.Add(args);
builder.Query = queryString.ToString();
return builder.Uri.ToString();
}
}
}

View File

@ -137,7 +137,7 @@ protected virtual IList<ReleaseInfo> FetchReleases(IndexerPageableRequestChain p
foreach (var request in pageableRequest)
{
url = request.Url.AbsoluteUri;
url = request.Url.FullUri;
var page = FetchPage(request, parser);

View File

@ -17,7 +17,7 @@ public IndexerRequest(HttpRequest httpRequest)
HttpRequest = httpRequest;
}
public Uri Url
public HttpUri Url
{
get { return HttpRequest.Url; }
}

View File

@ -27,7 +27,7 @@ protected override bool PreProcess(IndexerResponse indexerResponse)
throw new ApiKeyException("Invalid API key");
}
if (!indexerResponse.Request.Url.AbsoluteUri.Contains("apikey=") && (errorMessage == "Missing parameter" || errorMessage.Contains("apikey")))
if (!indexerResponse.Request.Url.FullUri.Contains("apikey=") && (errorMessage == "Missing parameter" || errorMessage.Contains("apikey")))
{
throw new ApiKeyException("Indexer requires an API key");
}

View File

@ -9,6 +9,7 @@
using System.Xml.Linq;
using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Core.Indexers.Exceptions;
using NzbDrone.Core.Parser.Model;
@ -266,14 +267,9 @@ protected virtual string ParseUrl(string value)
try
{
var url = new Uri(value, UriKind.RelativeOrAbsolute);
var url = _indexerResponse.HttpRequest.Url + new HttpUri(value);
if (!url.IsAbsoluteUri)
{
url = new Uri(_indexerResponse.HttpRequest.Url, url);
}
return url.AbsoluteUri;
return url.FullUri;
}
catch (Exception ex)
{

View File

@ -23,7 +23,7 @@ protected override bool PreProcess(IndexerResponse indexerResponse)
if (code >= 100 && code <= 199) throw new ApiKeyException("Invalid API key");
if (!indexerResponse.Request.Url.AbsoluteUri.Contains("apikey=") && errorMessage == "Missing parameter")
if (!indexerResponse.Request.Url.FullUri.Contains("apikey=") && errorMessage == "Missing parameter")
{
throw new ApiKeyException("Indexer requires an API key");
}

View File

@ -84,7 +84,6 @@ public List<Series> SearchForNewSeries(string title)
}
}
var term = System.Web.HttpUtility.UrlEncode((title.ToLower().Trim()));
var httpRequest = _requestBuilder.Create()
.SetSegment("route", "search")
.AddQueryParam("term", title.ToLower().Trim())