mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
New: IPv6 support for connections/indexers/download clients
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
@@ -10,6 +10,7 @@ namespace NzbDrone.Common.Test.Http
|
|||||||
[TestCase("abc://my_host.com:8080/root/api/")]
|
[TestCase("abc://my_host.com:8080/root/api/")]
|
||||||
[TestCase("abc://my_host.com:8080//root/api/")]
|
[TestCase("abc://my_host.com:8080//root/api/")]
|
||||||
[TestCase("abc://my_host.com:8080/root//api/")]
|
[TestCase("abc://my_host.com:8080/root//api/")]
|
||||||
|
[TestCase("abc://[::1]:8080/root//api/")]
|
||||||
public void should_parse(string uri)
|
public void should_parse(string uri)
|
||||||
{
|
{
|
||||||
var newUri = new HttpUri(uri);
|
var newUri = new HttpUri(uri);
|
||||||
|
@@ -252,5 +252,10 @@ namespace NzbDrone.Common.Extensions
|
|||||||
|
|
||||||
return parsedAddress.AddressFamily == AddressFamily.InterNetwork || parsedAddress.AddressFamily == AddressFamily.InterNetworkV6;
|
return parsedAddress.AddressFamily == AddressFamily.InterNetwork || parsedAddress.AddressFamily == AddressFamily.InterNetworkV6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string ToUrlHost(this string input)
|
||||||
|
{
|
||||||
|
return input.Contains(":") ? $"[{input}]" : input;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,7 @@ namespace NzbDrone.Common.Http
|
|||||||
{
|
{
|
||||||
public class HttpUri : IEquatable<HttpUri>
|
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 static readonly Regex RegexUri = new Regex(@"^(?:(?<scheme>[a-z]+):)?(?://(?<host>[-_A-Z0-9.]+|\[[[A-F0-9:]+\])(?::(?<port>[0-9]{1,5}))?)?(?<path>(?:(?:(?<=^)|/+)[^/?#\r\n]+)+/*|/+)?(?:\?(?<query>[^#\r\n]*))?(?:\#(?<fragment>.*))?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
private readonly string _uri;
|
private readonly string _uri;
|
||||||
public string FullUri => _uri;
|
public string FullUri => _uri;
|
||||||
@@ -70,6 +70,8 @@ namespace NzbDrone.Common.Http
|
|||||||
|
|
||||||
private void Parse()
|
private void Parse()
|
||||||
{
|
{
|
||||||
|
var parseSuccess = Uri.TryCreate(_uri, UriKind.RelativeOrAbsolute, out var uri);
|
||||||
|
|
||||||
var match = RegexUri.Match(_uri);
|
var match = RegexUri.Match(_uri);
|
||||||
|
|
||||||
var scheme = match.Groups["scheme"];
|
var scheme = match.Groups["scheme"];
|
||||||
@@ -79,7 +81,7 @@ namespace NzbDrone.Common.Http
|
|||||||
var query = match.Groups["query"];
|
var query = match.Groups["query"];
|
||||||
var fragment = match.Groups["fragment"];
|
var fragment = match.Groups["fragment"];
|
||||||
|
|
||||||
if (!match.Success || (scheme.Success && !host.Success && path.Success))
|
if (!parseSuccess || (scheme.Success && !host.Success && path.Success))
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Uri didn't match expected pattern: " + _uri);
|
throw new ArgumentException("Uri didn't match expected pattern: " + _uri);
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,15 @@
|
|||||||
|
using System;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using FluentValidation.Validators;
|
using FluentValidation.Validators;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Validation
|
namespace NzbDrone.Core.Validation
|
||||||
{
|
{
|
||||||
public static class RuleBuilderExtensions
|
public static class RuleBuilderExtensions
|
||||||
{
|
{
|
||||||
|
private static readonly Regex HostRegex = new Regex("^[-_a-z0-9.]+$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||||
|
|
||||||
public static IRuleBuilderOptions<T, int> ValidId<T>(this IRuleBuilder<T, int> ruleBuilder)
|
public static IRuleBuilderOptions<T, int> ValidId<T>(this IRuleBuilder<T, int> ruleBuilder)
|
||||||
{
|
{
|
||||||
return ruleBuilder.SetValidator(new GreaterThanValidator(0));
|
return ruleBuilder.SetValidator(new GreaterThanValidator(0));
|
||||||
@@ -24,13 +28,15 @@ namespace NzbDrone.Core.Validation
|
|||||||
public static IRuleBuilderOptions<T, string> ValidHost<T>(this IRuleBuilder<T, string> ruleBuilder)
|
public static IRuleBuilderOptions<T, string> ValidHost<T>(this IRuleBuilder<T, string> ruleBuilder)
|
||||||
{
|
{
|
||||||
ruleBuilder.SetValidator(new NotEmptyValidator(null));
|
ruleBuilder.SetValidator(new NotEmptyValidator(null));
|
||||||
return ruleBuilder.SetValidator(new RegularExpressionValidator("^[-_a-z0-9.]+$", RegexOptions.IgnoreCase)).WithMessage("must be valid Host without http://");
|
|
||||||
|
return ruleBuilder.Must(x => HostRegex.IsMatch(x) || x.IsValidIpAddress()).WithMessage("must be valid Host without http://");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IRuleBuilderOptions<T, string> ValidRootUrl<T>(this IRuleBuilder<T, string> ruleBuilder)
|
public static IRuleBuilderOptions<T, string> ValidRootUrl<T>(this IRuleBuilder<T, string> ruleBuilder)
|
||||||
{
|
{
|
||||||
ruleBuilder.SetValidator(new NotEmptyValidator(null));
|
ruleBuilder.SetValidator(new NotEmptyValidator(null));
|
||||||
return ruleBuilder.SetValidator(new RegularExpressionValidator("^https?://[-_a-z0-9.]+", RegexOptions.IgnoreCase)).WithMessage("must be valid URL that starts with http(s)://");
|
|
||||||
|
return ruleBuilder.Must(x => x.IsValidUrl() && x.StartsWith("http", StringComparison.InvariantCultureIgnoreCase)).WithMessage("must be valid URL that starts with http(s)://");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IRuleBuilderOptions<T, string> ValidUrlBase<T>(this IRuleBuilder<T, string> ruleBuilder, string example = "/sonarr")
|
public static IRuleBuilderOptions<T, string> ValidUrlBase<T>(this IRuleBuilder<T, string> ruleBuilder, string example = "/sonarr")
|
||||||
|
Reference in New Issue
Block a user