mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 00:38:16 +08:00
Added ability to strip claims and forward to downstream service as headers
This commit is contained in:
@ -1,4 +1,6 @@
|
||||
namespace Ocelot.Library.Builder
|
||||
using Ocelot.Library.RequestBuilder;
|
||||
|
||||
namespace Ocelot.Library.Builder
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Configuration;
|
||||
@ -16,6 +18,7 @@
|
||||
private List<string> _additionalScopes;
|
||||
private bool _requireHttps;
|
||||
private string _scopeSecret;
|
||||
private List<ConfigurationHeaderExtractorProperties> _configHeaderExtractorProperties;
|
||||
|
||||
public ReRouteBuilder()
|
||||
{
|
||||
@ -86,9 +89,15 @@
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReRouteBuilder WithConfigurationHeaderExtractorProperties(List<ConfigurationHeaderExtractorProperties> input)
|
||||
{
|
||||
_configHeaderExtractorProperties = input;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReRoute Build()
|
||||
{
|
||||
return new ReRoute(_downstreamTemplate, _upstreamTemplate, _upstreamHttpMethod, _upstreamTemplatePattern, _isAuthenticated, new AuthenticationOptions(_authenticationProvider, _authenticationProviderUrl, _scopeName, _requireHttps, _additionalScopes, _scopeSecret));
|
||||
return new ReRoute(_downstreamTemplate, _upstreamTemplate, _upstreamHttpMethod, _upstreamTemplatePattern, _isAuthenticated, new AuthenticationOptions(_authenticationProvider, _authenticationProviderUrl, _scopeName, _requireHttps, _additionalScopes, _scopeSecret), _configHeaderExtractorProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,8 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ocelot.Library.RequestBuilder;
|
||||
|
||||
namespace Ocelot.Library.Configuration
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
@ -11,11 +16,18 @@ namespace Ocelot.Library.Configuration
|
||||
private readonly List<ReRoute> _reRoutes;
|
||||
private const string RegExMatchEverything = ".*";
|
||||
private const string RegExMatchEndString = "$";
|
||||
private readonly IConfigurationHeaderExtrator _configurationHeaderExtrator;
|
||||
private readonly ILogger<OcelotConfiguration> _logger;
|
||||
|
||||
public OcelotConfiguration(IOptions<YamlConfiguration> options, IConfigurationValidator configurationValidator)
|
||||
public OcelotConfiguration(IOptions<YamlConfiguration> options,
|
||||
IConfigurationValidator configurationValidator,
|
||||
IConfigurationHeaderExtrator configurationHeaderExtrator,
|
||||
ILogger<OcelotConfiguration> logger)
|
||||
{
|
||||
_options = options;
|
||||
_configurationValidator = configurationValidator;
|
||||
_configurationHeaderExtrator = configurationHeaderExtrator;
|
||||
_logger = logger;
|
||||
_reRoutes = new List<ReRoute>();
|
||||
SetUpConfiguration();
|
||||
}
|
||||
@ -43,7 +55,7 @@ namespace Ocelot.Library.Configuration
|
||||
|
||||
var placeholders = new List<string>();
|
||||
|
||||
for (int i = 0; i < upstreamTemplate.Length; i++)
|
||||
for (var i = 0; i < upstreamTemplate.Length; i++)
|
||||
{
|
||||
if (IsPlaceHolder(upstreamTemplate, i))
|
||||
{
|
||||
@ -70,17 +82,41 @@ namespace Ocelot.Library.Configuration
|
||||
reRoute.AuthenticationOptions.RequireHttps, reRoute.AuthenticationOptions.AdditionalScopes,
|
||||
reRoute.AuthenticationOptions.ScopeSecret);
|
||||
|
||||
var configHeaders = GetHeadersToAddToRequest(reRoute);
|
||||
|
||||
_reRoutes.Add(new ReRoute(reRoute.DownstreamTemplate, reRoute.UpstreamTemplate,
|
||||
reRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated, authOptionsForRoute
|
||||
reRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated,
|
||||
authOptionsForRoute, configHeaders
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
_reRoutes.Add(new ReRoute(reRoute.DownstreamTemplate, reRoute.UpstreamTemplate, reRoute.UpstreamHttpMethod,
|
||||
upstreamTemplate, isAuthenticated, null));
|
||||
upstreamTemplate, isAuthenticated, null, new List<ConfigurationHeaderExtractorProperties>()));
|
||||
}
|
||||
}
|
||||
|
||||
private List<ConfigurationHeaderExtractorProperties> GetHeadersToAddToRequest(YamlReRoute reRoute)
|
||||
{
|
||||
var configHeaders = new List<ConfigurationHeaderExtractorProperties>();
|
||||
|
||||
foreach (var add in reRoute.AddHeadersToRequest)
|
||||
{
|
||||
var configurationHeader = _configurationHeaderExtrator.Extract(add.Key, add.Value);
|
||||
|
||||
if (configurationHeader.IsError)
|
||||
{
|
||||
_logger.LogCritical(new EventId(1, "Application Failed to start"),
|
||||
$"Unable to extract configuration for key: {add.Key} and value: {add.Value} your configuration file is incorrect");
|
||||
|
||||
throw new Exception(configurationHeader.Errors[0].Message);
|
||||
}
|
||||
configHeaders.Add(configurationHeader.Data);
|
||||
}
|
||||
|
||||
return configHeaders;
|
||||
}
|
||||
|
||||
private bool IsPlaceHolder(string upstreamTemplate, int i)
|
||||
{
|
||||
return upstreamTemplate[i] == '{';
|
||||
|
@ -1,8 +1,11 @@
|
||||
namespace Ocelot.Library.Configuration
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Library.RequestBuilder;
|
||||
|
||||
namespace Ocelot.Library.Configuration
|
||||
{
|
||||
public class ReRoute
|
||||
{
|
||||
public ReRoute(string downstreamTemplate, string upstreamTemplate, string upstreamHttpMethod, string upstreamTemplatePattern, bool isAuthenticated, AuthenticationOptions authenticationOptions)
|
||||
public ReRoute(string downstreamTemplate, string upstreamTemplate, string upstreamHttpMethod, string upstreamTemplatePattern, bool isAuthenticated, AuthenticationOptions authenticationOptions, List<ConfigurationHeaderExtractorProperties> configurationHeaderExtractorProperties)
|
||||
{
|
||||
DownstreamTemplate = downstreamTemplate;
|
||||
UpstreamTemplate = upstreamTemplate;
|
||||
@ -10,6 +13,8 @@
|
||||
UpstreamTemplatePattern = upstreamTemplatePattern;
|
||||
IsAuthenticated = isAuthenticated;
|
||||
AuthenticationOptions = authenticationOptions;
|
||||
ConfigurationHeaderExtractorProperties = configurationHeaderExtractorProperties
|
||||
?? new List<ConfigurationHeaderExtractorProperties>();
|
||||
}
|
||||
|
||||
public string DownstreamTemplate { get; private set; }
|
||||
@ -18,5 +23,6 @@
|
||||
public string UpstreamHttpMethod { get; private set; }
|
||||
public bool IsAuthenticated { get; private set; }
|
||||
public AuthenticationOptions AuthenticationOptions { get; private set; }
|
||||
public List<ConfigurationHeaderExtractorProperties> ConfigurationHeaderExtractorProperties { get; private set; }
|
||||
}
|
||||
}
|
@ -13,6 +13,6 @@
|
||||
public string UpstreamTemplate { get; set; }
|
||||
public string UpstreamHttpMethod { get; set; }
|
||||
public YamlAuthenticationOptions AuthenticationOptions { get; set; }
|
||||
public Dictionary<string,string> AddHeadersToRequest { get; set; }
|
||||
public Dictionary<string, string> AddHeadersToRequest { get; set; }
|
||||
}
|
||||
}
|
@ -21,6 +21,9 @@
|
||||
services.Configure<YamlConfiguration>(configurationRoot);
|
||||
|
||||
// Add framework services.
|
||||
services.AddSingleton<IAddHeadersToRequest, AddHeadersToRequest>();
|
||||
services.AddSingleton<IClaimsParser, ClaimsParser>();
|
||||
services.AddSingleton<IConfigurationHeaderExtrator, ConfigurationHeaderExtrator>();
|
||||
services.AddSingleton<IConfigurationValidator, ConfigurationValidator>();
|
||||
services.AddSingleton<IOcelotConfiguration, OcelotConfiguration>();
|
||||
services.AddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>();
|
||||
|
@ -10,6 +10,10 @@
|
||||
CannotFindDataError,
|
||||
UnableToCompleteRequestError,
|
||||
UnableToCreateAuthenticationHandlerError,
|
||||
UnsupportedAuthenticationProviderError
|
||||
UnsupportedAuthenticationProviderError,
|
||||
CannotFindClaimError,
|
||||
ParsingConfigurationHeaderError,
|
||||
NoInstructionsError,
|
||||
InstructionNotForClaimsError
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Repository;
|
||||
|
||||
public class ClaimsParserMiddleware : OcelotMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
|
||||
public ClaimsParserMiddleware(RequestDelegate next, IScopedRequestDataRepository scopedRequestDataRepository)
|
||||
: base(scopedRequestDataRepository)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Ocelot.Library.DownstreamRouteFinder;
|
||||
using Ocelot.Library.RequestBuilder;
|
||||
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Repository;
|
||||
|
||||
public class HttpRequestHeadersBuilderMiddleware : OcelotMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IAddHeadersToRequest _addHeadersToRequest;
|
||||
private readonly IScopedRequestDataRepository _scopedRequestDataRepository;
|
||||
|
||||
public HttpRequestHeadersBuilderMiddleware(RequestDelegate next,
|
||||
IScopedRequestDataRepository scopedRequestDataRepository,
|
||||
IAddHeadersToRequest addHeadersToRequest)
|
||||
: base(scopedRequestDataRepository)
|
||||
{
|
||||
_next = next;
|
||||
_addHeadersToRequest = addHeadersToRequest;
|
||||
_scopedRequestDataRepository = scopedRequestDataRepository;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
var downstreamRoute = _scopedRequestDataRepository.Get<DownstreamRoute>("DownstreamRoute");
|
||||
|
||||
if (downstreamRoute.Data.ReRoute.ConfigurationHeaderExtractorProperties.Any())
|
||||
{
|
||||
_addHeadersToRequest.SetHeadersOnContext(downstreamRoute.Data.ReRoute.ConfigurationHeaderExtractorProperties, context);
|
||||
}
|
||||
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
public static class HttpRequestHeadersBuilderMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseHttpRequestHeadersBuilderMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<HttpRequestHeadersBuilderMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
@ -12,6 +12,8 @@
|
||||
|
||||
builder.UseAuthenticationMiddleware();
|
||||
|
||||
builder.UseHttpRequestHeadersBuilderMiddleware();
|
||||
|
||||
builder.UseDownstreamUrlCreatorMiddleware();
|
||||
|
||||
builder.UseHttpRequestBuilderMiddleware();
|
||||
|
42
src/Ocelot.Library/RequestBuilder/AddHeadersToRequest.cs
Normal file
42
src/Ocelot.Library/RequestBuilder/AddHeadersToRequest.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Ocelot.Library.Responses;
|
||||
|
||||
namespace Ocelot.Library.RequestBuilder
|
||||
{
|
||||
public class AddHeadersToRequest : IAddHeadersToRequest
|
||||
{
|
||||
private readonly IClaimsParser _claimsParser;
|
||||
|
||||
public AddHeadersToRequest(IClaimsParser claimsParser)
|
||||
{
|
||||
_claimsParser = claimsParser;
|
||||
}
|
||||
|
||||
public Response SetHeadersOnContext(List<ConfigurationHeaderExtractorProperties> configurationHeaderExtractorProperties, HttpContext context)
|
||||
{
|
||||
foreach (var config in configurationHeaderExtractorProperties)
|
||||
{
|
||||
var value = _claimsParser.GetValue(context.User.Claims, config.ClaimKey, config.Delimiter, config.Index);
|
||||
|
||||
if (value.IsError)
|
||||
{
|
||||
return new ErrorResponse(value.Errors);
|
||||
}
|
||||
|
||||
var exists = context.Request.Headers.FirstOrDefault(x => x.Key == config.HeaderKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(exists.Key))
|
||||
{
|
||||
context.Request.Headers.Remove(exists);
|
||||
}
|
||||
|
||||
context.Request.Headers.Add(config.HeaderKey, new StringValues(value.Data));
|
||||
}
|
||||
|
||||
return new OkResponse();
|
||||
}
|
||||
}
|
||||
}
|
12
src/Ocelot.Library/RequestBuilder/CannotFindClaimError.cs
Normal file
12
src/Ocelot.Library/RequestBuilder/CannotFindClaimError.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using Ocelot.Library.Errors;
|
||||
|
||||
namespace Ocelot.Library.RequestBuilder
|
||||
{
|
||||
public class CannotFindClaimError : Error
|
||||
{
|
||||
public CannotFindClaimError(string message)
|
||||
: base(message, OcelotErrorCode.CannotFindClaimError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
55
src/Ocelot.Library/RequestBuilder/ClaimsParser.cs
Normal file
55
src/Ocelot.Library/RequestBuilder/ClaimsParser.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using Ocelot.Library.Errors;
|
||||
using Ocelot.Library.Responses;
|
||||
|
||||
namespace Ocelot.Library.RequestBuilder
|
||||
{
|
||||
public class ClaimsParser : IClaimsParser
|
||||
{
|
||||
public Response<string> GetValue(IEnumerable<Claim> claims, string key, string delimiter, int index)
|
||||
{
|
||||
var claimResponse = GetValue(claims, key);
|
||||
|
||||
if (claimResponse.IsError)
|
||||
{
|
||||
return claimResponse;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(delimiter))
|
||||
{
|
||||
return claimResponse;
|
||||
}
|
||||
|
||||
var splits = claimResponse.Data.Split(delimiter.ToCharArray());
|
||||
|
||||
if (splits.Length < index || index < 0)
|
||||
{
|
||||
return new ErrorResponse<string>(new List<Error>
|
||||
{
|
||||
new CannotFindClaimError($"Cannot find claim for key: {key}, delimiter: {delimiter}, index: {index}")
|
||||
});
|
||||
}
|
||||
|
||||
var value = splits[index];
|
||||
|
||||
return new OkResponse<string>(value);
|
||||
}
|
||||
|
||||
private Response<string> GetValue(IEnumerable<Claim> claims, string key)
|
||||
{
|
||||
var claim = claims.FirstOrDefault(c => c.Type == key);
|
||||
|
||||
if (claim != null)
|
||||
{
|
||||
return new OkResponse<string>(claim.Value);
|
||||
}
|
||||
|
||||
return new ErrorResponse<string>(new List<Error>
|
||||
{
|
||||
new CannotFindClaimError($"Cannot find claim for key: {key}")
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
namespace Ocelot.Library.RequestBuilder
|
||||
{
|
||||
public class ConfigurationHeaderExtractorProperties
|
||||
{
|
||||
public ConfigurationHeaderExtractorProperties(string headerKey, string claimKey, string delimiter, int index)
|
||||
{
|
||||
ClaimKey = claimKey;
|
||||
Delimiter = delimiter;
|
||||
Index = index;
|
||||
HeaderKey = headerKey;
|
||||
}
|
||||
|
||||
public string HeaderKey { get; private set; }
|
||||
public string ClaimKey { get; private set; }
|
||||
public string Delimiter { get; private set; }
|
||||
public int Index { get; private set; }
|
||||
}
|
||||
}
|
73
src/Ocelot.Library/RequestBuilder/HeaderExtrator.cs
Normal file
73
src/Ocelot.Library/RequestBuilder/HeaderExtrator.cs
Normal file
@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using Ocelot.Library.Errors;
|
||||
using Ocelot.Library.Responses;
|
||||
|
||||
namespace Ocelot.Library.RequestBuilder
|
||||
{
|
||||
public class ConfigurationHeaderExtrator : IConfigurationHeaderExtrator
|
||||
{
|
||||
private readonly Regex _claimRegex = new Regex("Claims\\[.*\\]");
|
||||
private readonly Regex _indexRegex = new Regex("value\\[.*\\]");
|
||||
private const string SplitToken = ">";
|
||||
|
||||
public Response<ConfigurationHeaderExtractorProperties> Extract(string headerKey, string value)
|
||||
{
|
||||
try
|
||||
{
|
||||
var instructions = value.Split(SplitToken.ToCharArray());
|
||||
|
||||
if (instructions.Length <= 1)
|
||||
{
|
||||
return new ErrorResponse<ConfigurationHeaderExtractorProperties>(
|
||||
new List<Error>
|
||||
{
|
||||
new NoInstructionsError(SplitToken)
|
||||
});
|
||||
}
|
||||
|
||||
var claimMatch = _claimRegex.IsMatch(instructions[0]);
|
||||
|
||||
if (!claimMatch)
|
||||
{
|
||||
return new ErrorResponse<ConfigurationHeaderExtractorProperties>(
|
||||
new List<Error>
|
||||
{
|
||||
new InstructionNotForClaimsError()
|
||||
});
|
||||
}
|
||||
|
||||
var claimKey = GetIndexValue(instructions[0]);
|
||||
var index = 0;
|
||||
var delimiter = string.Empty;
|
||||
|
||||
if (instructions.Length > 2 && _indexRegex.IsMatch(instructions[1]))
|
||||
{
|
||||
index = int.Parse(GetIndexValue(instructions[1]));
|
||||
delimiter = instructions[2].Trim();
|
||||
}
|
||||
|
||||
return new OkResponse<ConfigurationHeaderExtractorProperties>(
|
||||
new ConfigurationHeaderExtractorProperties(headerKey, claimKey, delimiter, index));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
return new ErrorResponse<ConfigurationHeaderExtractorProperties>(
|
||||
new List<Error>
|
||||
{
|
||||
new ParsingConfigurationHeaderError(exception)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private string GetIndexValue(string instruction)
|
||||
{
|
||||
var firstIndexer = instruction.IndexOf("[", StringComparison.Ordinal);
|
||||
var lastIndexer = instruction.IndexOf("]", StringComparison.Ordinal);
|
||||
var length = lastIndexer - firstIndexer;
|
||||
var claimKey = instruction.Substring(firstIndexer + 1, length - 1);
|
||||
return claimKey;
|
||||
}
|
||||
}
|
||||
}
|
12
src/Ocelot.Library/RequestBuilder/IAddHeadersToRequest.cs
Normal file
12
src/Ocelot.Library/RequestBuilder/IAddHeadersToRequest.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.Library.Responses;
|
||||
|
||||
namespace Ocelot.Library.RequestBuilder
|
||||
{
|
||||
public interface IAddHeadersToRequest
|
||||
{
|
||||
Response SetHeadersOnContext(List<ConfigurationHeaderExtractorProperties> configurationHeaderExtractorProperties,
|
||||
HttpContext context);
|
||||
}
|
||||
}
|
11
src/Ocelot.Library/RequestBuilder/IClaimsParser.cs
Normal file
11
src/Ocelot.Library/RequestBuilder/IClaimsParser.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using Ocelot.Library.Responses;
|
||||
|
||||
namespace Ocelot.Library.RequestBuilder
|
||||
{
|
||||
public interface IClaimsParser
|
||||
{
|
||||
Response<string> GetValue(IEnumerable<Claim> claims, string key, string delimiter, int index);
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Library.Responses;
|
||||
|
||||
namespace Ocelot.Library.RequestBuilder
|
||||
{
|
||||
public interface IConfigurationHeaderExtrator
|
||||
{
|
||||
Response<ConfigurationHeaderExtractorProperties> Extract(string headerKey, string value);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
using Ocelot.Library.Errors;
|
||||
|
||||
namespace Ocelot.Library.RequestBuilder
|
||||
{
|
||||
public class InstructionNotForClaimsError : Error
|
||||
{
|
||||
public InstructionNotForClaimsError()
|
||||
: base("instructions did not contain claims, at the moment we only support claims extraction", OcelotErrorCode.InstructionNotForClaimsError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
12
src/Ocelot.Library/RequestBuilder/NoInstructionsError.cs
Normal file
12
src/Ocelot.Library/RequestBuilder/NoInstructionsError.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using Ocelot.Library.Errors;
|
||||
|
||||
namespace Ocelot.Library.RequestBuilder
|
||||
{
|
||||
public class NoInstructionsError : Error
|
||||
{
|
||||
public NoInstructionsError(string splitToken)
|
||||
: base($"There we no instructions splitting on {splitToken}", OcelotErrorCode.NoInstructionsError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using Ocelot.Library.Errors;
|
||||
|
||||
namespace Ocelot.Library.RequestBuilder
|
||||
{
|
||||
public class ParsingConfigurationHeaderError : Error
|
||||
{
|
||||
public ParsingConfigurationHeaderError(Exception exception)
|
||||
: base($"error parsing configuration eception is {exception.Message}", OcelotErrorCode.ParsingConfigurationHeaderError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -12,18 +12,14 @@
|
||||
{
|
||||
public async Task<HttpContext> CreateResponse(HttpContext context, HttpResponseMessage response)
|
||||
{
|
||||
if (response.IsSuccessStatusCode)
|
||||
context.Response.OnStarting(x =>
|
||||
{
|
||||
context.Response.OnStarting(x =>
|
||||
{
|
||||
context.Response.StatusCode = (int)response.StatusCode;
|
||||
return Task.CompletedTask;
|
||||
}, context);
|
||||
context.Response.StatusCode = (int)response.StatusCode;
|
||||
return Task.CompletedTask;
|
||||
}, context);
|
||||
|
||||
await context.Response.WriteAsync(await response.Content.ReadAsStringAsync());
|
||||
return context;
|
||||
}
|
||||
return context;
|
||||
await context.Response.WriteAsync(await response.Content.ReadAsStringAsync());
|
||||
return context;
|
||||
}
|
||||
|
||||
public async Task<HttpContext> CreateErrorResponse(HttpContext context, int statusCode)
|
||||
|
Reference in New Issue
Block a user