mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 22:08:17 +08:00
@ -27,7 +27,13 @@
|
||||
}
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseMvc();
|
||||
app.UseRouting();
|
||||
app.UseAuthorization();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Values;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
@ -41,6 +42,8 @@ namespace Ocelot.Configuration.Builder
|
||||
private List<AddHeader> _addHeadersToUpstream;
|
||||
private bool _dangerousAcceptAnyServerCertificateValidator;
|
||||
private SecurityOptions _securityOptions;
|
||||
private string _downstreamHttpMethod;
|
||||
private Version _downstreamHttpVersion;
|
||||
|
||||
public DownstreamReRouteBuilder()
|
||||
{
|
||||
@ -56,6 +59,12 @@ namespace Ocelot.Configuration.Builder
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownstreamReRouteBuilder WithDownStreamHttpMethod(string method)
|
||||
{
|
||||
_downstreamHttpMethod = method;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownstreamReRouteBuilder WithLoadBalancerOptions(LoadBalancerOptions loadBalancerOptions)
|
||||
{
|
||||
_loadBalancerOptions = loadBalancerOptions;
|
||||
@ -248,6 +257,12 @@ namespace Ocelot.Configuration.Builder
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownstreamReRouteBuilder WithDownstreamHttpVersion(Version downstreamHttpVersion)
|
||||
{
|
||||
_downstreamHttpVersion = downstreamHttpVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownstreamReRoute Build()
|
||||
{
|
||||
return new DownstreamReRoute(
|
||||
@ -282,7 +297,9 @@ namespace Ocelot.Configuration.Builder
|
||||
_addHeadersToDownstream,
|
||||
_addHeadersToUpstream,
|
||||
_dangerousAcceptAnyServerCertificateValidator,
|
||||
_securityOptions);
|
||||
_securityOptions,
|
||||
_downstreamHttpMethod,
|
||||
_downstreamHttpVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
namespace Ocelot.Configuration.ChangeTracking
|
||||
{
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="IChangeToken" /> source which is activated when Ocelot's configuration is changed.
|
||||
/// </summary>
|
||||
public interface IOcelotConfigurationChangeTokenSource
|
||||
{
|
||||
IChangeToken ChangeToken { get; }
|
||||
|
||||
void Activate();
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
namespace Ocelot.Configuration.ChangeTracking
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
public class OcelotConfigurationChangeToken : IChangeToken
|
||||
{
|
||||
public const double PollingIntervalSeconds = 1;
|
||||
|
||||
private readonly ICollection<CallbackWrapper> _callbacks = new List<CallbackWrapper>();
|
||||
private readonly object _lock = new object();
|
||||
private DateTime? _timeChanged;
|
||||
|
||||
public IDisposable RegisterChangeCallback(Action<object> callback, object state)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
var wrapper = new CallbackWrapper(callback, state, _callbacks, _lock);
|
||||
_callbacks.Add(wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_timeChanged = DateTime.UtcNow;
|
||||
foreach (var wrapper in _callbacks)
|
||||
{
|
||||
wrapper.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Token stays active for PollingIntervalSeconds after a change (could be parameterised) - otherwise HasChanged would be true forever.
|
||||
// Taking suggestions for better ways to reset HasChanged back to false.
|
||||
public bool HasChanged => _timeChanged.HasValue && (DateTime.UtcNow - _timeChanged.Value).TotalSeconds < PollingIntervalSeconds;
|
||||
|
||||
public bool ActiveChangeCallbacks => true;
|
||||
|
||||
private class CallbackWrapper : IDisposable
|
||||
{
|
||||
private readonly ICollection<CallbackWrapper> _callbacks;
|
||||
private readonly object _lock;
|
||||
|
||||
public CallbackWrapper(Action<object> callback, object state, ICollection<CallbackWrapper> callbacks, object @lock)
|
||||
{
|
||||
_callbacks = callbacks;
|
||||
_lock = @lock;
|
||||
Callback = callback;
|
||||
State = state;
|
||||
}
|
||||
|
||||
public void Invoke()
|
||||
{
|
||||
Callback.Invoke(State);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_callbacks.Remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
public Action<object> Callback { get; }
|
||||
|
||||
public object State { get; }
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
namespace Ocelot.Configuration.ChangeTracking
|
||||
{
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
public class OcelotConfigurationChangeTokenSource : IOcelotConfigurationChangeTokenSource
|
||||
{
|
||||
private readonly OcelotConfigurationChangeToken _changeToken = new OcelotConfigurationChangeToken();
|
||||
|
||||
public IChangeToken ChangeToken => _changeToken;
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
_changeToken.Activate();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
namespace Ocelot.Configuration.ChangeTracking
|
||||
{
|
||||
using System;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Ocelot.Configuration.Repository;
|
||||
|
||||
public class OcelotConfigurationMonitor : IOptionsMonitor<IInternalConfiguration>
|
||||
{
|
||||
private readonly IOcelotConfigurationChangeTokenSource _changeTokenSource;
|
||||
private readonly IInternalConfigurationRepository _repo;
|
||||
|
||||
public OcelotConfigurationMonitor(IInternalConfigurationRepository repo, IOcelotConfigurationChangeTokenSource changeTokenSource)
|
||||
{
|
||||
_changeTokenSource = changeTokenSource;
|
||||
_repo = repo;
|
||||
}
|
||||
|
||||
public IInternalConfiguration Get(string name)
|
||||
{
|
||||
return _repo.Get().Data;
|
||||
}
|
||||
|
||||
public IDisposable OnChange(Action<IInternalConfiguration, string> listener)
|
||||
{
|
||||
return _changeTokenSource.ChangeToken.RegisterChangeCallback(_ => listener(CurrentValue, ""), null);
|
||||
}
|
||||
|
||||
public IInternalConfiguration CurrentValue => _repo.Get().Data;
|
||||
}
|
||||
}
|
@ -13,13 +13,15 @@ namespace Ocelot.Configuration.Creator
|
||||
private readonly IHttpHandlerOptionsCreator _httpHandlerOptionsCreator;
|
||||
private readonly IAdministrationPath _adminPath;
|
||||
private readonly ILoadBalancerOptionsCreator _loadBalancerOptionsCreator;
|
||||
private readonly IVersionCreator _versionCreator;
|
||||
|
||||
public ConfigurationCreator(
|
||||
IServiceProviderConfigurationCreator serviceProviderConfigCreator,
|
||||
IQoSOptionsCreator qosOptionsCreator,
|
||||
IHttpHandlerOptionsCreator httpHandlerOptionsCreator,
|
||||
IServiceProvider serviceProvider,
|
||||
ILoadBalancerOptionsCreator loadBalancerOptionsCreator
|
||||
ILoadBalancerOptionsCreator loadBalancerOptionsCreator,
|
||||
IVersionCreator versionCreator
|
||||
)
|
||||
{
|
||||
_adminPath = serviceProvider.GetService<IAdministrationPath>();
|
||||
@ -27,6 +29,7 @@ namespace Ocelot.Configuration.Creator
|
||||
_serviceProviderConfigCreator = serviceProviderConfigCreator;
|
||||
_qosOptionsCreator = qosOptionsCreator;
|
||||
_httpHandlerOptionsCreator = httpHandlerOptionsCreator;
|
||||
_versionCreator = versionCreator;
|
||||
}
|
||||
|
||||
public InternalConfiguration Create(FileConfiguration fileConfiguration, List<ReRoute> reRoutes)
|
||||
@ -41,6 +44,8 @@ namespace Ocelot.Configuration.Creator
|
||||
|
||||
var adminPath = _adminPath != null ? _adminPath.Path : null;
|
||||
|
||||
var version = _versionCreator.Create(fileConfiguration.GlobalConfiguration.DownstreamHttpVersion);
|
||||
|
||||
return new InternalConfiguration(reRoutes,
|
||||
adminPath,
|
||||
serviceProviderConfiguration,
|
||||
@ -48,7 +53,8 @@ namespace Ocelot.Configuration.Creator
|
||||
lbOptions,
|
||||
fileConfiguration.GlobalConfiguration.DownstreamScheme,
|
||||
qosOptions,
|
||||
httpHandlerOptions
|
||||
httpHandlerOptions,
|
||||
version
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,12 @@ namespace Ocelot.Configuration.Creator
|
||||
public class DynamicsCreator : IDynamicsCreator
|
||||
{
|
||||
private readonly IRateLimitOptionsCreator _rateLimitOptionsCreator;
|
||||
private readonly IVersionCreator _versionCreator;
|
||||
|
||||
public DynamicsCreator(IRateLimitOptionsCreator rateLimitOptionsCreator)
|
||||
public DynamicsCreator(IRateLimitOptionsCreator rateLimitOptionsCreator, IVersionCreator versionCreator)
|
||||
{
|
||||
_rateLimitOptionsCreator = rateLimitOptionsCreator;
|
||||
_versionCreator = versionCreator;
|
||||
}
|
||||
|
||||
public List<ReRoute> Create(FileConfiguration fileConfiguration)
|
||||
@ -26,10 +28,13 @@ namespace Ocelot.Configuration.Creator
|
||||
var rateLimitOption = _rateLimitOptionsCreator
|
||||
.Create(fileDynamicReRoute.RateLimitRule, globalConfiguration);
|
||||
|
||||
var version = _versionCreator.Create(fileDynamicReRoute.DownstreamHttpVersion);
|
||||
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithEnableRateLimiting(rateLimitOption.EnableRateLimiting)
|
||||
.WithRateLimitOptions(rateLimitOption)
|
||||
.WithServiceName(fileDynamicReRoute.ServiceName)
|
||||
.WithDownstreamHttpVersion(version)
|
||||
.Build();
|
||||
|
||||
var reRoute = new ReRouteBuilder()
|
||||
|
17
src/Ocelot/Configuration/Creator/HttpVersionCreator.cs
Normal file
17
src/Ocelot/Configuration/Creator/HttpVersionCreator.cs
Normal file
@ -0,0 +1,17 @@
|
||||
namespace Ocelot.Configuration.Creator
|
||||
{
|
||||
using System;
|
||||
|
||||
public class HttpVersionCreator : IVersionCreator
|
||||
{
|
||||
public Version Create(string downstreamHttpVersion)
|
||||
{
|
||||
if (!Version.TryParse(downstreamHttpVersion, out Version version))
|
||||
{
|
||||
version = new Version(1, 1);
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
9
src/Ocelot/Configuration/Creator/IVersionCreator.cs
Normal file
9
src/Ocelot/Configuration/Creator/IVersionCreator.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace Ocelot.Configuration.Creator
|
||||
{
|
||||
using System;
|
||||
|
||||
public interface IVersionCreator
|
||||
{
|
||||
Version Create(string downstreamHttpVersion);
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ namespace Ocelot.Configuration.Creator
|
||||
private readonly IDownstreamAddressesCreator _downstreamAddressesCreator;
|
||||
private readonly IReRouteKeyCreator _reRouteKeyCreator;
|
||||
private readonly ISecurityOptionsCreator _securityOptionsCreator;
|
||||
private readonly IVersionCreator _versionCreator;
|
||||
|
||||
public ReRoutesCreator(
|
||||
IClaimsToThingCreator claimsToThingCreator,
|
||||
@ -37,7 +38,8 @@ namespace Ocelot.Configuration.Creator
|
||||
IDownstreamAddressesCreator downstreamAddressesCreator,
|
||||
ILoadBalancerOptionsCreator loadBalancerOptionsCreator,
|
||||
IReRouteKeyCreator reRouteKeyCreator,
|
||||
ISecurityOptionsCreator securityOptionsCreator
|
||||
ISecurityOptionsCreator securityOptionsCreator,
|
||||
IVersionCreator versionCreator
|
||||
)
|
||||
{
|
||||
_reRouteKeyCreator = reRouteKeyCreator;
|
||||
@ -55,6 +57,7 @@ namespace Ocelot.Configuration.Creator
|
||||
_httpHandlerOptionsCreator = httpHandlerOptionsCreator;
|
||||
_loadBalancerOptionsCreator = loadBalancerOptionsCreator;
|
||||
_securityOptionsCreator = securityOptionsCreator;
|
||||
_versionCreator = versionCreator;
|
||||
}
|
||||
|
||||
public List<ReRoute> Create(FileConfiguration fileConfiguration)
|
||||
@ -104,6 +107,8 @@ namespace Ocelot.Configuration.Creator
|
||||
|
||||
var securityOptions = _securityOptionsCreator.Create(fileReRoute.SecurityOptions);
|
||||
|
||||
var downstreamHttpVersion = _versionCreator.Create(fileReRoute.DownstreamHttpVersion);
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithKey(fileReRoute.Key)
|
||||
.WithDownstreamPathTemplate(fileReRoute.DownstreamPathTemplate)
|
||||
@ -138,6 +143,8 @@ namespace Ocelot.Configuration.Creator
|
||||
.WithAddHeadersToUpstream(hAndRs.AddHeadersToUpstream)
|
||||
.WithDangerousAcceptAnyServerCertificateValidator(fileReRoute.DangerousAcceptAnyServerCertificateValidator)
|
||||
.WithSecurityOptions(securityOptions)
|
||||
.WithDownstreamHttpVersion(downstreamHttpVersion)
|
||||
.WithDownStreamHttpMethod(fileReRoute.DownstreamHttpMethod)
|
||||
.Build();
|
||||
|
||||
return reRoute;
|
||||
|
@ -1,6 +1,7 @@
|
||||
namespace Ocelot.Configuration
|
||||
{
|
||||
using Creator;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Values;
|
||||
|
||||
@ -38,7 +39,9 @@ namespace Ocelot.Configuration
|
||||
List<AddHeader> addHeadersToDownstream,
|
||||
List<AddHeader> addHeadersToUpstream,
|
||||
bool dangerousAcceptAnyServerCertificateValidator,
|
||||
SecurityOptions securityOptions)
|
||||
SecurityOptions securityOptions,
|
||||
string downstreamHttpMethod,
|
||||
Version downstreamHttpVersion)
|
||||
{
|
||||
DangerousAcceptAnyServerCertificateValidator = dangerousAcceptAnyServerCertificateValidator;
|
||||
AddHeadersToDownstream = addHeadersToDownstream;
|
||||
@ -72,6 +75,8 @@ namespace Ocelot.Configuration
|
||||
LoadBalancerKey = loadBalancerKey;
|
||||
AddHeadersToUpstream = addHeadersToUpstream;
|
||||
SecurityOptions = securityOptions;
|
||||
DownstreamHttpMethod = downstreamHttpMethod;
|
||||
DownstreamHttpVersion = downstreamHttpVersion;
|
||||
}
|
||||
|
||||
public string Key { get; }
|
||||
@ -106,5 +111,7 @@ namespace Ocelot.Configuration
|
||||
public List<AddHeader> AddHeadersToUpstream { get; }
|
||||
public bool DangerousAcceptAnyServerCertificateValidator { get; }
|
||||
public SecurityOptions SecurityOptions { get; }
|
||||
public string DownstreamHttpMethod { get; }
|
||||
public Version DownstreamHttpVersion { get; }
|
||||
}
|
||||
}
|
||||
|
@ -4,5 +4,6 @@ namespace Ocelot.Configuration.File
|
||||
{
|
||||
public string ServiceName { get; set; }
|
||||
public FileRateLimitRule RateLimitRule { get; set; }
|
||||
public string DownstreamHttpVersion { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -26,5 +26,7 @@
|
||||
public string DownstreamScheme { get; set; }
|
||||
|
||||
public FileHttpHandlerOptions HttpHandlerOptions { get; set; }
|
||||
|
||||
public string DownstreamHttpVersion { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ namespace Ocelot.Configuration.File
|
||||
public string DownstreamPathTemplate { get; set; }
|
||||
public string UpstreamPathTemplate { get; set; }
|
||||
public List<string> UpstreamHttpMethod { get; set; }
|
||||
public string DownstreamHttpMethod { get; set; }
|
||||
public Dictionary<string, string> AddHeadersToRequest { get; set; }
|
||||
public Dictionary<string, string> UpstreamHeaderTransform { get; set; }
|
||||
public Dictionary<string, string> DownstreamHeaderTransform { get; set; }
|
||||
@ -55,5 +56,6 @@ namespace Ocelot.Configuration.File
|
||||
public int Timeout { get; set; }
|
||||
public bool DangerousAcceptAnyServerCertificateValidator { get; set; }
|
||||
public FileSecurityOptions SecurityOptions { get; set; }
|
||||
public string DownstreamHttpVersion { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ using System.Collections.Generic;
|
||||
|
||||
namespace Ocelot.Configuration
|
||||
{
|
||||
using System;
|
||||
|
||||
public interface IInternalConfiguration
|
||||
{
|
||||
List<ReRoute> ReRoutes { get; }
|
||||
@ -19,5 +21,7 @@ namespace Ocelot.Configuration
|
||||
QoSOptions QoSOptions { get; }
|
||||
|
||||
HttpHandlerOptions HttpHandlerOptions { get; }
|
||||
|
||||
Version DownstreamHttpVersion { get; }
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ using System.Collections.Generic;
|
||||
|
||||
namespace Ocelot.Configuration
|
||||
{
|
||||
using System;
|
||||
|
||||
public class InternalConfiguration : IInternalConfiguration
|
||||
{
|
||||
public InternalConfiguration(
|
||||
@ -12,7 +14,8 @@ namespace Ocelot.Configuration
|
||||
LoadBalancerOptions loadBalancerOptions,
|
||||
string downstreamScheme,
|
||||
QoSOptions qoSOptions,
|
||||
HttpHandlerOptions httpHandlerOptions)
|
||||
HttpHandlerOptions httpHandlerOptions,
|
||||
Version downstreamHttpVersion)
|
||||
{
|
||||
ReRoutes = reRoutes;
|
||||
AdministrationPath = administrationPath;
|
||||
@ -22,6 +25,7 @@ namespace Ocelot.Configuration
|
||||
DownstreamScheme = downstreamScheme;
|
||||
QoSOptions = qoSOptions;
|
||||
HttpHandlerOptions = httpHandlerOptions;
|
||||
DownstreamHttpVersion = downstreamHttpVersion;
|
||||
}
|
||||
|
||||
public List<ReRoute> ReRoutes { get; }
|
||||
@ -32,5 +36,7 @@ namespace Ocelot.Configuration
|
||||
public string DownstreamScheme { get; }
|
||||
public QoSOptions QoSOptions { get; }
|
||||
public HttpHandlerOptions HttpHandlerOptions { get; }
|
||||
|
||||
public Version DownstreamHttpVersion { get; }
|
||||
}
|
||||
}
|
||||
|
@ -4,18 +4,21 @@ using Ocelot.Configuration.File;
|
||||
using Ocelot.Responses;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.Configuration.ChangeTracking;
|
||||
|
||||
namespace Ocelot.Configuration.Repository
|
||||
{
|
||||
public class DiskFileConfigurationRepository : IFileConfigurationRepository
|
||||
{
|
||||
private readonly IOcelotConfigurationChangeTokenSource _changeTokenSource;
|
||||
private readonly string _environmentFilePath;
|
||||
private readonly string _ocelotFilePath;
|
||||
private static readonly object _lock = new object();
|
||||
private const string ConfigurationFileName = "ocelot";
|
||||
|
||||
public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment)
|
||||
public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment, IOcelotConfigurationChangeTokenSource changeTokenSource)
|
||||
{
|
||||
_changeTokenSource = changeTokenSource;
|
||||
_environmentFilePath = $"{AppContext.BaseDirectory}{ConfigurationFileName}{(string.IsNullOrEmpty(hostingEnvironment.EnvironmentName) ? string.Empty : ".")}{hostingEnvironment.EnvironmentName}.json";
|
||||
|
||||
_ocelotFilePath = $"{AppContext.BaseDirectory}{ConfigurationFileName}.json";
|
||||
@ -56,6 +59,7 @@ namespace Ocelot.Configuration.Repository
|
||||
System.IO.File.WriteAllText(_ocelotFilePath, jsonConfiguration);
|
||||
}
|
||||
|
||||
_changeTokenSource.Activate();
|
||||
return Task.FromResult<Response>(new OkResponse());
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Configuration.ChangeTracking;
|
||||
using Ocelot.Responses;
|
||||
|
||||
namespace Ocelot.Configuration.Repository
|
||||
{
|
||||
@ -10,6 +11,12 @@ namespace Ocelot.Configuration.Repository
|
||||
private static readonly object LockObject = new object();
|
||||
|
||||
private IInternalConfiguration _internalConfiguration;
|
||||
private readonly IOcelotConfigurationChangeTokenSource _changeTokenSource;
|
||||
|
||||
public InMemoryInternalConfigurationRepository(IOcelotConfigurationChangeTokenSource changeTokenSource)
|
||||
{
|
||||
_changeTokenSource = changeTokenSource;
|
||||
}
|
||||
|
||||
public Response<IInternalConfiguration> Get()
|
||||
{
|
||||
@ -23,6 +30,7 @@ namespace Ocelot.Configuration.Repository
|
||||
_internalConfiguration = internalConfiguration;
|
||||
}
|
||||
|
||||
_changeTokenSource.Activate();
|
||||
return new OkResponse();
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +83,11 @@
|
||||
RuleForEach(reRoute => reRoute.DownstreamHostAndPorts)
|
||||
.SetValidator(hostAndPortValidator);
|
||||
});
|
||||
|
||||
When(reRoute => !string.IsNullOrEmpty(reRoute.DownstreamHttpVersion), () =>
|
||||
{
|
||||
RuleFor(r => r.DownstreamHttpVersion).Matches("^[0-9]([.,][0-9]{1,1})?$");
|
||||
});
|
||||
}
|
||||
|
||||
private async Task<bool> IsSupportedAuthenticationProviders(FileAuthenticationOptions authenticationOptions, CancellationToken cancellationToken)
|
||||
|
@ -1,9 +1,12 @@
|
||||
using Ocelot.Configuration.ChangeTracking;
|
||||
|
||||
namespace Ocelot.DependencyInjection
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Ocelot.Authorisation;
|
||||
using Ocelot.Cache;
|
||||
using Ocelot.Claims;
|
||||
@ -112,6 +115,8 @@ namespace Ocelot.DependencyInjection
|
||||
Services.TryAddSingleton<IDownstreamAddressesCreator, DownstreamAddressesCreator>();
|
||||
Services.TryAddSingleton<IDelegatingHandlerHandlerFactory, DelegatingHandlerHandlerFactory>();
|
||||
Services.TryAddSingleton<ICacheKeyGenerator, CacheKeyGenerator>();
|
||||
Services.TryAddSingleton<IOcelotConfigurationChangeTokenSource, OcelotConfigurationChangeTokenSource>();
|
||||
Services.TryAddSingleton<IOptionsMonitor<IInternalConfiguration>, OcelotConfigurationMonitor>();
|
||||
|
||||
// see this for why we register this as singleton http://stackoverflow.com/questions/37371264/invalidoperationexception-unable-to-resolve-service-for-type-microsoft-aspnetc
|
||||
// could maybe use a scoped data repository
|
||||
@ -131,6 +136,7 @@ namespace Ocelot.DependencyInjection
|
||||
Services.TryAddSingleton<IFrameworkDescription, FrameworkDescription>();
|
||||
Services.TryAddSingleton<IQoSFactory, QoSFactory>();
|
||||
Services.TryAddSingleton<IExceptionToErrorMapper, HttpExeptionToErrorMapper>();
|
||||
Services.TryAddSingleton<IVersionCreator, HttpVersionCreator>();
|
||||
|
||||
//add security
|
||||
this.AddSecurity();
|
||||
@ -215,7 +221,7 @@ namespace Ocelot.DependencyInjection
|
||||
{
|
||||
// see: https://greatrexpectations.com/2018/10/25/decorators-in-net-core-with-dependency-injection
|
||||
var wrappedDescriptor = Services.First(x => x.ServiceType == typeof(IPlaceholders));
|
||||
|
||||
|
||||
var objectFactory = ActivatorUtilities.CreateFactory(
|
||||
typeof(ConfigAwarePlaceholders),
|
||||
new[] { typeof(IPlaceholders) });
|
||||
@ -229,7 +235,7 @@ namespace Ocelot.DependencyInjection
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
private static object CreateInstance(IServiceProvider services, ServiceDescriptor descriptor)
|
||||
{
|
||||
if (descriptor.ImplementationInstance != null)
|
||||
|
@ -1,5 +1,6 @@
|
||||
namespace Ocelot.DownstreamRouteFinder.Finder
|
||||
{
|
||||
using System;
|
||||
using Configuration;
|
||||
using Configuration.Builder;
|
||||
using Configuration.Creator;
|
||||
@ -54,6 +55,7 @@
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithDownstreamScheme(configuration.DownstreamScheme)
|
||||
.WithLoadBalancerOptions(configuration.LoadBalancerOptions)
|
||||
.WithDownstreamHttpVersion(configuration.DownstreamHttpVersion)
|
||||
.WithUpstreamPathTemplate(upstreamPathTemplate);
|
||||
|
||||
var rateLimitOptions = configuration.ReRoutes != null
|
||||
|
@ -15,4 +15,4 @@ using System.Runtime.InteropServices;
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("d6df4206-0dba-41d8-884d-c3e08290fdbb")]
|
||||
[assembly: Guid("d6df4206-0dba-41d8-884d-c3e08290fdbb")]
|
||||
|
@ -1,12 +1,13 @@
|
||||
namespace Ocelot.Request.Mapper
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Responses;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public interface IRequestMapper
|
||||
{
|
||||
Task<Response<HttpRequestMessage>> Map(HttpRequest request);
|
||||
Task<Response<HttpRequestMessage>> Map(HttpRequest request, DownstreamReRoute downstreamReRoute);
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Responses;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -15,15 +16,16 @@
|
||||
{
|
||||
private readonly string[] _unsupportedHeaders = { "host" };
|
||||
|
||||
public async Task<Response<HttpRequestMessage>> Map(HttpRequest request)
|
||||
public async Task<Response<HttpRequestMessage>> Map(HttpRequest request, DownstreamReRoute downstreamReRoute)
|
||||
{
|
||||
try
|
||||
{
|
||||
var requestMessage = new HttpRequestMessage()
|
||||
{
|
||||
Content = await MapContent(request),
|
||||
Method = MapMethod(request),
|
||||
RequestUri = MapUri(request)
|
||||
Method = MapMethod(request, downstreamReRoute),
|
||||
RequestUri = MapUri(request),
|
||||
Version = downstreamReRoute.DownstreamHttpVersion,
|
||||
};
|
||||
|
||||
MapHeaders(request, requestMessage);
|
||||
@ -71,8 +73,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
private HttpMethod MapMethod(HttpRequest request)
|
||||
private HttpMethod MapMethod(HttpRequest request, DownstreamReRoute downstreamReRoute)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(downstreamReRoute?.DownstreamHttpMethod))
|
||||
{
|
||||
return new HttpMethod(downstreamReRoute.DownstreamHttpMethod);
|
||||
}
|
||||
|
||||
return new HttpMethod(request.Method);
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@ namespace Ocelot.Request.Middleware
|
||||
};
|
||||
|
||||
_request.RequestUri = uriBuilder.Uri;
|
||||
_request.Method = new HttpMethod(Method);
|
||||
return _request;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ namespace Ocelot.Request.Middleware
|
||||
|
||||
public async Task Invoke(DownstreamContext context)
|
||||
{
|
||||
var downstreamRequest = await _requestMapper.Map(context.HttpContext.Request);
|
||||
var downstreamRequest = await _requestMapper.Map(context.HttpContext.Request, context.DownstreamReRoute);
|
||||
|
||||
if (downstreamRequest.IsError)
|
||||
{
|
||||
|
@ -1,4 +1,3 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Ocelot.Middleware.Pipeline;
|
||||
|
||||
namespace Ocelot.Request.Middleware
|
||||
|
Reference in New Issue
Block a user