mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-10-31 14:45:28 +08:00 
			
		
		
		
	Merge branch 'pitming-feature/MethodTransformer'
This commit is contained in:
		| @@ -24,6 +24,7 @@ Here is an example ReRoute configuration, You don't need to set all of these thi | ||||
|             "UpstreamHttpMethod": [ | ||||
|                 "Get" | ||||
|             ], | ||||
|             "DownstreamHttpMethod": "", | ||||
|             "AddHeadersToRequest": {}, | ||||
|             "AddClaimsToRequest": {}, | ||||
|             "RouteClaimsRequirement": {}, | ||||
|   | ||||
							
								
								
									
										28
									
								
								docs/features/methodtransformation.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								docs/features/methodtransformation.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| HTTP Method Transformation | ||||
| ========================== | ||||
|  | ||||
| Ocelot allows the user to change the HTTP request method that will be used when making a request to a downstream service. | ||||
|  | ||||
| This achieved by setting the following ReRoute configuration: | ||||
|  | ||||
| .. code-block:: json | ||||
|  | ||||
| { | ||||
|     "DownstreamPathTemplate": "/{url}", | ||||
|     "UpstreamPathTemplate": "/{url}", | ||||
|     "UpstreamHttpMethod": [ | ||||
|         "Get" | ||||
|     ], | ||||
|     "DownstreamHttpMethod": "POST", | ||||
|     "DownstreamScheme": "http", | ||||
|     "DownstreamHostAndPorts": [ | ||||
|         { | ||||
|             "Host": "localhost", | ||||
|             "Port": 53271 | ||||
|         } | ||||
|     ], | ||||
| } | ||||
|  | ||||
| The key property here is DownstreamHttpMethod which is set as POST and the ReRoute will only match on GET as set by UpstreamHttpMethod. | ||||
|  | ||||
| This feature can be useful when interacting with downstream apis that only support POST and you want to present some kind of RESTful interface. | ||||
| @@ -1,6 +1,7 @@ | ||||
| using Microsoft.AspNetCore.Builder; | ||||
| using Microsoft.AspNetCore.Hosting; | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
| using Microsoft.Extensions.Hosting; | ||||
| using Ocelot.DependencyInjection; | ||||
| using Ocelot.Middleware; | ||||
| using Ocelot.Provider.Kubernetes; | ||||
| @@ -18,7 +19,7 @@ namespace ApiGateway | ||||
|         } | ||||
|  | ||||
|         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | ||||
|         public void Configure(IApplicationBuilder app, IHostingEnvironment env) | ||||
|         public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | ||||
|         { | ||||
|             if (env.IsDevelopment()) | ||||
|             { | ||||
|   | ||||
| @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Hosting; | ||||
| using Microsoft.AspNetCore.Mvc; | ||||
| using Microsoft.Extensions.Configuration; | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
| using Microsoft.Extensions.Hosting; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Microsoft.Extensions.Options; | ||||
|  | ||||
| @@ -28,7 +29,7 @@ namespace DownstreamService | ||||
|         } | ||||
|  | ||||
|         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | ||||
|         public void Configure(IApplicationBuilder app, IHostingEnvironment env) | ||||
|         public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | ||||
|         { | ||||
|             if (env.IsDevelopment()) | ||||
|             { | ||||
|   | ||||
| @@ -41,6 +41,7 @@ namespace Ocelot.Configuration.Builder | ||||
|         private List<AddHeader> _addHeadersToUpstream; | ||||
|         private bool _dangerousAcceptAnyServerCertificateValidator; | ||||
|         private SecurityOptions _securityOptions; | ||||
|         private string _downstreamHttpMethod; | ||||
|  | ||||
|         public DownstreamReRouteBuilder() | ||||
|         { | ||||
| @@ -56,6 +57,12 @@ namespace Ocelot.Configuration.Builder | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public DownstreamReRouteBuilder WithDownStreamHttpMethod(string method) | ||||
|         { | ||||
|             _downstreamHttpMethod = method; | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public DownstreamReRouteBuilder WithLoadBalancerOptions(LoadBalancerOptions loadBalancerOptions) | ||||
|         { | ||||
|             _loadBalancerOptions = loadBalancerOptions; | ||||
| @@ -282,7 +289,8 @@ namespace Ocelot.Configuration.Builder | ||||
|                 _addHeadersToDownstream, | ||||
|                 _addHeadersToUpstream, | ||||
|                 _dangerousAcceptAnyServerCertificateValidator, | ||||
|                 _securityOptions); | ||||
|                 _securityOptions, | ||||
|                 _downstreamHttpMethod); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -138,6 +138,7 @@ namespace Ocelot.Configuration.Creator | ||||
|                 .WithAddHeadersToUpstream(hAndRs.AddHeadersToUpstream) | ||||
|                 .WithDangerousAcceptAnyServerCertificateValidator(fileReRoute.DangerousAcceptAnyServerCertificateValidator) | ||||
|                 .WithSecurityOptions(securityOptions) | ||||
|                 .WithDownStreamHttpMethod(fileReRoute.DownstreamHttpMethod) | ||||
|                 .Build(); | ||||
|  | ||||
|             return reRoute; | ||||
|   | ||||
| @@ -38,7 +38,8 @@ namespace Ocelot.Configuration | ||||
|             List<AddHeader> addHeadersToDownstream, | ||||
|             List<AddHeader> addHeadersToUpstream, | ||||
|             bool dangerousAcceptAnyServerCertificateValidator, | ||||
|             SecurityOptions securityOptions) | ||||
|             SecurityOptions securityOptions, | ||||
|             string downstreamHttpMethod) | ||||
|         { | ||||
|             DangerousAcceptAnyServerCertificateValidator = dangerousAcceptAnyServerCertificateValidator; | ||||
|             AddHeadersToDownstream = addHeadersToDownstream; | ||||
| @@ -72,6 +73,7 @@ namespace Ocelot.Configuration | ||||
|             LoadBalancerKey = loadBalancerKey; | ||||
|             AddHeadersToUpstream = addHeadersToUpstream; | ||||
|             SecurityOptions = securityOptions; | ||||
|             DownstreamHttpMethod = downstreamHttpMethod; | ||||
|         } | ||||
|  | ||||
|         public string Key { get; } | ||||
| @@ -106,5 +108,6 @@ namespace Ocelot.Configuration | ||||
|         public List<AddHeader> AddHeadersToUpstream { get; } | ||||
|         public bool DangerousAcceptAnyServerCertificateValidator { get; } | ||||
|         public SecurityOptions SecurityOptions { get; } | ||||
|         public string DownstreamHttpMethod { get; } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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; } | ||||
|   | ||||
| @@ -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,14 +16,14 @@ | ||||
|     { | ||||
|         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), | ||||
|                     Method = MapMethod(request, downstreamReRoute), | ||||
|                     RequestUri = MapUri(request) | ||||
|                 }; | ||||
|  | ||||
| @@ -71,8 +72,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 | ||||
|   | ||||
							
								
								
									
										158
									
								
								test/Ocelot.AcceptanceTests/MethodTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								test/Ocelot.AcceptanceTests/MethodTests.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,158 @@ | ||||
