mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 09:38:14 +08:00
Feature/#574 look at httpclient cache key (#589)
* #574 consolidate some code, man the config stuff is a mess! * #574 just use the downstream re route and the key for caching http clients * #574 added benchmark, i was suprised to learn using a complex type was faster than a string in benchmark .net dictionary tests, hey ho probably dont have enough data in the type...
This commit is contained in:
@ -50,7 +50,7 @@
|
||||
Logger.LogWarning("user scopes is not authorised setting pipeline error");
|
||||
|
||||
SetPipelineError(context, new UnauthorisedError(
|
||||
$"{context.HttpContext.User.Identity.Name} unable to access {context.DownstreamReRoute.UpstreamPathTemplate.Value}"));
|
||||
$"{context.HttpContext.User.Identity.Name} unable to access {context.DownstreamReRoute.UpstreamPathTemplate.OriginalValue}"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,19 +70,19 @@
|
||||
|
||||
if (IsAuthorised(authorised))
|
||||
{
|
||||
Logger.LogInformation($"{context.HttpContext.User.Identity.Name} has succesfully been authorised for {context.DownstreamReRoute.UpstreamPathTemplate.Value}.");
|
||||
Logger.LogInformation($"{context.HttpContext.User.Identity.Name} has succesfully been authorised for {context.DownstreamReRoute.UpstreamPathTemplate.OriginalValue}.");
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogWarning($"{context.HttpContext.User.Identity.Name} is not authorised to access {context.DownstreamReRoute.UpstreamPathTemplate.Value}. Setting pipeline error");
|
||||
Logger.LogWarning($"{context.HttpContext.User.Identity.Name} is not authorised to access {context.DownstreamReRoute.UpstreamPathTemplate.OriginalValue}. Setting pipeline error");
|
||||
|
||||
SetPipelineError(context, new UnauthorisedError($"{context.HttpContext.User.Identity.Name} is not authorised to access {context.DownstreamReRoute.UpstreamPathTemplate.Value}"));
|
||||
SetPipelineError(context, new UnauthorisedError($"{context.HttpContext.User.Identity.Name} is not authorised to access {context.DownstreamReRoute.UpstreamPathTemplate.OriginalValue}"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogInformation($"{context.DownstreamReRoute.DownstreamPathTemplate.Value} route does not require user to be authorised");
|
||||
Logger.LogInformation($"{context.DownstreamReRoute.DownstreamDownstreamPathTemplate.Value} route does not require user to be authorised");
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ namespace Ocelot.Configuration.Builder
|
||||
private AuthenticationOptions _authenticationOptions;
|
||||
private string _loadBalancerKey;
|
||||
private string _downstreamPathTemplate;
|
||||
private string _upstreamTemplate;
|
||||
private UpstreamPathTemplate _upstreamTemplatePattern;
|
||||
private List<HttpMethod> _upstreamHttpMethod;
|
||||
private bool _isAuthenticated;
|
||||
@ -79,12 +78,6 @@ namespace Ocelot.Configuration.Builder
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownstreamReRouteBuilder WithUpstreamPathTemplate(string input)
|
||||
{
|
||||
_upstreamTemplate = input;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownstreamReRouteBuilder WithUpstreamTemplatePattern(UpstreamPathTemplate input)
|
||||
{
|
||||
_upstreamTemplatePattern = input;
|
||||
@ -245,7 +238,7 @@ namespace Ocelot.Configuration.Builder
|
||||
{
|
||||
return new DownstreamReRoute(
|
||||
_key,
|
||||
new PathTemplate(_upstreamTemplate),
|
||||
_upstreamTemplatePattern,
|
||||
_upstreamHeaderFindAndReplace,
|
||||
_downstreamHeaderFindAndReplace,
|
||||
_downstreamAddresses,
|
||||
@ -267,7 +260,7 @@ namespace Ocelot.Configuration.Builder
|
||||
_isAuthenticated,
|
||||
_isAuthorised,
|
||||
_authenticationOptions,
|
||||
new PathTemplate(_downstreamPathTemplate),
|
||||
new DownstreamPathTemplate(_downstreamPathTemplate),
|
||||
_loadBalancerKey,
|
||||
_delegatingHandlers,
|
||||
_addHeadersToDownstream,
|
||||
|
@ -1,15 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Ocelot.Values;
|
||||
using System.Linq;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using System;
|
||||
|
||||
namespace Ocelot.Configuration.Builder
|
||||
namespace Ocelot.Configuration.Builder
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Ocelot.Values;
|
||||
using System.Linq;
|
||||
|
||||
public class ReRouteBuilder
|
||||
{
|
||||
private string _upstreamTemplate;
|
||||
private UpstreamPathTemplate _upstreamTemplatePattern;
|
||||
private List<HttpMethod> _upstreamHttpMethod;
|
||||
private string _upstreamHost;
|
||||
@ -39,12 +36,6 @@ namespace Ocelot.Configuration.Builder
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReRouteBuilder WithUpstreamPathTemplate(string input)
|
||||
{
|
||||
_upstreamTemplate = input;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReRouteBuilder WithUpstreamTemplatePattern(UpstreamPathTemplate input)
|
||||
{
|
||||
_upstreamTemplatePattern = input;
|
||||
@ -67,7 +58,6 @@ namespace Ocelot.Configuration.Builder
|
||||
{
|
||||
return new ReRoute(
|
||||
_downstreamReRoutes,
|
||||
new PathTemplate(_upstreamTemplate),
|
||||
_upstreamHttpMethod,
|
||||
_upstreamTemplatePattern,
|
||||
_upstreamHost,
|
||||
|
@ -0,0 +1,41 @@
|
||||
namespace Ocelot.Configuration.Builder
|
||||
{
|
||||
using Values;
|
||||
|
||||
public class UpstreamPathTemplateBuilder
|
||||
{
|
||||
private string _template;
|
||||
private int _priority;
|
||||
private bool _containsQueryString;
|
||||
private string _originalValue;
|
||||
|
||||
public UpstreamPathTemplateBuilder WithTemplate(string template)
|
||||
{
|
||||
_template = template;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpstreamPathTemplateBuilder WithPriority(int priority)
|
||||
{
|
||||
_priority = priority;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpstreamPathTemplateBuilder WithContainsQueryString(bool containsQueryString)
|
||||
{
|
||||
_containsQueryString = containsQueryString;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpstreamPathTemplateBuilder WithOriginalValue(string originalValue)
|
||||
{
|
||||
_originalValue = originalValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpstreamPathTemplate Build()
|
||||
{
|
||||
return new UpstreamPathTemplate(_template, _priority, _containsQueryString, _originalValue);
|
||||
}
|
||||
}
|
||||
}
|
@ -166,7 +166,6 @@ namespace Ocelot.Configuration.Creator
|
||||
var upstreamTemplatePattern = _upstreamTemplatePatternCreator.Create(aggregateReRoute);
|
||||
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithUpstreamPathTemplate(aggregateReRoute.UpstreamPathTemplate)
|
||||
.WithUpstreamHttpMethod(aggregateReRoute.UpstreamHttpMethod)
|
||||
.WithUpstreamTemplatePattern(upstreamTemplatePattern)
|
||||
.WithDownstreamReRoutes(applicableReRoutes)
|
||||
@ -182,7 +181,6 @@ namespace Ocelot.Configuration.Creator
|
||||
var upstreamTemplatePattern = _upstreamTemplatePatternCreator.Create(fileReRoute);
|
||||
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithUpstreamPathTemplate(fileReRoute.UpstreamPathTemplate)
|
||||
.WithUpstreamHttpMethod(fileReRoute.UpstreamHttpMethod)
|
||||
.WithUpstreamTemplatePattern(upstreamTemplatePattern)
|
||||
.WithDownstreamReRoute(downstreamReRoutes)
|
||||
@ -229,7 +227,6 @@ namespace Ocelot.Configuration.Creator
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithKey(fileReRoute.Key)
|
||||
.WithDownstreamPathTemplate(fileReRoute.DownstreamPathTemplate)
|
||||
.WithUpstreamPathTemplate(fileReRoute.UpstreamPathTemplate)
|
||||
.WithUpstreamHttpMethod(fileReRoute.UpstreamHttpMethod)
|
||||
.WithUpstreamTemplatePattern(upstreamTemplatePattern)
|
||||
.WithIsAuthenticated(fileReRouteOptions.IsAuthenticated)
|
||||
|
@ -31,7 +31,7 @@ namespace Ocelot.Configuration.Creator
|
||||
//hack to handle /{url} case
|
||||
if(ForwardSlashAndOnePlaceHolder(upstreamTemplate, placeholders, postitionOfPlaceHolderClosingBracket))
|
||||
{
|
||||
return new UpstreamPathTemplate(RegExForwardSlashAndOnePlaceHolder, 0, false);
|
||||
return new UpstreamPathTemplate(RegExForwardSlashAndOnePlaceHolder, 0, false, reRoute.UpstreamPathTemplate);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -60,7 +60,7 @@ namespace Ocelot.Configuration.Creator
|
||||
|
||||
if (upstreamTemplate == "/")
|
||||
{
|
||||
return new UpstreamPathTemplate(RegExForwardSlashOnly, reRoute.Priority, containsQueryString);
|
||||
return new UpstreamPathTemplate(RegExForwardSlashOnly, reRoute.Priority, containsQueryString, reRoute.UpstreamPathTemplate);
|
||||
}
|
||||
|
||||
if(upstreamTemplate.EndsWith("/"))
|
||||
@ -72,7 +72,7 @@ namespace Ocelot.Configuration.Creator
|
||||
? $"^{upstreamTemplate}{RegExMatchEndString}"
|
||||
: $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}";
|
||||
|
||||
return new UpstreamPathTemplate(route, reRoute.Priority, containsQueryString);
|
||||
return new UpstreamPathTemplate(route, reRoute.Priority, containsQueryString, reRoute.UpstreamPathTemplate);
|
||||
}
|
||||
|
||||
private bool ForwardSlashAndOnePlaceHolder(string upstreamTemplate, List<string> placeholders, int postitionOfPlaceHolderClosingBracket)
|
||||
|
@ -8,7 +8,7 @@ namespace Ocelot.Configuration
|
||||
{
|
||||
public DownstreamReRoute(
|
||||
string key,
|
||||
PathTemplate upstreamPathTemplate,
|
||||
UpstreamPathTemplate upstreamPathTemplate,
|
||||
List<HeaderFindAndReplace> upstreamHeadersFindAndReplace,
|
||||
List<HeaderFindAndReplace> downstreamHeadersFindAndReplace,
|
||||
List<DownstreamHostAndPort> downstreamAddresses,
|
||||
@ -30,7 +30,7 @@ namespace Ocelot.Configuration
|
||||
bool isAuthenticated,
|
||||
bool isAuthorised,
|
||||
AuthenticationOptions authenticationOptions,
|
||||
PathTemplate downstreamPathTemplate,
|
||||
DownstreamPathTemplate downstreamDownstreamPathTemplate,
|
||||
string loadBalancerKey,
|
||||
List<string> delegatingHandlers,
|
||||
List<AddHeader> addHeadersToDownstream,
|
||||
@ -63,13 +63,13 @@ namespace Ocelot.Configuration
|
||||
IsAuthenticated = isAuthenticated;
|
||||
IsAuthorised = isAuthorised;
|
||||
AuthenticationOptions = authenticationOptions;
|
||||
DownstreamPathTemplate = downstreamPathTemplate;
|
||||
DownstreamDownstreamPathTemplate = downstreamDownstreamPathTemplate;
|
||||
LoadBalancerKey = loadBalancerKey;
|
||||
AddHeadersToUpstream = addHeadersToUpstream;
|
||||
}
|
||||
|
||||
public string Key { get; }
|
||||
public PathTemplate UpstreamPathTemplate { get; }
|
||||
public UpstreamPathTemplate UpstreamPathTemplate { get; }
|
||||
public List<HeaderFindAndReplace> UpstreamHeadersFindAndReplace { get; }
|
||||
public List<HeaderFindAndReplace> DownstreamHeadersFindAndReplace { get; }
|
||||
public List<DownstreamHostAndPort> DownstreamAddresses { get; }
|
||||
@ -91,7 +91,7 @@ namespace Ocelot.Configuration
|
||||
public bool IsAuthenticated { get; }
|
||||
public bool IsAuthorised { get; }
|
||||
public AuthenticationOptions AuthenticationOptions { get; }
|
||||
public PathTemplate DownstreamPathTemplate { get; }
|
||||
public DownstreamPathTemplate DownstreamDownstreamPathTemplate { get; }
|
||||
public string LoadBalancerKey { get; }
|
||||
public List<string> DelegatingHandlers { get; }
|
||||
public List<AddHeader> AddHeadersToDownstream { get; }
|
||||
|
@ -1,15 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Requester.QoS;
|
||||
using Ocelot.Values;
|
||||
|
||||
namespace Ocelot.Configuration
|
||||
namespace Ocelot.Configuration
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Ocelot.Values;
|
||||
|
||||
public class ReRoute
|
||||
{
|
||||
public ReRoute(List<DownstreamReRoute> downstreamReRoute,
|
||||
PathTemplate upstreamPathTemplate,
|
||||
List<HttpMethod> upstreamHttpMethod,
|
||||
UpstreamPathTemplate upstreamTemplatePattern,
|
||||
string upstreamHost,
|
||||
@ -17,13 +14,11 @@ namespace Ocelot.Configuration
|
||||
{
|
||||
UpstreamHost = upstreamHost;
|
||||
DownstreamReRoute = downstreamReRoute;
|
||||
UpstreamPathTemplate = upstreamPathTemplate;
|
||||
UpstreamHttpMethod = upstreamHttpMethod;
|
||||
UpstreamTemplatePattern = upstreamTemplatePattern;
|
||||
Aggregator = aggregator;
|
||||
}
|
||||
|
||||
public PathTemplate UpstreamPathTemplate { get; private set; }
|
||||
public UpstreamPathTemplate UpstreamTemplatePattern { get; private set; }
|
||||
public List<HttpMethod> UpstreamHttpMethod { get; private set; }
|
||||
public string UpstreamHost { get; private set; }
|
||||
|
@ -55,7 +55,7 @@ namespace Ocelot.DownstreamRouteFinder.Finder
|
||||
|
||||
private DownstreamRoute GetPlaceholderNamesAndValues(string path, string query, ReRoute reRoute)
|
||||
{
|
||||
var templatePlaceholderNameAndValues = _placeholderNameAndValueFinder.Find(path, query, reRoute.UpstreamPathTemplate.Value);
|
||||
var templatePlaceholderNameAndValues = _placeholderNameAndValueFinder.Find(path, query, reRoute.UpstreamTemplatePattern.OriginalValue);
|
||||
|
||||
return new DownstreamRoute(templatePlaceholderNameAndValues.Data, reRoute);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
public class DownstreamRouteProviderFactory : IDownstreamRouteProviderFactory
|
||||
{
|
||||
private readonly Dictionary<string, IDownstreamRouteProvider> _providers;
|
||||
private IOcelotLogger _logger;
|
||||
private readonly IOcelotLogger _logger;
|
||||
|
||||
public DownstreamRouteProviderFactory(IServiceProvider provider, IOcelotLoggerFactory factory)
|
||||
{
|
||||
@ -22,7 +22,7 @@
|
||||
{
|
||||
//todo - this is a bit hacky we are saying there are no reRoutes or there are reRoutes but none of them have
|
||||
//an upstream path template which means they are dyanmic and service discovery is on...
|
||||
if((!config.ReRoutes.Any() || config.ReRoutes.All(x => string.IsNullOrEmpty(x.UpstreamPathTemplate.Value))) && IsServiceDiscovery(config.ServiceProviderConfiguration))
|
||||
if((!config.ReRoutes.Any() || config.ReRoutes.All(x => string.IsNullOrEmpty(x.UpstreamTemplatePattern?.OriginalValue))) && IsServiceDiscovery(config.ServiceProviderConfiguration))
|
||||
{
|
||||
_logger.LogInformation($"Selected {nameof(DownstreamRouteCreator)} as DownstreamRouteProvider for this request");
|
||||
return _providers[nameof(DownstreamRouteCreator)];
|
||||
|
@ -51,7 +51,7 @@ namespace Ocelot.DownstreamRouteFinder.Middleware
|
||||
return;
|
||||
}
|
||||
|
||||
var downstreamPathTemplates = string.Join(", ", downstreamRoute.Data.ReRoute.DownstreamReRoute.Select(r => r.DownstreamPathTemplate.Value));
|
||||
var downstreamPathTemplates = string.Join(", ", downstreamRoute.Data.ReRoute.DownstreamReRoute.Select(r => r.DownstreamDownstreamPathTemplate.Value));
|
||||
|
||||
Logger.LogDebug($"downstream templates are {downstreamPathTemplates}");
|
||||
|
||||
|
@ -14,7 +14,7 @@ namespace Ocelot.DownstreamRouteFinder.UrlMatcher
|
||||
return regex.IsMatch(upstreamUrlPath)
|
||||
? new OkResponse<UrlMatch>(new UrlMatch(true))
|
||||
: new OkResponse<UrlMatch>(new UrlMatch(false));
|
||||
}
|
||||
}
|
||||
|
||||
return regex.IsMatch($"{upstreamUrlPath}{upstreamQueryString}")
|
||||
? new OkResponse<UrlMatch>(new UrlMatch(true))
|
||||
|
@ -27,7 +27,7 @@ namespace Ocelot.DownstreamUrlCreator.Middleware
|
||||
public async Task Invoke(DownstreamContext context)
|
||||
{
|
||||
var response = _replacer
|
||||
.Replace(context.DownstreamReRoute.DownstreamPathTemplate, context.TemplatePlaceholderNameAndValues);
|
||||
.Replace(context.DownstreamReRoute.DownstreamDownstreamPathTemplate, context.TemplatePlaceholderNameAndValues);
|
||||
|
||||
if (response.IsError)
|
||||
{
|
||||
|
@ -8,11 +8,11 @@ namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
|
||||
{
|
||||
public class DownstreamTemplatePathPlaceholderReplacer : IDownstreamPathPlaceholderReplacer
|
||||
{
|
||||
public Response<DownstreamPath> Replace(PathTemplate downstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues)
|
||||
public Response<DownstreamPath> Replace(DownstreamPathTemplate downstreamDownstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues)
|
||||
{
|
||||
var downstreamPath = new StringBuilder();
|
||||
|
||||
downstreamPath.Append(downstreamPathTemplate.Value);
|
||||
downstreamPath.Append(downstreamDownstreamPathTemplate.Value);
|
||||
|
||||
foreach (var placeholderVariableAndValue in urlPathPlaceholderNameAndValues)
|
||||
{
|
||||
@ -22,4 +22,4 @@ namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
|
||||
return new OkResponse<DownstreamPath>(new DownstreamPath(downstreamPath.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,6 @@ namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
|
||||
{
|
||||
public interface IDownstreamPathPlaceholderReplacer
|
||||
{
|
||||
Response<DownstreamPath> Replace(PathTemplate downstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues);
|
||||
Response<DownstreamPath> Replace(DownstreamPathTemplate downstreamDownstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ namespace Ocelot.Headers.Middleware
|
||||
{
|
||||
if (context.DownstreamReRoute.ClaimsToHeaders.Any())
|
||||
{
|
||||
Logger.LogInformation($"{context.DownstreamReRoute.DownstreamPathTemplate.Value} has instructions to convert claims to headers");
|
||||
Logger.LogInformation($"{context.DownstreamReRoute.DownstreamDownstreamPathTemplate.Value} has instructions to convert claims to headers");
|
||||
|
||||
var response = _addHeadersToRequest.SetHeadersOnDownstreamRequest(context.DownstreamReRoute.ClaimsToHeaders, context.HttpContext.User.Claims, context.DownstreamRequest);
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace Ocelot.QueryStrings.Middleware
|
||||
{
|
||||
if (context.DownstreamReRoute.ClaimsToQueries.Any())
|
||||
{
|
||||
Logger.LogInformation($"{context.DownstreamReRoute.DownstreamPathTemplate.Value} has instructions to convert claims to queries");
|
||||
Logger.LogInformation($"{context.DownstreamReRoute.DownstreamDownstreamPathTemplate.Value} has instructions to convert claims to queries");
|
||||
|
||||
var response = _addQueriesToRequest.SetQueriesOnDownstreamRequest(context.DownstreamReRoute.ClaimsToQueries, context.HttpContext.User.Claims, context.DownstreamRequest);
|
||||
|
||||
|
@ -34,7 +34,7 @@ namespace Ocelot.RateLimit.Middleware
|
||||
// check if rate limiting is enabled
|
||||
if (!context.DownstreamReRoute.EnableEndpointEndpointRateLimiting)
|
||||
{
|
||||
Logger.LogInformation($"EndpointRateLimiting is not enabled for {context.DownstreamReRoute.DownstreamPathTemplate.Value}");
|
||||
Logger.LogInformation($"EndpointRateLimiting is not enabled for {context.DownstreamReRoute.DownstreamDownstreamPathTemplate.Value}");
|
||||
await _next.Invoke(context);
|
||||
return;
|
||||
}
|
||||
@ -45,7 +45,7 @@ namespace Ocelot.RateLimit.Middleware
|
||||
// check white list
|
||||
if (IsWhitelisted(identity, options))
|
||||
{
|
||||
Logger.LogInformation($"{context.DownstreamReRoute.DownstreamPathTemplate.Value} is white listed from rate limiting");
|
||||
Logger.LogInformation($"{context.DownstreamReRoute.DownstreamDownstreamPathTemplate.Value} is white listed from rate limiting");
|
||||
await _next.Invoke(context);
|
||||
return;
|
||||
}
|
||||
@ -112,7 +112,7 @@ namespace Ocelot.RateLimit.Middleware
|
||||
public virtual void LogBlockedRequest(HttpContext httpContext, ClientRequestIdentity identity, RateLimitCounter counter, RateLimitRule rule, DownstreamReRoute downstreamReRoute)
|
||||
{
|
||||
Logger.LogInformation(
|
||||
$"Request {identity.HttpVerb}:{identity.Path} from ClientId {identity.ClientId} has been blocked, quota {rule.Limit}/{rule.Period} exceeded by {counter.TotalRequests}. Blocked by rule { downstreamReRoute.UpstreamPathTemplate.Value }, TraceIdentifier {httpContext.TraceIdentifier}.");
|
||||
$"Request {identity.HttpVerb}:{identity.Path} from ClientId {identity.ClientId} has been blocked, quota {rule.Limit}/{rule.Period} exceeded by {counter.TotalRequests}. Blocked by rule { downstreamReRoute.UpstreamPathTemplate.OriginalValue }, TraceIdentifier {httpContext.TraceIdentifier}.");
|
||||
}
|
||||
|
||||
public virtual Task ReturnQuotaExceededResponse(HttpContext httpContext, RateLimitOptions option, string retryAfter)
|
||||
|
@ -13,7 +13,7 @@ namespace Ocelot.Requester
|
||||
private readonly IDelegatingHandlerHandlerFactory _factory;
|
||||
private readonly IHttpClientCache _cacheHandlers;
|
||||
private readonly IOcelotLogger _logger;
|
||||
private string _cacheKey;
|
||||
private DownstreamReRoute _cacheKey;
|
||||
private HttpClient _httpClient;
|
||||
private IHttpClient _client;
|
||||
private readonly TimeSpan _defaultTimeout;
|
||||
@ -34,7 +34,7 @@ namespace Ocelot.Requester
|
||||
|
||||
public IHttpClient Create(DownstreamContext context)
|
||||
{
|
||||
_cacheKey = GetCacheKey(context);
|
||||
_cacheKey = context.DownstreamReRoute;
|
||||
|
||||
var httpClient = _cacheHandlers.Get(_cacheKey);
|
||||
|
||||
@ -51,7 +51,7 @@ namespace Ocelot.Requester
|
||||
handler.ServerCertificateCustomValidationCallback = (request, certificate, chain, errors) => true;
|
||||
|
||||
_logger
|
||||
.LogWarning($"You have ignored all SSL warnings by using DangerousAcceptAnyServerCertificateValidator for this DownstreamReRoute, UpstreamPathTemplate: {context.DownstreamReRoute.UpstreamPathTemplate}, DownstreamPathTemplate: {context.DownstreamReRoute.DownstreamPathTemplate}");
|
||||
.LogWarning($"You have ignored all SSL warnings by using DangerousAcceptAnyServerCertificateValidator for this DownstreamReRoute, UpstreamPathTemplate: {context.DownstreamReRoute.UpstreamPathTemplate}, DownstreamDownstreamPathTemplate: {context.DownstreamReRoute.DownstreamDownstreamPathTemplate}");
|
||||
}
|
||||
|
||||
var timeout = context.DownstreamReRoute.QosOptions.TimeoutValue == 0
|
||||
@ -127,14 +127,5 @@ namespace Ocelot.Requester
|
||||
});
|
||||
return httpMessageHandler;
|
||||
}
|
||||
|
||||
private string GetCacheKey(DownstreamContext request)
|
||||
{
|
||||
var cacheKey = $"{request.DownstreamRequest.Method}:{request.DownstreamRequest.OriginalString}";
|
||||
|
||||
_logger.LogDebug($"Cache key for request is {cacheKey}");
|
||||
|
||||
return cacheKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
namespace Ocelot.Requester
|
||||
{
|
||||
using System;
|
||||
using Configuration;
|
||||
|
||||
public interface IHttpClientCache
|
||||
{
|
||||
IHttpClient Get(string key);
|
||||
void Set(string key, IHttpClient handler, TimeSpan expirationTime);
|
||||
IHttpClient Get(DownstreamReRoute key);
|
||||
void Set(DownstreamReRoute key, IHttpClient handler, TimeSpan expirationTime);
|
||||
}
|
||||
}
|
||||
|
@ -2,22 +2,23 @@
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Configuration;
|
||||
|
||||
public class MemoryHttpClientCache : IHttpClientCache
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, IHttpClient> _httpClientsCache;
|
||||
private readonly ConcurrentDictionary<DownstreamReRoute, IHttpClient> _httpClientsCache;
|
||||
|
||||
public MemoryHttpClientCache()
|
||||
{
|
||||
_httpClientsCache = new ConcurrentDictionary<string, IHttpClient>();
|
||||
_httpClientsCache = new ConcurrentDictionary<DownstreamReRoute, IHttpClient>();
|
||||
}
|
||||
|
||||
public void Set(string key, IHttpClient client, TimeSpan expirationTime)
|
||||
public void Set(DownstreamReRoute key, IHttpClient client, TimeSpan expirationTime)
|
||||
{
|
||||
_httpClientsCache.AddOrUpdate(key, client, (k, oldValue) => client);
|
||||
}
|
||||
|
||||
public IHttpClient Get(string key)
|
||||
public IHttpClient Get(DownstreamReRoute key)
|
||||
{
|
||||
//todo handle error?
|
||||
return _httpClientsCache.TryGetValue(key, out var client) ? client : null;
|
||||
|
@ -27,7 +27,7 @@ namespace Ocelot.Requester.QoS
|
||||
return new OkResponse<DelegatingHandler>(handler(request, _ocelotLoggerFactory));
|
||||
}
|
||||
|
||||
return new ErrorResponse<DelegatingHandler>(new UnableToFindQoSProviderError($"could not find qosProvider for {request.DownstreamScheme}{request.DownstreamAddresses}{request.DownstreamPathTemplate}"));
|
||||
return new ErrorResponse<DelegatingHandler>(new UnableToFindQoSProviderError($"could not find qosProvider for {request.DownstreamScheme}{request.DownstreamAddresses}{request.DownstreamDownstreamPathTemplate}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
namespace Ocelot.Values
|
||||
{
|
||||
public class PathTemplate
|
||||
{
|
||||
public PathTemplate(string value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public string Value { get; }
|
||||
}
|
||||
}
|
||||
namespace Ocelot.Values
|
||||
{
|
||||
public class DownstreamPathTemplate
|
||||
{
|
||||
public DownstreamPathTemplate(string value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public string Value { get; }
|
||||
}
|
||||
}
|
@ -2,16 +2,20 @@ namespace Ocelot.Values
|
||||
{
|
||||
public class UpstreamPathTemplate
|
||||
{
|
||||
public UpstreamPathTemplate(string template, int priority, bool containsQueryString)
|
||||
public UpstreamPathTemplate(string template, int priority, bool containsQueryString, string originalValue)
|
||||
{
|
||||
Template = template;
|
||||
Priority = priority;
|
||||
ContainsQueryString = containsQueryString;
|
||||
OriginalValue = originalValue;
|
||||
}
|
||||
|
||||
public string Template { get; }
|
||||
|
||||
public int Priority { get; }
|
||||
public int Priority { get; }
|
||||
|
||||
public bool ContainsQueryString { get; }
|
||||
|
||||
public string OriginalValue { get; }
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user