mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	Added some basic cache stuff
This commit is contained in:
		
							
								
								
									
										10
									
								
								src/Ocelot/Cache/IOcelotCache.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/Ocelot/Cache/IOcelotCache.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Cache
 | 
			
		||||
{
 | 
			
		||||
    public interface IOcelotCache<T>
 | 
			
		||||
    {
 | 
			
		||||
        void Add(string key, T value, TimeSpan ttl);
 | 
			
		||||
        T Get(string key);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								src/Ocelot/Cache/Middleware/OutputCacheMiddleware.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/Ocelot/Cache/Middleware/OutputCacheMiddleware.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Cache.Middleware
 | 
			
		||||
{
 | 
			
		||||
    public class OutputCacheMiddleware : OcelotMiddleware
 | 
			
		||||
    {
 | 
			
		||||
        private readonly RequestDelegate _next;
 | 
			
		||||
        private readonly ILogger _logger;
 | 
			
		||||
        private readonly IOcelotCache<HttpResponseMessage> _outputCache;
 | 
			
		||||
 | 
			
		||||
        public OutputCacheMiddleware(RequestDelegate next, 
 | 
			
		||||
            ILoggerFactory loggerFactory,
 | 
			
		||||
            IRequestScopedDataRepository scopedDataRepository,
 | 
			
		||||
            IOcelotCache<HttpResponseMessage> outputCache)
 | 
			
		||||
            :base(scopedDataRepository)
 | 
			
		||||
        {
 | 
			
		||||
            _next = next;
 | 
			
		||||
            _outputCache = outputCache;
 | 
			
		||||
            _logger = loggerFactory.CreateLogger<OutputCacheMiddleware>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task Invoke(HttpContext context)
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamUrlKey = DownstreamUrl;
 | 
			
		||||
 | 
			
		||||
            if (!DownstreamRoute.ReRoute.IsCached)
 | 
			
		||||
            {
 | 
			
		||||
                await _next.Invoke(context);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _logger.LogDebug("OutputCacheMiddleware.Invoke stared checking cache for downstreamUrlKey", downstreamUrlKey);
 | 
			
		||||
  
 | 
			
		||||
            var cached = _outputCache.Get(downstreamUrlKey);
 | 
			
		||||
 | 
			
		||||
            if (cached != null)
 | 
			
		||||
            {
 | 
			
		||||
                SetHttpResponseMessageThisRequest(cached);
 | 
			
		||||
 | 
			
		||||
                _logger.LogDebug("OutputCacheMiddleware.Invoke finished returned cached response for downstreamUrlKey", downstreamUrlKey);
 | 
			
		||||
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _logger.LogDebug("OutputCacheMiddleware.Invoke no resonse cached for downstreamUrlKey", downstreamUrlKey);
 | 
			
		||||
 | 
			
		||||
            await _next.Invoke(context);
 | 
			
		||||
 | 
			
		||||
            if (PipelineError())
 | 
			
		||||
            {
 | 
			
		||||
                _logger.LogDebug("OutputCacheMiddleware.Invoke there was a pipeline error for downstreamUrlKey", downstreamUrlKey);
 | 
			
		||||
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var response = HttpResponseMessage;
 | 
			
		||||
 | 
			
		||||
            _outputCache.Add(downstreamUrlKey, response, TimeSpan.FromSeconds(DownstreamRoute.ReRoute.FileCacheOptions.TtlSeconds));
 | 
			
		||||
 | 
			
		||||
            _logger.LogDebug("OutputCacheMiddleware.Invoke finished response added to cache for downstreamUrlKey", downstreamUrlKey);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,12 @@
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Cache.Middleware
 | 
			
		||||
{
 | 
			
		||||
    public static class OutputCacheMiddlewareExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static IApplicationBuilder UseOutputCacheMiddleware(this IApplicationBuilder builder)
 | 
			
		||||
        {
 | 
			
		||||
            return builder.UseMiddleware<OutputCacheMiddleware>();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								src/Ocelot/Cache/OcelotCacheManagerCache.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/Ocelot/Cache/OcelotCacheManagerCache.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
using System;
 | 
			
		||||
using CacheManager.Core;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Cache
 | 
			
		||||
{
 | 
			
		||||
    public class OcelotCacheManagerCache<T> : IOcelotCache<T>
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ICacheManager<T> _cacheManager;
 | 
			
		||||
 | 
			
		||||
        public OcelotCacheManagerCache(ICacheManager<T> cacheManager)
 | 
			
		||||
        {
 | 
			
		||||
            _cacheManager = cacheManager;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Add(string key, T value, TimeSpan ttl)
 | 
			
		||||
        {
 | 
			
		||||
            _cacheManager.Add(new CacheItem<T>(key, value, ExpirationMode.Absolute, ttl));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public T Get(string key)
 | 
			
		||||
        {
 | 
			
		||||
            return _cacheManager.Get<T>(key);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -21,6 +21,8 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
        private bool _isAuthorised;
 | 
			
		||||
        private List<ClaimToThing> _claimToQueries;
 | 
			
		||||
        private string _requestIdHeaderKey;
 | 
			
		||||
        private bool _isCached;
 | 
			
		||||
        private CacheOptions _fileCacheOptions;
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder()
 | 
			
		||||
        {
 | 
			
		||||
@@ -127,9 +129,24 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithIsCached(bool input)
 | 
			
		||||
        {
 | 
			
		||||
            _isCached = input;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithCacheOptions(CacheOptions input)
 | 
			
		||||
        {
 | 
			
		||||
            _fileCacheOptions = input;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRoute Build()
 | 
			
		||||
        {
 | 
			
		||||
            return new ReRoute(_downstreamTemplate, _upstreamTemplate, _upstreamHttpMethod, _upstreamTemplatePattern, _isAuthenticated, new AuthenticationOptions(_authenticationProvider, _authenticationProviderUrl, _scopeName, _requireHttps, _additionalScopes, _scopeSecret), _configHeaderExtractorProperties, _claimToClaims, _routeClaimRequirement, _isAuthorised, _claimToQueries, _requestIdHeaderKey);
 | 
			
		||||
            return new ReRoute(_downstreamTemplate, _upstreamTemplate, _upstreamHttpMethod, _upstreamTemplatePattern, 
 | 
			
		||||
                _isAuthenticated, new AuthenticationOptions(_authenticationProvider, _authenticationProviderUrl, _scopeName, 
 | 
			
		||||
                _requireHttps, _additionalScopes, _scopeSecret), _configHeaderExtractorProperties, _claimToClaims, _routeClaimRequirement, 
 | 
			
		||||
                _isAuthorised, _claimToQueries, _requestIdHeaderKey, _isCached, _fileCacheOptions);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								src/Ocelot/Configuration/CacheOptions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/Ocelot/Configuration/CacheOptions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
namespace Ocelot.Configuration
 | 
			
		||||
{
 | 
			
		||||
    public class CacheOptions
 | 
			
		||||
    {
 | 
			
		||||
        public CacheOptions(int ttlSeconds)
 | 
			
		||||
        {
 | 
			
		||||
            TtlSeconds = ttlSeconds;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int TtlSeconds { get; private set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -100,6 +100,8 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
 | 
			
		||||
            var isAuthorised = reRoute.RouteClaimsRequirement?.Count > 0;
 | 
			
		||||
 | 
			
		||||
            var isCached = reRoute.FileCacheOptions.TtlSeconds > 0;
 | 
			
		||||
 | 
			
		||||
            if (isAuthenticated)
 | 
			
		||||
            {
 | 
			
		||||
                var authOptionsForRoute = new AuthenticationOptions(reRoute.AuthenticationOptions.Provider,
 | 
			
		||||
@@ -115,7 +117,7 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
                    reRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated,
 | 
			
		||||
                    authOptionsForRoute, claimsToHeaders, claimsToClaims, 
 | 
			
		||||
                    reRoute.RouteClaimsRequirement, isAuthorised, claimsToQueries,
 | 
			
		||||
                    reRoute.RequestIdKey
 | 
			
		||||
                    reRoute.RequestIdKey, isCached, new CacheOptions(reRoute.FileCacheOptions.TtlSeconds)
 | 
			
		||||
                    );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -123,7 +125,7 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
                reRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated, 
 | 
			
		||||
                null, new List<ClaimToThing>(), new List<ClaimToThing>(), 
 | 
			
		||||
                reRoute.RouteClaimsRequirement, isAuthorised, new List<ClaimToThing>(),
 | 
			
		||||
                    reRoute.RequestIdKey);
 | 
			
		||||
                    reRoute.RequestIdKey, isCached, new CacheOptions(reRoute.FileCacheOptions.TtlSeconds));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private List<ClaimToThing> GetAddThingsToRequest(Dictionary<string,string> thingBeingAdded)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								src/Ocelot/Configuration/File/FileCacheOptions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/Ocelot/Configuration/File/FileCacheOptions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
namespace Ocelot.Configuration.File
 | 
			
		||||
{
 | 
			
		||||
    public class FileCacheOptions
 | 
			
		||||
    {
 | 
			
		||||
        public int TtlSeconds { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -11,6 +11,7 @@ namespace Ocelot.Configuration.File
 | 
			
		||||
            RouteClaimsRequirement = new Dictionary<string, string>();
 | 
			
		||||
            AddQueriesToRequest = new Dictionary<string, string>();
 | 
			
		||||
            AuthenticationOptions = new FileAuthenticationOptions();
 | 
			
		||||
            FileCacheOptions = new FileCacheOptions();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string DownstreamTemplate { get; set; }
 | 
			
		||||
@@ -22,5 +23,6 @@ namespace Ocelot.Configuration.File
 | 
			
		||||
        public Dictionary<string, string> RouteClaimsRequirement { get; set; }
 | 
			
		||||
        public Dictionary<string, string> AddQueriesToRequest { get; set; }
 | 
			
		||||
        public string RequestIdKey { get; set; }
 | 
			
		||||
        public FileCacheOptions FileCacheOptions { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -4,7 +4,10 @@ namespace Ocelot.Configuration
 | 
			
		||||
{
 | 
			
		||||
    public class ReRoute
 | 
			
		||||
    {
 | 
			
		||||
        public ReRoute(string downstreamTemplate, string upstreamTemplate, string upstreamHttpMethod, string upstreamTemplatePattern, bool isAuthenticated, AuthenticationOptions authenticationOptions, List<ClaimToThing> configurationHeaderExtractorProperties, List<ClaimToThing> claimsToClaims, Dictionary<string, string> routeClaimsRequirement, bool isAuthorised, List<ClaimToThing> claimsToQueries, string requestIdKey)
 | 
			
		||||
        public ReRoute(string downstreamTemplate, string upstreamTemplate, string upstreamHttpMethod, string upstreamTemplatePattern, 
 | 
			
		||||
            bool isAuthenticated, AuthenticationOptions authenticationOptions, List<ClaimToThing> configurationHeaderExtractorProperties, 
 | 
			
		||||
            List<ClaimToThing> claimsToClaims, Dictionary<string, string> routeClaimsRequirement, bool isAuthorised, List<ClaimToThing> claimsToQueries, 
 | 
			
		||||
            string requestIdKey, bool isCached, CacheOptions fileCacheOptions)
 | 
			
		||||
        {
 | 
			
		||||
            DownstreamTemplate = downstreamTemplate;
 | 
			
		||||
            UpstreamTemplate = upstreamTemplate;
 | 
			
		||||
@@ -15,6 +18,8 @@ namespace Ocelot.Configuration
 | 
			
		||||
            RouteClaimsRequirement = routeClaimsRequirement;
 | 
			
		||||
            IsAuthorised = isAuthorised;
 | 
			
		||||
            RequestIdKey = requestIdKey;
 | 
			
		||||
            IsCached = isCached;
 | 
			
		||||
            FileCacheOptions = fileCacheOptions;
 | 
			
		||||
            ClaimsToQueries = claimsToQueries
 | 
			
		||||
                ?? new List<ClaimToThing>();
 | 
			
		||||
            ClaimsToClaims = claimsToClaims 
 | 
			
		||||
@@ -35,5 +40,7 @@ namespace Ocelot.Configuration
 | 
			
		||||
        public List<ClaimToThing> ClaimsToClaims { get; private set; }
 | 
			
		||||
        public Dictionary<string, string> RouteClaimsRequirement { get; private set; }
 | 
			
		||||
        public string RequestIdKey { get; private set; }
 | 
			
		||||
        public bool IsCached { get; private set; }
 | 
			
		||||
        public CacheOptions FileCacheOptions { get; private set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +1,14 @@
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using CacheManager.Core;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Microsoft.Extensions.Configuration;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using Ocelot.Authentication.Handler.Creator;
 | 
			
		||||
using Ocelot.Authentication.Handler.Factory;
 | 
			
		||||
using Ocelot.Authorisation;
 | 
			
		||||
using Ocelot.Cache;
 | 
			
		||||
using Ocelot.Claims;
 | 
			
		||||
using Ocelot.Configuration.Creator;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
@@ -26,11 +31,21 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
{
 | 
			
		||||
    public static class ServiceCollectionExtensions
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        public static IServiceCollection AddOcelotOutputCaching(this IServiceCollection services, Action<ConfigurationBuilderCachePart> settings)
 | 
			
		||||
        {
 | 
			
		||||
            var cacheManagerOutputCache = CacheFactory.Build<HttpResponseMessage>("OcelotOutputCache", settings);
 | 
			
		||||
            var ocelotCacheManager = new OcelotCacheManagerCache<HttpResponseMessage>(cacheManagerOutputCache);
 | 
			
		||||
 | 
			
		||||
            services.AddSingleton<ICacheManager<HttpResponseMessage>>(cacheManagerOutputCache);
 | 
			
		||||
            services.AddSingleton<IOcelotCache<HttpResponseMessage>>(ocelotCacheManager);
 | 
			
		||||
 | 
			
		||||
            return services;
 | 
			
		||||
        }
 | 
			
		||||
        public static IServiceCollection AddOcelotFileConfiguration(this IServiceCollection services, IConfigurationRoot configurationRoot)
 | 
			
		||||
        {
 | 
			
		||||
            services.Configure<FileConfiguration>(configurationRoot);
 | 
			
		||||
 | 
			
		||||
            // ocelot services.
 | 
			
		||||
            services.AddSingleton<IOcelotConfigurationCreator, FileOcelotConfigurationCreator>();
 | 
			
		||||
            services.AddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>();
 | 
			
		||||
            services.AddSingleton<IConfigurationValidator, FileConfigurationValidator>();
 | 
			
		||||
@@ -40,11 +55,9 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
 | 
			
		||||
        public static IServiceCollection AddOcelot(this IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            // framework services dependency for the identity server middleware
 | 
			
		||||
            services.AddMvcCore().AddJsonFormatters();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
 | 
			
		||||
            // ocelot services.
 | 
			
		||||
            services.AddSingleton<IRemoveOutputHeaders, RemoveOutputHeaders>();
 | 
			
		||||
            services.AddSingleton<IOcelotConfigurationProvider, OcelotConfigurationProvider>();
 | 
			
		||||
            services.AddSingleton<IClaimToThingConfigurationParser, ClaimToThingConfigurationParser>();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using Ocelot.DownstreamRouteFinder;
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
@@ -59,6 +60,15 @@ namespace Ocelot.Middleware
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public HttpResponseMessage HttpResponseMessage
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                var request = _requestScopedDataRepository.Get<HttpResponseMessage>("HttpResponseMessage");
 | 
			
		||||
                return request.Data;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SetDownstreamRouteForThisRequest(DownstreamRoute downstreamRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _requestScopedDataRepository.Add("DownstreamRoute", downstreamRoute);
 | 
			
		||||
@@ -73,5 +83,11 @@ namespace Ocelot.Middleware
 | 
			
		||||
        {
 | 
			
		||||
            _requestScopedDataRepository.Add("Request", request);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SetHttpResponseMessageThisRequest(HttpResponseMessage responseMessage)
 | 
			
		||||
        {
 | 
			
		||||
            _requestScopedDataRepository.Add("HttpResponseMessage", responseMessage);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Ocelot.Authentication.Middleware;
 | 
			
		||||
using Ocelot.Cache.Middleware;
 | 
			
		||||
using Ocelot.Claims.Middleware;
 | 
			
		||||
using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
using Ocelot.DownstreamUrlCreator.Middleware;
 | 
			
		||||
@@ -99,6 +100,10 @@ namespace Ocelot.Middleware
 | 
			
		||||
            // This takes the downstream route we retrieved earlier and replaces any placeholders with the variables that should be used
 | 
			
		||||
            builder.UseDownstreamUrlCreatorMiddleware();
 | 
			
		||||
 | 
			
		||||
            // Not sure if this is the best place for this but we use the downstream url 
 | 
			
		||||
            // as the basis for our cache key.
 | 
			
		||||
            builder.UseOutputCacheMiddleware();
 | 
			
		||||
 | 
			
		||||
            // Everything should now be ready to build or HttpRequest
 | 
			
		||||
            builder.UseHttpRequestBuilderMiddleware();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,7 @@
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
using Ocelot.Responder;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Requester.Middleware
 | 
			
		||||
{
 | 
			
		||||
@@ -12,17 +9,14 @@ namespace Ocelot.Requester.Middleware
 | 
			
		||||
    {
 | 
			
		||||
        private readonly RequestDelegate _next;
 | 
			
		||||
        private readonly IHttpRequester _requester;
 | 
			
		||||
        private readonly IHttpResponder _responder;
 | 
			
		||||
 | 
			
		||||
        public HttpRequesterMiddleware(RequestDelegate next, 
 | 
			
		||||
            IHttpRequester requester, 
 | 
			
		||||
            IRequestScopedDataRepository requestScopedDataRepository, 
 | 
			
		||||
            IHttpResponder responder)
 | 
			
		||||
            IRequestScopedDataRepository requestScopedDataRepository)
 | 
			
		||||
            :base(requestScopedDataRepository)
 | 
			
		||||
        {
 | 
			
		||||
            _next = next;
 | 
			
		||||
            _requester = requester;
 | 
			
		||||
            _responder = responder;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task Invoke(HttpContext context)
 | 
			
		||||
@@ -35,12 +29,7 @@ namespace Ocelot.Requester.Middleware
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var setResponse = await _responder.SetResponseOnHttpContext(context, response.Data);
 | 
			
		||||
 | 
			
		||||
            if (setResponse.IsError)
 | 
			
		||||
            {
 | 
			
		||||
                SetPipelineError(response.Errors);
 | 
			
		||||
            }
 | 
			
		||||
            SetHttpResponseMessageThisRequest(response.Data);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -38,7 +38,7 @@ namespace Ocelot.Responder
 | 
			
		||||
                AddHeaderIfDoesntExist(context, httpResponseHeader);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var content = await response.Content.ReadAsStreamAsync();
 | 
			
		||||
            var content = await response.Content.ReadAsByteArrayAsync();
 | 
			
		||||
 | 
			
		||||
            AddHeaderIfDoesntExist(context, new KeyValuePair<string, IEnumerable<string>>("Content-Length", new []{ content.Length.ToString() }) );
 | 
			
		||||
 | 
			
		||||
@@ -52,12 +52,10 @@ namespace Ocelot.Responder
 | 
			
		||||
 | 
			
		||||
            }, context);
 | 
			
		||||
 | 
			
		||||
            using (var reader = new StreamReader(content))
 | 
			
		||||
            using (Stream stream = new MemoryStream(content))
 | 
			
		||||
            {
 | 
			
		||||
                var responseContent = reader.ReadToEnd();
 | 
			
		||||
                await context.Response.WriteAsync(responseContent);
 | 
			
		||||
                await stream.CopyToAsync(context.Response.Body);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new OkResponse();       
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
@@ -30,18 +31,32 @@ namespace Ocelot.Responder.Middleware
 | 
			
		||||
            if (PipelineError())
 | 
			
		||||
            {
 | 
			
		||||
                var errors = GetPipelineErrors();
 | 
			
		||||
                
 | 
			
		||||
                var statusCode = _codeMapper.Map(errors);
 | 
			
		||||
 | 
			
		||||
                if (!statusCode.IsError)
 | 
			
		||||
                await SetErrorResponse(context, errors);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                var setResponse = await _responder.SetResponseOnHttpContext(context, HttpResponseMessage);
 | 
			
		||||
 | 
			
		||||
                if (setResponse.IsError)
 | 
			
		||||
                {
 | 
			
		||||
                    await _responder.SetErrorResponseOnContext(context, statusCode.Data);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    await _responder.SetErrorResponseOnContext(context, 500);
 | 
			
		||||
                    await SetErrorResponse(context, setResponse.Errors);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task SetErrorResponse(HttpContext context, List<Error> errors)
 | 
			
		||||
        {
 | 
			
		||||
            var statusCode = _codeMapper.Map(errors);
 | 
			
		||||
 | 
			
		||||
            if (!statusCode.IsError)
 | 
			
		||||
            {
 | 
			
		||||
                await _responder.SetErrorResponseOnContext(context, statusCode.Data);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                await _responder.SetErrorResponseOnContext(context, 500);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -27,7 +27,10 @@
 | 
			
		||||
        "Microsoft.NETCore.App": {
 | 
			
		||||
            "version": "1.0.1",
 | 
			
		||||
            "type": "platform"
 | 
			
		||||
        }
 | 
			
		||||
        },
 | 
			
		||||
        "CacheManager.Core": "0.9.1",
 | 
			
		||||
        "CacheManager.Microsoft.Extensions.Configuration": "0.9.1",
 | 
			
		||||
        "CacheManager.Microsoft.Extensions.Logging": "0.9.1"
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "frameworks": {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user