| namespace Ocelot.AcceptanceTests | ||||
| { | ||||
|     using Microsoft.AspNetCore.Http; | ||||
|     using Ocelot.Configuration.File; | ||||
|     using System; | ||||
|     using System.Collections.Generic; | ||||
|     using System.IO; | ||||
|     using System.Net; | ||||
|     using System.Net.Http; | ||||
|     using TestStack.BDDfy; | ||||
|     using Xunit; | ||||
|  | ||||
|     public class MethodTests : IDisposable | ||||
|     { | ||||
|         private readonly Steps _steps; | ||||
|         private readonly ServiceHandler _serviceHandler; | ||||
|  | ||||
|         public MethodTests() | ||||
|         { | ||||
|             _serviceHandler = new ServiceHandler(); | ||||
|             _steps = new Steps(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_return_response_200_when_get_converted_to_post() | ||||
|         { | ||||
|             var configuration = new FileConfiguration | ||||
|             { | ||||
|                 ReRoutes = new List<FileReRoute> | ||||
|                     { | ||||
|                         new FileReRoute | ||||
|                         { | ||||
|                             DownstreamPathTemplate = "/{url}", | ||||
|                             DownstreamScheme = "http", | ||||
|                             UpstreamPathTemplate = "/{url}", | ||||
|                             UpstreamHttpMethod = new List<string> { "Get" }, | ||||
|                             DownstreamHostAndPorts = new List<FileHostAndPort> | ||||
|                             { | ||||
|                                 new FileHostAndPort | ||||
|                                 { | ||||
|                                     Host = "localhost", | ||||
|                                     Port = 53171, | ||||
|                                 }, | ||||
|                             }, | ||||
|                             DownstreamHttpMethod = "POST", | ||||
|                         }, | ||||
|                     }, | ||||
|             }; | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:53171/", "/", "POST")) | ||||
|                 .And(x => _steps.GivenThereIsAConfiguration(configuration)) | ||||
|                 .And(x => _steps.GivenOcelotIsRunning()) | ||||
|                 .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) | ||||
|                 .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_return_response_200_when_get_converted_to_post_with_content() | ||||
|         { | ||||
|             var configuration = new FileConfiguration | ||||
|             { | ||||
|                 ReRoutes = new List<FileReRoute> | ||||
|                 { | ||||
|                     new FileReRoute | ||||
|                     { | ||||
|                         DownstreamPathTemplate = "/{url}", | ||||
|                         DownstreamScheme = "http", | ||||
|                         UpstreamPathTemplate = "/{url}", | ||||
|                         UpstreamHttpMethod = new List<string> { "Get" }, | ||||
|                         DownstreamHostAndPorts = new List<FileHostAndPort> | ||||
|                         { | ||||
|                             new FileHostAndPort | ||||
|                             { | ||||
|                                 Host = "localhost", | ||||
|                                 Port = 53271, | ||||
|                             }, | ||||
|                         }, | ||||
|                         DownstreamHttpMethod = "POST", | ||||
|                     }, | ||||
|                 }, | ||||
|             }; | ||||
|  | ||||
|             const string expected = "here is some content"; | ||||
|             var httpContent = new StringContent(expected); | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:53271/", "/", "POST")) | ||||
|                 .And(x => _steps.GivenThereIsAConfiguration(configuration)) | ||||
|                 .And(x => _steps.GivenOcelotIsRunning()) | ||||
|                 .When(x => _steps.WhenIGetUrlOnTheApiGateway("/", httpContent)) | ||||
|                 .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) | ||||
|                 .And(_ => _steps.ThenTheResponseBodyShouldBe(expected)) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_return_response_200_when_get_converted_to_get_with_content() | ||||
|         { | ||||
|             var configuration = new FileConfiguration | ||||
|             { | ||||
|                 ReRoutes = new List<FileReRoute> | ||||
|                 { | ||||
|                     new FileReRoute | ||||
|                     { | ||||
|                         DownstreamPathTemplate = "/{url}", | ||||
|                         DownstreamScheme = "http", | ||||
|                         UpstreamPathTemplate = "/{url}", | ||||
|                         UpstreamHttpMethod = new List<string> { "Post" }, | ||||
|                         DownstreamHostAndPorts = new List<FileHostAndPort> | ||||
|                         { | ||||
|                             new FileHostAndPort | ||||
|                             { | ||||
|                                 Host = "localhost", | ||||
|                                 Port = 53272, | ||||
|                             }, | ||||
|                         }, | ||||
|                         DownstreamHttpMethod = "GET", | ||||
|                     }, | ||||
|                 }, | ||||
|             }; | ||||
|  | ||||
|             const string expected = "here is some content"; | ||||
|             var httpContent = new StringContent(expected); | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:53272/", "/", "GET")) | ||||
|                 .And(x => _steps.GivenThereIsAConfiguration(configuration)) | ||||
|                 .And(x => _steps.GivenOcelotIsRunning()) | ||||
|                 .When(x => _steps.WhenIPostUrlOnTheApiGateway("/", httpContent)) | ||||
|                 .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) | ||||
|                 .And(_ => _steps.ThenTheResponseBodyShouldBe(expected)) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, string expected) | ||||
|         { | ||||
|             _serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context => | ||||
|             { | ||||
|                 if (context.Request.Method == expected) | ||||
|                 { | ||||
|                     context.Response.StatusCode = 200; | ||||
|                     var reader = new StreamReader(context.Request.Body); | ||||
|                     var body = await reader.ReadToEndAsync(); | ||||
|                     await context.Response.WriteAsync(body); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     context.Response.StatusCode = 500; | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         public void Dispose() | ||||
|         { | ||||
|             _serviceHandler.Dispose(); | ||||
|             _steps.Dispose(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -909,6 +909,18 @@ namespace Ocelot.AcceptanceTests | ||||
|             _response = _ocelotClient.GetAsync(url).Result; | ||||
|         } | ||||
|  | ||||
|         public void WhenIGetUrlOnTheApiGateway(string url, HttpContent content) | ||||
|         { | ||||
|             var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, url) {Content = content}; | ||||
|             _response = _ocelotClient.SendAsync(httpRequestMessage).Result; | ||||
|         } | ||||
|  | ||||
|         public void WhenIPostUrlOnTheApiGateway(string url, HttpContent content) | ||||
|         { | ||||
|             var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, url) { Content = content }; | ||||
|             _response = _ocelotClient.SendAsync(httpRequestMessage).Result; | ||||
|         } | ||||
|  | ||||
|         public void WhenIGetUrlOnTheApiGateway(string url, string cookie, string value) | ||||
|         { | ||||
|             var request = _ocelotServer.CreateRequest(url); | ||||
|   | ||||
| @@ -1,6 +1,4 @@ | ||||
| using Ocelot.Middleware; | ||||
|  | ||||
| namespace Ocelot.UnitTests.Request | ||||
| namespace Ocelot.UnitTests.Request | ||||
| { | ||||
|     using Microsoft.AspNetCore.Http; | ||||
|     using Moq; | ||||
| @@ -9,9 +7,12 @@ namespace Ocelot.UnitTests.Request | ||||
|     using Ocelot.Request.Creator; | ||||
|     using Ocelot.Request.Mapper; | ||||
|     using Ocelot.Request.Middleware; | ||||
|     using Ocelot.Configuration.Builder; | ||||
|     using Ocelot.Middleware; | ||||
|     using Ocelot.Responses; | ||||
|     using Shouldly; | ||||
|     using System.Net.Http; | ||||
|     using Ocelot.Configuration; | ||||
|     using TestStack.BDDfy; | ||||
|     using Xunit; | ||||
|  | ||||
| @@ -65,6 +66,20 @@ namespace Ocelot.UnitTests.Request | ||||
|                 .Then(_ => ThenTheContexRequestIsMappedToADownstreamRequest()) | ||||
|                 .And(_ => ThenTheDownstreamRequestIsStored()) | ||||
|                 .And(_ => ThenTheNextMiddlewareIsInvoked()) | ||||
|                 .And(_ => ThenTheDownstreamRequestMethodIs("GET")) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void Should_map_downstream_reroute_method_to_downstream_request() | ||||
|         { | ||||
|             this.Given(_ => GivenTheHttpContextContainsARequest()) | ||||
|                 .And(_ => GivenTheMapperWillReturnAMappedRequest()) | ||||
|                 .When(_ => WhenTheMiddlewareIsInvoked()) | ||||
|                 .Then(_ => ThenTheContexRequestIsMappedToADownstreamRequest()) | ||||
|                 .And(_ => ThenTheDownstreamRequestIsStored()) | ||||
|                 .And(_ => ThenTheNextMiddlewareIsInvoked()) | ||||
|                 .And(_ => ThenTheDownstreamRequestMethodIs("GET")) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
| @@ -80,6 +95,11 @@ namespace Ocelot.UnitTests.Request | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         private void ThenTheDownstreamRequestMethodIs(string expected) | ||||
|         { | ||||
|             _downstreamContext.DownstreamRequest.Method.ShouldBe(expected); | ||||
|         } | ||||
|  | ||||
|         private void GivenTheHttpContextContainsARequest() | ||||
|         { | ||||
|             _httpContext | ||||
| @@ -92,7 +112,7 @@ namespace Ocelot.UnitTests.Request | ||||
|             _mappedRequest = new OkResponse<HttpRequestMessage>(new HttpRequestMessage(HttpMethod.Get, "http://www.bbc.co.uk")); | ||||
|  | ||||
|             _requestMapper | ||||
|                 .Setup(rm => rm.Map(It.IsAny<HttpRequest>())) | ||||
|                 .Setup(rm => rm.Map(It.IsAny<HttpRequest>(), It.IsAny<DownstreamReRoute>())) | ||||
|                 .ReturnsAsync(_mappedRequest); | ||||
|         } | ||||
|  | ||||
| @@ -101,7 +121,7 @@ namespace Ocelot.UnitTests.Request | ||||
|             _mappedRequest = new ErrorResponse<HttpRequestMessage>(new UnmappableRequestError(new System.Exception("boooom!"))); | ||||
|  | ||||
|             _requestMapper | ||||
|                 .Setup(rm => rm.Map(It.IsAny<HttpRequest>())) | ||||
|                 .Setup(rm => rm.Map(It.IsAny<HttpRequest>(), It.IsAny<DownstreamReRoute>())) | ||||
|                 .ReturnsAsync(_mappedRequest); | ||||
|         } | ||||
|  | ||||
| @@ -112,7 +132,7 @@ namespace Ocelot.UnitTests.Request | ||||
|  | ||||
|         private void ThenTheContexRequestIsMappedToADownstreamRequest() | ||||
|         { | ||||
|             _requestMapper.Verify(rm => rm.Map(_httpRequest.Object), Times.Once); | ||||
|             _requestMapper.Verify(rm => rm.Map(_httpRequest.Object, _downstreamContext.DownstreamReRoute), Times.Once); | ||||
|         } | ||||
|  | ||||
|         private void ThenTheDownstreamRequestIsStored() | ||||
|   | ||||
| @@ -13,6 +13,8 @@ | ||||
|     using System.Security.Cryptography; | ||||
|     using System.Text; | ||||
|     using System.Threading.Tasks; | ||||
|     using Ocelot.Configuration; | ||||
|     using Ocelot.Configuration.Builder; | ||||
|     using TestStack.BDDfy; | ||||
|     using Xunit; | ||||
|  | ||||
| @@ -27,6 +29,8 @@ | ||||
|  | ||||
|         private List<KeyValuePair<string, StringValues>> _inputHeaders = null; | ||||
|  | ||||
|         private DownstreamReRoute _downstreamReRoute; | ||||
|  | ||||
|         public RequestMapperTests() | ||||
|         { | ||||
|             _httpContext = new DefaultHttpContext(); | ||||
| @@ -82,6 +86,21 @@ | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Theory] | ||||
|         [InlineData("", "GET")] | ||||
|         [InlineData(null, "GET")] | ||||
|         [InlineData("POST", "POST")] | ||||
|         public void Should_use_downstream_reroute_method_if_set(string input, string expected) | ||||
|         { | ||||
|             this.Given(_ => GivenTheInputRequestHasMethod("GET")) | ||||
|                 .And(_ => GivenTheDownstreamReRouteMethodIs(input)) | ||||
|                 .And(_ => GivenTheInputRequestHasAValidUri()) | ||||
|                 .When(_ => WhenMapped()) | ||||
|                 .Then(_ => ThenNoErrorIsReturned()) | ||||
|                 .And(_ => ThenTheMappedRequestHasMethod(expected)) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void Should_map_all_headers() | ||||
|         { | ||||
| @@ -154,16 +173,6 @@ | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         private void GivenTheInputRequestHasNoContentLength() | ||||
|         { | ||||
|             _inputRequest.ContentLength = null; | ||||
|         } | ||||
|  | ||||
|         private void GivenTheInputRequestHasNoContentType() | ||||
|         { | ||||
|             _inputRequest.ContentType = null; | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void Should_map_content_headers() | ||||
|         { | ||||
| @@ -212,6 +221,22 @@ | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         private void GivenTheDownstreamReRouteMethodIs(string input) | ||||
|         { | ||||
|             _downstreamReRoute = new DownstreamReRouteBuilder().WithDownStreamHttpMethod(input).Build(); | ||||
|         } | ||||
|  | ||||
|         private void GivenTheInputRequestHasNoContentLength() | ||||
|         { | ||||
|             _inputRequest.ContentLength = null; | ||||
|         } | ||||
|  | ||||
|         private void GivenTheInputRequestHasNoContentType() | ||||
|         { | ||||
|             _inputRequest.ContentType = null; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         private void ThenTheContentHeadersAreNotAddedToNonContentHeaders() | ||||
|         { | ||||
|             _mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-Disposition"); | ||||
| @@ -380,7 +405,7 @@ | ||||
|  | ||||
|         private async Task WhenMapped() | ||||
|         { | ||||
|             _mappedRequest = await _requestMapper.Map(_inputRequest); | ||||
|             _mappedRequest = await _requestMapper.Map(_inputRequest, _downstreamReRoute); | ||||
|         } | ||||
|  | ||||
|         private void ThenNoErrorIsReturned() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 TomPallister
					TomPallister