mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	Made changes based on PR comments. Also added lots more tests!
This commit is contained in:
		@@ -31,6 +31,7 @@ using Ocelot.Middleware;
 | 
			
		||||
using Ocelot.QueryStrings;
 | 
			
		||||
using Ocelot.RateLimit;
 | 
			
		||||
using Ocelot.Request.Builder;
 | 
			
		||||
using Ocelot.Request.Mapper;
 | 
			
		||||
using Ocelot.Requester;
 | 
			
		||||
using Ocelot.Requester.QoS;
 | 
			
		||||
using Ocelot.Responder;
 | 
			
		||||
@@ -160,6 +161,7 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
            services.TryAddSingleton<IAuthenticationHandlerCreator, AuthenticationHandlerCreator>();
 | 
			
		||||
            services.TryAddSingleton<IRateLimitCounterHandler, MemoryCacheRateLimitCounterHandler>();
 | 
			
		||||
            services.TryAddSingleton<IHttpClientCache, MemoryHttpClientCache>();
 | 
			
		||||
            services.TryAddSingleton<IRequestMapper, RequestMapper>();
 | 
			
		||||
 | 
			
		||||
            // 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
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,7 @@
 | 
			
		||||
        UnableToFindLoadBalancerError,
 | 
			
		||||
        RequestTimedOutError,
 | 
			
		||||
        UnableToFindQoSProviderError,
 | 
			
		||||
        UnableToSetConfigInConsulError
 | 
			
		||||
        UnableToSetConfigInConsulError,
 | 
			
		||||
        UnmappableRequestError
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -53,9 +53,6 @@ namespace Ocelot.Middleware
 | 
			
		||||
        {
 | 
			
		||||
            await CreateAdministrationArea(builder);
 | 
			
		||||
 | 
			
		||||
            // Initialises downstream request
 | 
			
		||||
            builder.UseDownstreamRequestInitialiser();
 | 
			
		||||
 | 
			
		||||
            // This is registered to catch any global exceptions that are not handled
 | 
			
		||||
            builder.UseExceptionHandlerMiddleware();
 | 
			
		||||
 | 
			
		||||
@@ -65,6 +62,9 @@ namespace Ocelot.Middleware
 | 
			
		||||
            // This is registered first so it can catch any errors and issue an appropriate response
 | 
			
		||||
            builder.UseResponderMiddleware();
 | 
			
		||||
 | 
			
		||||
            // Initialises downstream request
 | 
			
		||||
            builder.UseDownstreamRequestInitialiser();
 | 
			
		||||
 | 
			
		||||
            // Then we get the downstream route information
 | 
			
		||||
            builder.UseDownstreamRouteFinderMiddleware();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								src/Ocelot/Request/Mapper/IRequestMapper.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/Ocelot/Request/Mapper/IRequestMapper.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
namespace Ocelot.Request.Mapper
 | 
			
		||||
{
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
    public interface IRequestMapper
 | 
			
		||||
    {
 | 
			
		||||
        Task<Response<HttpRequestMessage>> Map(HttpRequest request);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,33 +1,40 @@
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Microsoft.AspNetCore.Http.Extensions;
 | 
			
		||||
using Microsoft.Extensions.Primitives;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Request
 | 
			
		||||
namespace Ocelot.Request.Mapper
 | 
			
		||||
{
 | 
			
		||||
    public class Mapper
 | 
			
		||||
    using System;
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.IO;
 | 
			
		||||
    using System.Linq;
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Microsoft.AspNetCore.Http.Extensions;
 | 
			
		||||
    using Microsoft.Extensions.Primitives;
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
    public class RequestMapper : IRequestMapper
 | 
			
		||||
    {
 | 
			
		||||
        private readonly string[] _unsupportedHeaders = { "host" };
 | 
			
		||||
 | 
			
		||||
        public async Task<HttpRequestMessage> Map(HttpRequest request)
 | 
			
		||||
        public async Task<Response<HttpRequestMessage>> Map(HttpRequest request)
 | 
			
		||||
        {
 | 
			
		||||
            var requestMessage = new HttpRequestMessage()
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                Content = await MapContent(request),
 | 
			
		||||
                Method = MapMethod(request),
 | 
			
		||||
                RequestUri = MapUri(request),
 | 
			
		||||
                //Properties = null
 | 
			
		||||
                //Version = null
 | 
			
		||||
            };
 | 
			
		||||
                var requestMessage = new HttpRequestMessage()
 | 
			
		||||
                {
 | 
			
		||||
                    Content = await MapContent(request),
 | 
			
		||||
                    Method = MapMethod(request),
 | 
			
		||||
                    RequestUri = MapUri(request)
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
            MapHeaders(request, requestMessage);
 | 
			
		||||
                MapHeaders(request, requestMessage);
 | 
			
		||||
 | 
			
		||||
            return requestMessage;
 | 
			
		||||
                return new OkResponse<HttpRequestMessage>(requestMessage);
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                return new ErrorResponse<HttpRequestMessage>(new UnmappableRequestError(ex));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task<HttpContent> MapContent(HttpRequest request)
 | 
			
		||||
@@ -37,7 +44,6 @@ namespace Ocelot.Request
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            return new ByteArrayContent(await ToByteArray(request.Body));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								src/Ocelot/Request/Mapper/UnmappableRequestError.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/Ocelot/Request/Mapper/UnmappableRequestError.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
namespace Ocelot.Request.Mapper
 | 
			
		||||
{
 | 
			
		||||
    using Ocelot.Errors;
 | 
			
		||||
    using System;
 | 
			
		||||
 | 
			
		||||
    public class UnmappableRequestError : Error
 | 
			
		||||
    {
 | 
			
		||||
        public UnmappableRequestError(Exception ex) : base($"Error when parsing incoming request, exception: {ex.Message}", OcelotErrorCode.UnmappableRequestError)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,40 +1,41 @@
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
using Ocelot.Logging;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
using Ocelot.Request.Builder;
 | 
			
		||||
using Ocelot.Requester.QoS;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Request.Middleware
 | 
			
		||||
{
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
 | 
			
		||||
    using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
    using Ocelot.Logging;
 | 
			
		||||
    using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
    public class DownstreamRequestInitialiserMiddleware : OcelotMiddleware
 | 
			
		||||
    {
 | 
			
		||||
        private readonly RequestDelegate _next;
 | 
			
		||||
        private readonly IRequestCreator _requestCreator;
 | 
			
		||||
        private readonly IOcelotLogger _logger;
 | 
			
		||||
        private readonly IQosProviderHouse _qosProviderHouse;
 | 
			
		||||
        private readonly Mapper.IRequestMapper _requestMapper;
 | 
			
		||||
 | 
			
		||||
        public DownstreamRequestInitialiserMiddleware(RequestDelegate next,
 | 
			
		||||
            IOcelotLoggerFactory loggerFactory,
 | 
			
		||||
            IRequestScopedDataRepository requestScopedDataRepository, 
 | 
			
		||||
            IRequestCreator requestCreator, 
 | 
			
		||||
            IQosProviderHouse qosProviderHouse)
 | 
			
		||||
            IRequestScopedDataRepository requestScopedDataRepository,
 | 
			
		||||
            Mapper.IRequestMapper requestMapper)
 | 
			
		||||
            :base(requestScopedDataRepository)
 | 
			
		||||
        {
 | 
			
		||||
            _next = next;
 | 
			
		||||
            _requestCreator = requestCreator;
 | 
			
		||||
            _qosProviderHouse = qosProviderHouse;
 | 
			
		||||
            _logger = loggerFactory.CreateLogger<DownstreamRequestInitialiserMiddleware>();
 | 
			
		||||
            _requestMapper = requestMapper;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task Invoke(HttpContext context)
 | 
			
		||||
        {
 | 
			
		||||
            _logger.LogDebug("started calling request builder middleware");
 | 
			
		||||
 | 
			
		||||
            var mapper = new Mapper();
 | 
			
		||||
            var downstreamRequest = await _requestMapper.Map(context.Request);
 | 
			
		||||
            if (downstreamRequest.IsError)
 | 
			
		||||
            {
 | 
			
		||||
                SetPipelineError(downstreamRequest.Errors);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            SetDownstreamRequest(await mapper.Map(context.Request));
 | 
			
		||||
            SetDownstreamRequest(downstreamRequest.Data);
 | 
			
		||||
 | 
			
		||||
            _logger.LogDebug("calling next middleware");
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user