mirror of https://github.com/Squidex/squidex.git
75 changed files with 287 additions and 1182 deletions
@ -1,20 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
|
|
||||
namespace Microsoft.Extensions.Configuration |
|
||||
{ |
|
||||
public sealed class Alternatives : Dictionary<string, Action> |
|
||||
{ |
|
||||
public Alternatives() |
|
||||
: base(StringComparer.OrdinalIgnoreCase) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,70 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Globalization; |
|
||||
using System.Linq; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Squidex.Text; |
|
||||
|
|
||||
namespace Microsoft.Extensions.Configuration |
|
||||
{ |
|
||||
public static class ConfigurationExtensions |
|
||||
{ |
|
||||
public static T GetOptionalValue<T>(this IConfiguration config, string path, T defaultValue = default) |
|
||||
{ |
|
||||
var value = config.GetValue(path, defaultValue!); |
|
||||
|
|
||||
return value; |
|
||||
} |
|
||||
|
|
||||
public static int GetOptionalValue(this IConfiguration config, string path, int defaultValue) |
|
||||
{ |
|
||||
var value = config.GetValue<string>(path); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(value) || !int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) |
|
||||
{ |
|
||||
result = defaultValue; |
|
||||
} |
|
||||
|
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
public static string GetRequiredValue(this IConfiguration config, string path) |
|
||||
{ |
|
||||
var value = config.GetValue<string>(path); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(value)) |
|
||||
{ |
|
||||
var name = string.Join(" ", path.Split(':').Select(x => x.ToPascalCase())); |
|
||||
|
|
||||
throw new ConfigurationException($"Configure the {name} with '{path}'."); |
|
||||
} |
|
||||
|
|
||||
return value; |
|
||||
} |
|
||||
|
|
||||
public static string ConfigureByOption(this IConfiguration config, string path, Alternatives options) |
|
||||
{ |
|
||||
var value = config.GetRequiredValue(path); |
|
||||
|
|
||||
if (options.TryGetValue(value, out var action)) |
|
||||
{ |
|
||||
action(); |
|
||||
} |
|
||||
else if (options.TryGetValue("default", out action)) |
|
||||
{ |
|
||||
action(); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
throw new ConfigurationException($"Unsupported value '{value}' for '{path}', supported: {string.Join(" ", options.Keys)}."); |
|
||||
} |
|
||||
|
|
||||
return value; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,26 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using System.Runtime.Serialization; |
|
||||
|
|
||||
namespace Squidex.Infrastructure |
|
||||
{ |
|
||||
[Serializable] |
|
||||
public class ConfigurationException : Exception |
|
||||
{ |
|
||||
public ConfigurationException(string message, Exception? inner = null) |
|
||||
: base(message, inner) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
protected ConfigurationException(SerializationInfo info, StreamingContext context) |
|
||||
: base(info, context) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,38 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using System.Threading; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
namespace Squidex.Infrastructure |
|
||||
{ |
|
||||
public sealed class DelegateInitializer : IInitializable |
|
||||
{ |
|
||||
private readonly string name; |
|
||||
private readonly Func<CancellationToken, Task> action; |
|
||||
|
|
||||
public DelegateInitializer(string name, Func<CancellationToken, Task> action) |
|
||||
{ |
|
||||
Guard.NotNull(action, nameof(action)); |
|
||||
|
|
||||
this.name = name; |
|
||||
|
|
||||
this.action = action; |
|
||||
} |
|
||||
|
|
||||
public override string ToString() |
|
||||
{ |
|
||||
return name; |
|
||||
} |
|
||||
|
|
||||
public Task InitializeAsync(CancellationToken ct = default) |
|
||||
{ |
|
||||
return action(ct); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,110 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using System.Linq; |
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|
||||
using Squidex.Infrastructure; |
|
||||
|
|
||||
namespace Microsoft.Extensions.DependencyInjection |
|
||||
{ |
|
||||
public static class DependencyInjectionExtensions |
|
||||
{ |
|
||||
public delegate void Registrator(Type serviceType, Func<IServiceProvider, object> implementationFactory); |
|
||||
|
|
||||
public sealed class InterfaceRegistrator<T> where T : notnull |
|
||||
{ |
|
||||
private readonly Registrator register; |
|
||||
private readonly Registrator registerOptional; |
|
||||
|
|
||||
public InterfaceRegistrator(Registrator register, Registrator registerOptional) |
|
||||
{ |
|
||||
this.register = register; |
|
||||
this.registerOptional = registerOptional; |
|
||||
|
|
||||
var interfaces = typeof(T).GetInterfaces(); |
|
||||
|
|
||||
if (interfaces.Contains(typeof(IInitializable))) |
|
||||
{ |
|
||||
register(typeof(IInitializable), c => c.GetRequiredService<T>()); |
|
||||
} |
|
||||
|
|
||||
if (interfaces.Contains(typeof(IBackgroundProcess))) |
|
||||
{ |
|
||||
register(typeof(IBackgroundProcess), c => c.GetRequiredService<T>()); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public InterfaceRegistrator<T> AsSelf() |
|
||||
{ |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public InterfaceRegistrator<T> AsOptional<TInterface>() |
|
||||
{ |
|
||||
if (typeof(TInterface) != typeof(T)) |
|
||||
{ |
|
||||
registerOptional(typeof(TInterface), c => c.GetRequiredService<T>()); |
|
||||
} |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public InterfaceRegistrator<T> As<TInterface>() |
|
||||
{ |
|
||||
if (typeof(TInterface) != typeof(T)) |
|
||||
{ |
|
||||
register(typeof(TInterface), c => c.GetRequiredService<T>()); |
|
||||
} |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public static InterfaceRegistrator<T> AddTransientAs<T>(this IServiceCollection services, Func<IServiceProvider, T> factory) where T : class |
|
||||
{ |
|
||||
services.AddTransient(typeof(T), factory); |
|
||||
|
|
||||
return new InterfaceRegistrator<T>((t, f) => services.AddTransient(t, f), services.TryAddTransient); |
|
||||
} |
|
||||
|
|
||||
public static InterfaceRegistrator<T> AddTransientAs<T>(this IServiceCollection services) where T : class |
|
||||
{ |
|
||||
services.AddTransient<T, T>(); |
|
||||
|
|
||||
return new InterfaceRegistrator<T>((t, f) => services.AddTransient(t, f), services.TryAddTransient); |
|
||||
} |
|
||||
|
|
||||
public static InterfaceRegistrator<T> AddSingletonAs<T>(this IServiceCollection services, Func<IServiceProvider, T> factory) where T : class |
|
||||
{ |
|
||||
services.AddSingleton(typeof(T), factory); |
|
||||
|
|
||||
return new InterfaceRegistrator<T>((t, f) => services.AddSingleton(t, f), services.TryAddSingleton); |
|
||||
} |
|
||||
|
|
||||
public static InterfaceRegistrator<T> AddSingletonAs<T>(this IServiceCollection services) where T : class |
|
||||
{ |
|
||||
services.AddSingleton<T, T>(); |
|
||||
|
|
||||
return new InterfaceRegistrator<T>((t, f) => services.AddSingleton(t, f), services.TryAddSingleton); |
|
||||
} |
|
||||
|
|
||||
public static InterfaceRegistrator<T> AddScopedAs<T>(this IServiceCollection services, Func<IServiceProvider, T> factory) where T : class |
|
||||
{ |
|
||||
services.AddScoped(typeof(T), factory); |
|
||||
|
|
||||
return new InterfaceRegistrator<T>((t, f) => services.AddScoped(t, f), services.TryAddScoped); |
|
||||
} |
|
||||
|
|
||||
public static InterfaceRegistrator<T> AddScopedAs<T>(this IServiceCollection services) where T : class |
|
||||
{ |
|
||||
services.AddScoped<T, T>(); |
|
||||
|
|
||||
return new InterfaceRegistrator<T>((t, f) => services.AddScoped(t, f), services.TryAddScoped); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,17 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Threading; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
namespace Squidex.Infrastructure |
|
||||
{ |
|
||||
public interface IBackgroundProcess |
|
||||
{ |
|
||||
Task StartAsync(CancellationToken ct); |
|
||||
} |
|
||||
} |
|
||||
@ -1,19 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Threading; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
namespace Squidex.Infrastructure |
|
||||
{ |
|
||||
public interface IInitializable |
|
||||
{ |
|
||||
int Order => 0; |
|
||||
|
|
||||
Task InitializeAsync(CancellationToken ct = default); |
|
||||
} |
|
||||
} |
|
||||
@ -1,44 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Threading.Tasks; |
|
||||
using Microsoft.AspNetCore.Http; |
|
||||
|
|
||||
namespace Squidex.Web.Pipeline |
|
||||
{ |
|
||||
public class CleanupHostMiddleware |
|
||||
{ |
|
||||
private readonly RequestDelegate next; |
|
||||
|
|
||||
public CleanupHostMiddleware(RequestDelegate next) |
|
||||
{ |
|
||||
this.next = next; |
|
||||
} |
|
||||
|
|
||||
public Task InvokeAsync(HttpContext context) |
|
||||
{ |
|
||||
var request = context.Request; |
|
||||
|
|
||||
if (request.Host.HasValue && (HasHttpsPort(request) || HasHttpPort(request))) |
|
||||
{ |
|
||||
request.Host = new HostString(request.Host.Host); |
|
||||
} |
|
||||
|
|
||||
return next(context); |
|
||||
} |
|
||||
|
|
||||
private static bool HasHttpPort(HttpRequest request) |
|
||||
{ |
|
||||
return request.Scheme == "http" && request.Host.Port == 80; |
|
||||
} |
|
||||
|
|
||||
private static bool HasHttpsPort(HttpRequest request) |
|
||||
{ |
|
||||
return request.Scheme == "https" && request.Host.Port == 443; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,159 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using Microsoft.AspNetCore.Http; |
|
||||
using Squidex.Infrastructure; |
|
||||
|
|
||||
namespace Squidex.Web |
|
||||
{ |
|
||||
public sealed class UrlsOptions |
|
||||
{ |
|
||||
private readonly HashSet<HostString> allTrustedHosts = new HashSet<HostString>(); |
|
||||
private string baseUrl; |
|
||||
private string[]? trustedHosts; |
|
||||
|
|
||||
public string[]? KnownProxies { get; set; } |
|
||||
|
|
||||
public bool EnableForwardHeaders { get; set; } = true; |
|
||||
|
|
||||
public bool EnforceHTTPS { get; set; } = false; |
|
||||
|
|
||||
public bool EnforceHost { get; set; } = false; |
|
||||
|
|
||||
public int? HttpsPort { get; set; } = 443; |
|
||||
|
|
||||
public string BaseUrl |
|
||||
{ |
|
||||
get |
|
||||
{ |
|
||||
return baseUrl; |
|
||||
} |
|
||||
set |
|
||||
{ |
|
||||
if (TryBuildHost(value, out var host)) |
|
||||
{ |
|
||||
allTrustedHosts.Add(host); |
|
||||
} |
|
||||
|
|
||||
baseUrl = value; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public string[]? TrustedHosts |
|
||||
{ |
|
||||
get |
|
||||
{ |
|
||||
return trustedHosts; |
|
||||
} |
|
||||
set |
|
||||
{ |
|
||||
if (trustedHosts != null) |
|
||||
{ |
|
||||
foreach (var canidate in trustedHosts) |
|
||||
{ |
|
||||
if (TryBuildHost(canidate, out var host)) |
|
||||
{ |
|
||||
allTrustedHosts.Add(host); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
trustedHosts = value; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public bool IsAllowedHost(string? url) |
|
||||
{ |
|
||||
if (!Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out var uri)) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
return IsAllowedHost(uri); |
|
||||
} |
|
||||
|
|
||||
public bool IsAllowedHost(Uri uri) |
|
||||
{ |
|
||||
if (!uri.IsAbsoluteUri) |
|
||||
{ |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
return allTrustedHosts.Contains(BuildHost(uri)); |
|
||||
} |
|
||||
|
|
||||
public string BuildUrl(string path, bool trailingSlash = true) |
|
||||
{ |
|
||||
if (string.IsNullOrWhiteSpace(BaseUrl)) |
|
||||
{ |
|
||||
throw new ConfigurationException("Configure BaseUrl with 'urls:baseUrl'."); |
|
||||
} |
|
||||
|
|
||||
return BaseUrl.BuildFullUrl(path, trailingSlash); |
|
||||
} |
|
||||
|
|
||||
public HostString BuildHost() |
|
||||
{ |
|
||||
if (string.IsNullOrWhiteSpace(BaseUrl)) |
|
||||
{ |
|
||||
throw new ConfigurationException("Configure BaseUrl with 'urls:baseUrl'."); |
|
||||
} |
|
||||
|
|
||||
if (!TryBuildHost(BaseUrl, out var host)) |
|
||||
{ |
|
||||
throw new ConfigurationException("Configure BaseUrl with 'urls:baseUrl' host name."); |
|
||||
} |
|
||||
|
|
||||
return host; |
|
||||
} |
|
||||
|
|
||||
private static bool TryBuildHost(string urlOrHost, out HostString host) |
|
||||
{ |
|
||||
host = default; |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(urlOrHost)) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
if (Uri.TryCreate(urlOrHost, UriKind.Absolute, out var uri1)) |
|
||||
{ |
|
||||
host = BuildHost(uri1); |
|
||||
|
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
if (Uri.TryCreate($"http://{urlOrHost}", UriKind.Absolute, out var uri2)) |
|
||||
{ |
|
||||
host = BuildHost(uri2); |
|
||||
|
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
private static HostString BuildHost(Uri uri) |
|
||||
{ |
|
||||
return BuildHost(uri.Host, uri.Port); |
|
||||
} |
|
||||
|
|
||||
private static HostString BuildHost(string host, int port) |
|
||||
{ |
|
||||
if (port == 443 || port == 80) |
|
||||
{ |
|
||||
return new HostString(host.ToLowerInvariant()); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
return new HostString(host.ToLowerInvariant(), port); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,38 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Threading; |
|
||||
using System.Threading.Tasks; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Squidex.Log; |
|
||||
|
|
||||
namespace Squidex.Config.Startup |
|
||||
{ |
|
||||
public sealed class BackgroundHost : SafeHostedService |
|
||||
{ |
|
||||
private readonly IEnumerable<IBackgroundProcess> targets; |
|
||||
|
|
||||
public BackgroundHost(IEnumerable<IBackgroundProcess> targets, ISemanticLog log) |
|
||||
: base(log) |
|
||||
{ |
|
||||
this.targets = targets; |
|
||||
} |
|
||||
|
|
||||
protected override async Task StartAsync(ISemanticLog log, CancellationToken ct) |
|
||||
{ |
|
||||
foreach (var target in targets.Distinct()) |
|
||||
{ |
|
||||
await target.StartAsync(ct); |
|
||||
|
|
||||
log.LogInformation(w => w.WriteProperty("backgroundSystem", target.ToString())); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,37 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Threading; |
|
||||
using System.Threading.Tasks; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Squidex.Log; |
|
||||
|
|
||||
namespace Squidex.Config.Startup |
|
||||
{ |
|
||||
public sealed class InitializerHost : SafeHostedService |
|
||||
{ |
|
||||
private readonly IEnumerable<IInitializable> targets; |
|
||||
|
|
||||
public InitializerHost(IEnumerable<IInitializable> targets, ISemanticLog log) |
|
||||
: base(log) |
|
||||
{ |
|
||||
this.targets = targets; |
|
||||
} |
|
||||
|
|
||||
protected override async Task StartAsync(ISemanticLog log, CancellationToken ct) |
|
||||
{ |
|
||||
foreach (var target in targets.Distinct().OrderBy(x => x.Order)) |
|
||||
{ |
|
||||
await target.InitializeAsync(ct); |
|
||||
|
|
||||
log.LogInformation(w => w.WriteProperty("initializedSystem", target.ToString())); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,47 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Threading; |
|
||||
using System.Threading.Tasks; |
|
||||
using Microsoft.Extensions.Hosting; |
|
||||
using Squidex.Log; |
|
||||
|
|
||||
namespace Squidex.Config.Startup |
|
||||
{ |
|
||||
public abstract class SafeHostedService : IHostedService |
|
||||
{ |
|
||||
private readonly ISemanticLog log; |
|
||||
private bool isStarted; |
|
||||
|
|
||||
protected SafeHostedService(ISemanticLog log) |
|
||||
{ |
|
||||
this.log = log; |
|
||||
} |
|
||||
|
|
||||
public async Task StartAsync(CancellationToken cancellationToken) |
|
||||
{ |
|
||||
await StartAsync(log, cancellationToken); |
|
||||
|
|
||||
isStarted = true; |
|
||||
} |
|
||||
|
|
||||
public async Task StopAsync(CancellationToken cancellationToken) |
|
||||
{ |
|
||||
if (isStarted) |
|
||||
{ |
|
||||
await StopAsync(log, cancellationToken); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
protected abstract Task StartAsync(ISemanticLog log, CancellationToken ct); |
|
||||
|
|
||||
protected virtual Task StopAsync(ISemanticLog log, CancellationToken ct) |
|
||||
{ |
|
||||
return Task.CompletedTask; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,75 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Threading.Tasks; |
|
||||
using Microsoft.AspNetCore.Http; |
|
||||
using Xunit; |
|
||||
|
|
||||
#pragma warning disable RECS0092 // Convert field to readonly
|
|
||||
|
|
||||
namespace Squidex.Web.Pipeline |
|
||||
{ |
|
||||
public class CleanupHostMiddlewareTests |
|
||||
{ |
|
||||
private readonly CleanupHostMiddleware sut; |
|
||||
private bool isNextCalled; |
|
||||
|
|
||||
public CleanupHostMiddlewareTests() |
|
||||
{ |
|
||||
Task Next(HttpContext context) |
|
||||
{ |
|
||||
isNextCalled = true; |
|
||||
|
|
||||
return Task.CompletedTask; |
|
||||
} |
|
||||
|
|
||||
sut = new CleanupHostMiddleware(Next); |
|
||||
} |
|
||||
|
|
||||
[Fact] |
|
||||
public async Task Should_cleanup_host_if_https_schema_contains_default_port() |
|
||||
{ |
|
||||
var httpContext = new DefaultHttpContext(); |
|
||||
|
|
||||
httpContext.Request.Scheme = "https"; |
|
||||
httpContext.Request.Host = new HostString("host", 443); |
|
||||
|
|
||||
await sut.InvokeAsync(httpContext); |
|
||||
|
|
||||
Assert.Null(httpContext.Request.Host.Port); |
|
||||
Assert.True(isNextCalled); |
|
||||
} |
|
||||
|
|
||||
[Fact] |
|
||||
public async Task Should_cleanup_host_if_http_schema_contains_default_port() |
|
||||
{ |
|
||||
var httpContext = new DefaultHttpContext(); |
|
||||
|
|
||||
httpContext.Request.Scheme = "http"; |
|
||||
httpContext.Request.Host = new HostString("host", 80); |
|
||||
|
|
||||
await sut.InvokeAsync(httpContext); |
|
||||
|
|
||||
Assert.Null(httpContext.Request.Host.Port); |
|
||||
Assert.True(isNextCalled); |
|
||||
} |
|
||||
|
|
||||
[Fact] |
|
||||
public async Task Should_not_cleanup_host_if_http_schema_contains_other_port() |
|
||||
{ |
|
||||
var httpContext = new DefaultHttpContext(); |
|
||||
|
|
||||
httpContext.Request.Scheme = "http"; |
|
||||
httpContext.Request.Host = new HostString("host", 8080); |
|
||||
|
|
||||
await sut.InvokeAsync(httpContext); |
|
||||
|
|
||||
Assert.Equal(8080, httpContext.Request.Host.Port); |
|
||||
Assert.True(isNextCalled); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,65 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Xunit; |
|
||||
|
|
||||
namespace Squidex.Web |
|
||||
{ |
|
||||
public sealed class UrlsOptionsTests |
|
||||
{ |
|
||||
private readonly UrlsOptions sut = new UrlsOptions |
|
||||
{ |
|
||||
BaseUrl = "http://localhost" |
|
||||
}; |
|
||||
|
|
||||
[Theory] |
|
||||
[InlineData("/url")] |
|
||||
[InlineData("/url/")] |
|
||||
[InlineData("url")] |
|
||||
public void Should_build_url_with_leading_slash(string path) |
|
||||
{ |
|
||||
var url = sut.BuildUrl(path); |
|
||||
|
|
||||
Assert.Equal("http://localhost/url/", url); |
|
||||
} |
|
||||
|
|
||||
[Theory] |
|
||||
[InlineData("/url")] |
|
||||
[InlineData("/url/")] |
|
||||
[InlineData("url")] |
|
||||
public void Should_build_url_without_leading_slash(string path) |
|
||||
{ |
|
||||
var url = sut.BuildUrl(path, false); |
|
||||
|
|
||||
Assert.Equal("http://localhost/url", url); |
|
||||
} |
|
||||
|
|
||||
[Fact] |
|
||||
public void Should_allow_same_host() |
|
||||
{ |
|
||||
Assert.True(sut.IsAllowedHost("http://localhost")); |
|
||||
} |
|
||||
|
|
||||
[Fact] |
|
||||
public void Should_allow_https_port() |
|
||||
{ |
|
||||
Assert.True(sut.IsAllowedHost("https://localhost")); |
|
||||
} |
|
||||
|
|
||||
[Fact] |
|
||||
public void Should_not_allow_other_host() |
|
||||
{ |
|
||||
Assert.False(sut.IsAllowedHost("https://other:5000")); |
|
||||
} |
|
||||
|
|
||||
[Fact] |
|
||||
public void Should_not_allow_same_host_with_other_port() |
|
||||
{ |
|
||||
Assert.False(sut.IsAllowedHost("https://localhost:3000")); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue