mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-10-31 23:15:28 +08:00 
			
		
		
		
	made a response middlware as terminating middleware...
This commit is contained in:
		| @@ -3,13 +3,14 @@ using System.IO; | ||||
| using System.Net; | ||||
| using System.Net.Http; | ||||
| using System.Net.Http.Headers; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| 
 | ||||
| namespace Ocelot.Library.Infrastructure.RequestBuilder | ||||
| { | ||||
|     public class RequestBuilder : IRequestBuilder | ||||
|     public class HttpRequestBuilder : IRequestBuilder | ||||
|     { | ||||
|         public Request Build(string httpMethod, string downstreamUrl, Stream content, IHeaderDictionary headers, | ||||
|         public async Task<Request> Build(string httpMethod, string downstreamUrl, Stream content, IHeaderDictionary headers, | ||||
|             IRequestCookieCollection cookies, string queryString, string contentType) | ||||
|         { | ||||
|             var method = new HttpMethod(httpMethod); | ||||
| @@ -20,7 +21,11 @@ namespace Ocelot.Library.Infrastructure.RequestBuilder | ||||
| 
 | ||||
|             if (content != null) | ||||
|             { | ||||
|                 httpRequestMessage.Content = new StreamContent(content); | ||||
|                 using (var reader = new StreamReader(content)) | ||||
|                 { | ||||
|                     var body = await reader.ReadToEndAsync(); | ||||
|                     httpRequestMessage.Content = new StringContent(body); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             if (!string.IsNullOrEmpty(contentType)) | ||||
| @@ -41,7 +46,11 @@ namespace Ocelot.Library.Infrastructure.RequestBuilder | ||||
|             { | ||||
|                 foreach (var header in headers) | ||||
|                 { | ||||
|                     httpRequestMessage.Headers.Add(header.Key, header.Value.ToArray()); | ||||
|                     //todo get rid of if.. | ||||
|                     if (header.Key.ToLower() != "host") | ||||
|                     { | ||||
|                         httpRequestMessage.Headers.Add(header.Key, header.Value.ToArray()); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
| @@ -1,11 +1,12 @@ | ||||
| using System.IO; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Http; | ||||
|  | ||||
| namespace Ocelot.Library.Infrastructure.RequestBuilder | ||||
| { | ||||
|     public interface IRequestBuilder | ||||
|     { | ||||
|         Request Build(string httpMethod, | ||||
|         Task<Request> Build(string httpMethod, | ||||
|             string downstreamUrl, | ||||
|             Stream content, | ||||
|             IHeaderDictionary headers, | ||||
|   | ||||
| @@ -1,17 +1,32 @@ | ||||
| using System.Net.Http; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Net.Http; | ||||
| using System.Threading.Tasks; | ||||
| using Ocelot.Library.Infrastructure.RequestBuilder; | ||||
| using Ocelot.Library.Infrastructure.Responses; | ||||
|  | ||||
| namespace Ocelot.Library.Infrastructure.Requester | ||||
| { | ||||
|     public class HttpClientHttpRequester : IHttpRequester | ||||
|     { | ||||
|         public async Task<HttpResponseMessage> GetResponse(Request request) | ||||
|         public async Task<Response<HttpResponseMessage>> GetResponse(Request request) | ||||
|         { | ||||
|             using (var handler = new HttpClientHandler { CookieContainer = request.CookieContainer }) | ||||
|             using (var httpClient = new HttpClient(handler)) | ||||
|             { | ||||
|                 return await httpClient.SendAsync(request.HttpRequestMessage); | ||||
|                 try | ||||
|                 { | ||||
|                     var response = await httpClient.SendAsync(request.HttpRequestMessage); | ||||
|                     return new OkResponse<HttpResponseMessage>(response); | ||||
|                 } | ||||
|                 catch (Exception exception) | ||||
|                 { | ||||
|                     return | ||||
|                         new ErrorResponse<HttpResponseMessage>(new List<Error> | ||||
|                         { | ||||
|                             new UnableToCompleteRequestError(exception) | ||||
|                         }); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -1,11 +1,12 @@ | ||||
| using System.Net.Http; | ||||
| using System.Threading.Tasks; | ||||
| using Ocelot.Library.Infrastructure.RequestBuilder; | ||||
| using Ocelot.Library.Infrastructure.Responses; | ||||
|  | ||||
| namespace Ocelot.Library.Infrastructure.Requester | ||||
| { | ||||
|     public interface IHttpRequester | ||||
|     { | ||||
|         Task<HttpResponseMessage> GetResponse(Request request); | ||||
|         Task<Response<HttpResponseMessage>> GetResponse(Request request); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,13 @@ | ||||
| using System; | ||||
| using Ocelot.Library.Infrastructure.Responses; | ||||
|  | ||||
| namespace Ocelot.Library.Infrastructure.Requester | ||||
| { | ||||
|     public class UnableToCompleteRequestError : Error | ||||
|     { | ||||
|         public UnableToCompleteRequestError(Exception exception)  | ||||
|             : base($"Error making http request, exception: {exception.Message}") | ||||
|         { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -11,7 +11,12 @@ namespace Ocelot.Library.Infrastructure.Responder | ||||
|         { | ||||
|             if (response.IsSuccessStatusCode) | ||||
|             { | ||||
|                 context.Response.StatusCode = (int)response.StatusCode; | ||||
|                 context.Response.OnStarting(x => | ||||
|                 { | ||||
|                     context.Response.StatusCode = (int)response.StatusCode; | ||||
|                     return Task.CompletedTask; | ||||
|                 }, context); | ||||
|  | ||||
|                 await context.Response.WriteAsync(await response.Content.ReadAsStringAsync()); | ||||
|                 return context; | ||||
|             } | ||||
| @@ -20,7 +25,11 @@ namespace Ocelot.Library.Infrastructure.Responder | ||||
|  | ||||
|         public async Task<HttpContext> CreateNotFoundResponse(HttpContext context) | ||||
|         { | ||||
|             context.Response.StatusCode = (int)HttpStatusCode.NotFound; | ||||
|             context.Response.OnStarting(x => | ||||
|             { | ||||
|                 context.Response.StatusCode = (int)HttpStatusCode.NotFound; | ||||
|                 return Task.CompletedTask; | ||||
|             }, context); | ||||
|             return context; | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -2,6 +2,6 @@ namespace Ocelot.Library.Infrastructure.UrlMatcher | ||||
| { | ||||
|      public interface IUrlPathToUrlTemplateMatcher | ||||
|      { | ||||
|         UrlMatch Match(string upstreamUrlPath, string upstreamUrlTemplate); | ||||
|         UrlMatch Match(string upstreamUrlPath, string upstreamUrlPathTemplate); | ||||
|      } | ||||
| }  | ||||
| @@ -5,21 +5,26 @@ namespace Ocelot.Library.Infrastructure.UrlMatcher | ||||
| { | ||||
|      public class UrlPathToUrlTemplateMatcher : IUrlPathToUrlTemplateMatcher | ||||
|     { | ||||
|         public UrlMatch Match(string upstreamUrlPath, string upstreamUrlTemplate) | ||||
|         public UrlMatch Match(string upstreamUrlPath, string upstreamUrlPathTemplate) | ||||
|         { | ||||
|             var urlPathTemplateCopy = upstreamUrlTemplate; | ||||
|             if (upstreamUrlPath.Length > upstreamUrlPathTemplate.Length) | ||||
|             { | ||||
|                 return new UrlMatch(false, new List<TemplateVariableNameAndValue>(), string.Empty); | ||||
|             } | ||||
|  | ||||
|             var urlPathTemplateCopy = upstreamUrlPathTemplate; | ||||
|  | ||||
|             var templateKeysAndValues = new List<TemplateVariableNameAndValue>(); | ||||
|  | ||||
|             int counterForUrl = 0; | ||||
|  | ||||
|             for (int counterForTemplate = 0; counterForTemplate < upstreamUrlTemplate.Length; counterForTemplate++) | ||||
|             for (int counterForTemplate = 0; counterForTemplate < upstreamUrlPathTemplate.Length; counterForTemplate++) | ||||
|             { | ||||
|                 if (CharactersDontMatch(upstreamUrlTemplate[counterForTemplate], upstreamUrlPath[counterForUrl]) && ContinueScanningUrl(counterForUrl,upstreamUrlPath.Length)) | ||||
|                 if (CharactersDontMatch(upstreamUrlPathTemplate[counterForTemplate], upstreamUrlPath[counterForUrl]) && ContinueScanningUrl(counterForUrl,upstreamUrlPath.Length)) | ||||
|                 { | ||||
|                     if (IsPlaceholder(upstreamUrlTemplate[counterForTemplate])) | ||||
|                     if (IsPlaceholder(upstreamUrlPathTemplate[counterForTemplate])) | ||||
|                     { | ||||
|                         var variableName = GetPlaceholderVariableName(upstreamUrlTemplate, counterForTemplate); | ||||
|                         var variableName = GetPlaceholderVariableName(upstreamUrlPathTemplate, counterForTemplate); | ||||
|                          | ||||
|                         var variableValue = GetPlaceholderVariableValue(upstreamUrlPath, counterForUrl); | ||||
|  | ||||
| @@ -27,7 +32,7 @@ namespace Ocelot.Library.Infrastructure.UrlMatcher | ||||
|  | ||||
|                         templateKeysAndValues.Add(templateVariableNameAndValue); | ||||
|  | ||||
|                         counterForTemplate = GetNextCounterPosition(upstreamUrlTemplate, counterForTemplate, '}'); | ||||
|                         counterForTemplate = GetNextCounterPosition(upstreamUrlPathTemplate, counterForTemplate, '}'); | ||||
|  | ||||
|                         counterForUrl = GetNextCounterPosition(upstreamUrlPath, counterForUrl, '/'); | ||||
|  | ||||
|   | ||||
| @@ -36,7 +36,7 @@ namespace Ocelot.Library.Middleware | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             var request = _requestBuilder | ||||
|             var request = await _requestBuilder | ||||
|               .Build(context.Request.Method, downstreamUrl.Data, context.Request.Body, | ||||
|               context.Request.Headers, context.Request.Cookies, context.Request.QueryString.Value, context.Request.ContentType); | ||||
|  | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| using System.Net.Http; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Ocelot.Library.Infrastructure.Repository; | ||||
| @@ -14,19 +15,16 @@ namespace Ocelot.Library.Middleware | ||||
|         private readonly IHttpRequester _requester; | ||||
|         private readonly IHttpResponder _responder; | ||||
|         private readonly IScopedRequestDataRepository _scopedRequestDataRepository; | ||||
|         private readonly IRequestBuilder _requestBuilder; | ||||
|  | ||||
|         public HttpRequesterMiddleware(RequestDelegate next,  | ||||
|             IHttpRequester requester,  | ||||
|             IHttpResponder responder, | ||||
|             IScopedRequestDataRepository scopedRequestDataRepository,  | ||||
|             IRequestBuilder requestBuilder) | ||||
|             IScopedRequestDataRepository scopedRequestDataRepository) | ||||
|         { | ||||
|             _next = next; | ||||
|             _requester = requester; | ||||
|             _responder = responder; | ||||
|             _scopedRequestDataRepository = scopedRequestDataRepository; | ||||
|             _requestBuilder = requestBuilder; | ||||
|         } | ||||
|  | ||||
|         public async Task Invoke(HttpContext context) | ||||
| @@ -42,8 +40,8 @@ namespace Ocelot.Library.Middleware | ||||
|             var response = await _requester | ||||
|                 .GetResponse(request.Data); | ||||
|  | ||||
|             await _responder.CreateResponse(context, response); | ||||
|  | ||||
|             _scopedRequestDataRepository.Add("Response", response.Data); | ||||
|              | ||||
|             await _next.Invoke(context); | ||||
|         } | ||||
|     } | ||||
|   | ||||
							
								
								
									
										34
									
								
								src/Ocelot.Library/Middleware/HttpResponderMiddleware.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/Ocelot.Library/Middleware/HttpResponderMiddleware.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| using System.Net.Http; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Ocelot.Library.Infrastructure.Repository; | ||||
| using Ocelot.Library.Infrastructure.Responder; | ||||
|  | ||||
| namespace Ocelot.Library.Middleware | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Terminating middleware that is responsible for returning a http response to the client | ||||
|     /// </summary> | ||||
|     public class HttpResponderMiddleware | ||||
|     { | ||||
|         private readonly RequestDelegate _next; | ||||
|         private readonly IHttpResponder _responder; | ||||
|         private readonly IScopedRequestDataRepository _scopedRequestDataRepository; | ||||
|  | ||||
|         public HttpResponderMiddleware(RequestDelegate next,  | ||||
|             IHttpResponder responder, | ||||
|             IScopedRequestDataRepository scopedRequestDataRepository) | ||||
|         { | ||||
|             _next = next; | ||||
|             _responder = responder; | ||||
|             _scopedRequestDataRepository = scopedRequestDataRepository; | ||||
|         } | ||||
|  | ||||
|         public async Task Invoke(HttpContext context) | ||||
|         { | ||||
|             var response = _scopedRequestDataRepository.Get<HttpResponseMessage>("Response"); | ||||
|  | ||||
|             await _responder.CreateResponse(context, response.Data); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,12 @@ | ||||
| using Microsoft.AspNetCore.Builder; | ||||
|  | ||||
| namespace Ocelot.Library.Middleware | ||||
| { | ||||
|     public static class HttpResponderMiddlewareExtensions | ||||
|     { | ||||
|         public static IApplicationBuilder UseHttpResponderMiddleware(this IApplicationBuilder builder) | ||||
|         { | ||||
|             return builder.UseMiddleware<HttpResponderMiddleware>(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,10 +1,5 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| using System.IO; | ||||
| using Microsoft.AspNetCore.Hosting; | ||||
| using Microsoft.AspNetCore.Builder; | ||||
|  | ||||
| namespace Ocelot | ||||
| { | ||||
|   | ||||
| @@ -44,7 +44,7 @@ namespace Ocelot | ||||
|             services.AddSingleton<IDownstreamRouteFinder, DownstreamRouteFinder>(); | ||||
|             services.AddSingleton<IHttpRequester, HttpClientHttpRequester>(); | ||||
|             services.AddSingleton<IHttpResponder, HttpContextResponder>(); | ||||
|             services.AddSingleton<IRequestBuilder, RequestBuilder>(); | ||||
|             services.AddSingleton<IRequestBuilder, HttpRequestBuilder>(); | ||||
|  | ||||
|             // see this for why we register this as singleton http://stackoverflow.com/questions/37371264/invalidoperationexception-unable-to-resolve-service-for-type-microsoft-aspnetc | ||||
|             services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); | ||||
| @@ -65,6 +65,8 @@ namespace Ocelot | ||||
|             app.UseHttpRequestBuilderMiddleware(); | ||||
|  | ||||
|             app.UseHttpRequesterMiddleware(); | ||||
|  | ||||
|             app.UseHttpResponderMiddleware(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| ReRoutes: | ||||
| - DownstreamTemplate: http://www.bbc.co.uk | ||||
| - DownstreamTemplate: http://www.mattsite.dev/ | ||||
|   UpstreamTemplate: / | ||||
|   UpstreamHttpMethod: Get | ||||
|   | ||||
| @@ -27,7 +27,7 @@ namespace Ocelot.UnitTests.RequestBuilder | ||||
|         public RequestBuilderTests() | ||||
|         { | ||||
|             _content = new StringContent(string.Empty); | ||||
|             _requestBuilder = new Library.Infrastructure.RequestBuilder.RequestBuilder(); | ||||
|             _requestBuilder = new Library.Infrastructure.RequestBuilder.HttpRequestBuilder(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
| @@ -70,7 +70,6 @@ namespace Ocelot.UnitTests.RequestBuilder | ||||
|                 .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom"))) | ||||
|                 .And(x => x.GivenTheContentTypeIs("application/json")) | ||||
|                .When(x => x.WhenICreateARequest()) | ||||
|                .And(x => x.ThenTheCorrectContentIsUsed(new StringContent("Hi from Tom"))) | ||||
|                .And(x => x.ThenTheCorrectContentHeadersAreUsed(new HeaderDictionary | ||||
|                 { | ||||
|                     { | ||||
| @@ -202,7 +201,7 @@ namespace Ocelot.UnitTests.RequestBuilder | ||||
|         private void WhenICreateARequest() | ||||
|         { | ||||
|             _result = _requestBuilder.Build(_httpMethod, _downstreamUrl, _content?.ReadAsStreamAsync().Result, _headers, | ||||
|                 _cookies, _query, _contentType); | ||||
|                 _cookies, _query, _contentType).Result; | ||||
|         } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -18,11 +18,21 @@ namespace Ocelot.UnitTests.UrlMatcher | ||||
|             _urlMatcher = new UrlPathToUrlTemplateMatcher(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_not_find_match() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("/api/values")) | ||||
|                 .And(x => x.GivenIHaveAnUpstreamUrlTemplate("/")) | ||||
|                 .When(x => x.WhenIMatchThePaths()) | ||||
|                 .And(x => x.ThenTheResultIsFalse()) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void can_match_down_stream_url() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveADownstreamPath("")) | ||||
|                 .And(x => x.GivenIHaveAnDownstreamUrlTemplate("")) | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("")) | ||||
|                 .And(x => x.GivenIHaveAnUpstreamUrlTemplate("")) | ||||
|                 .When(x => x.WhenIMatchThePaths()) | ||||
|                 .And(x => x.ThenTheResultIsTrue()) | ||||
|                 .And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>())) | ||||
| @@ -33,8 +43,8 @@ namespace Ocelot.UnitTests.UrlMatcher | ||||
|         [Fact] | ||||
|         public void can_match_down_stream_url_with_no_slash() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveADownstreamPath("api")) | ||||
|                  .Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api")) | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("api")) | ||||
|                  .Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api")) | ||||
|                  .When(x => x.WhenIMatchThePaths()) | ||||
|                  .Then(x => x.ThenTheResultIsTrue()) | ||||
|                  .And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>())) | ||||
| @@ -45,8 +55,8 @@ namespace Ocelot.UnitTests.UrlMatcher | ||||
|         [Fact] | ||||
|         public void can_match_down_stream_url_with_one_slash() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveADownstreamPath("api/")) | ||||
|                  .Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/")) | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("api/")) | ||||
|                  .Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api/")) | ||||
|                  .When(x => x.WhenIMatchThePaths()) | ||||
|                  .Then(x => x.ThenTheResultIsTrue()) | ||||
|                  .And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>())) | ||||
| @@ -57,8 +67,8 @@ namespace Ocelot.UnitTests.UrlMatcher | ||||
|         [Fact] | ||||
|         public void can_match_down_stream_url_with_downstream_template() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/")) | ||||
|               .Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/")) | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/")) | ||||
|               .Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/")) | ||||
|               .When(x => x.WhenIMatchThePaths()) | ||||
|               .Then(x => x.ThenTheResultIsTrue()) | ||||
|               .And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>())) | ||||
| @@ -66,35 +76,6 @@ namespace Ocelot.UnitTests.UrlMatcher | ||||
|               .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void can_match_down_stream_url_with_downstream_template_with_one_query_string_parameter() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/?soldout=false")) | ||||
|               .Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/")) | ||||
|               .When(x => x.WhenIMatchThePaths()) | ||||
|               .Then(x => x.ThenTheResultIsTrue()) | ||||
|               .And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>())) | ||||
|               .And(x => x.ThenTheDownstreamUrlTemplateIs("api/product/products/")) | ||||
|               .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void can_match_down_stream_url_with_downstream_template_with_one_query_string_parameter_and_one_template() | ||||
|         { | ||||
|             var expectedTemplates = new List<TemplateVariableNameAndValue>  | ||||
|             { | ||||
|                 new TemplateVariableNameAndValue("{productId}", "1") | ||||
|             }; | ||||
|  | ||||
|             this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/variants/?soldout=false")) | ||||
|               .Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/{productId}/variants/")) | ||||
|               .When(x => x.WhenIMatchThePaths()) | ||||
|               .Then(x => x.ThenTheResultIsTrue()) | ||||
|               .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates)) | ||||
|               .And(x => x.ThenTheDownstreamUrlTemplateIs("api/product/products/{productId}/variants/")) | ||||
|               .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void can_match_down_stream_url_with_downstream_template_with_one_place_holder() | ||||
|         { | ||||
| @@ -103,8 +84,8 @@ namespace Ocelot.UnitTests.UrlMatcher | ||||
|                 new TemplateVariableNameAndValue("{productId}", "1") | ||||
|             }; | ||||
|  | ||||
|             this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1")) | ||||
|                .Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/{productId}")) | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1")) | ||||
|                .Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/{productId}")) | ||||
|                .When(x => x.WhenIMatchThePaths()) | ||||
|                .Then(x => x.ThenTheResultIsTrue()) | ||||
|                .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates)) | ||||
| @@ -121,8 +102,8 @@ namespace Ocelot.UnitTests.UrlMatcher | ||||
|                 new TemplateVariableNameAndValue("{categoryId}", "2") | ||||
|             }; | ||||
|  | ||||
|             this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/2")) | ||||
|                  .Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/{productId}/{categoryId}")) | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/2")) | ||||
|                  .Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/{productId}/{categoryId}")) | ||||
|                  .When(x => x.WhenIMatchThePaths()) | ||||
|                  .Then(x => x.ThenTheResultIsTrue()) | ||||
|                  .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates)) | ||||
| @@ -139,8 +120,8 @@ namespace Ocelot.UnitTests.UrlMatcher | ||||
|                 new TemplateVariableNameAndValue("{categoryId}", "2") | ||||
|             }; | ||||
|  | ||||
|             this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/categories/2")) | ||||
|                 .And(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/{productId}/categories/{categoryId}")) | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2")) | ||||
|                 .And(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/{productId}/categories/{categoryId}")) | ||||
|                 .When(x => x.WhenIMatchThePaths()) | ||||
|                 .Then(x => x.ThenTheResultIsTrue()) | ||||
|                 .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates)) | ||||
| @@ -158,8 +139,8 @@ namespace Ocelot.UnitTests.UrlMatcher | ||||
|                 new TemplateVariableNameAndValue("{variantId}", "123") | ||||
|             }; | ||||
|  | ||||
|             this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/categories/2/variant/123")) | ||||
|                 .And(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/{productId}/categories/{categoryId}/variant/{variantId}")) | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/123")) | ||||
|                 .And(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/{productId}/categories/{categoryId}/variant/{variantId}")) | ||||
|                 .When(x => x.WhenIMatchThePaths()) | ||||
|                 .Then(x => x.ThenTheResultIsTrue()) | ||||
|                 .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates)) | ||||
| @@ -176,8 +157,8 @@ namespace Ocelot.UnitTests.UrlMatcher | ||||
|                 new TemplateVariableNameAndValue("{categoryId}", "2") | ||||
|             }; | ||||
|  | ||||
|             this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/categories/2/variant/")) | ||||
|                  .And(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/{productId}/categories/{categoryId}/variant/")) | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/")) | ||||
|                  .And(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/{productId}/categories/{categoryId}/variant/")) | ||||
|                  .When(x => x.WhenIMatchThePaths()) | ||||
|                  .Then(x => x.ThenTheResultIsTrue()) | ||||
|                  .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates)) | ||||
| @@ -199,12 +180,12 @@ namespace Ocelot.UnitTests.UrlMatcher | ||||
|         { | ||||
|             _result.DownstreamUrlTemplate.ShouldBe(expectedDownstreamUrlTemplate); | ||||
|         } | ||||
|         private void GivenIHaveADownstreamPath(string downstreamPath) | ||||
|         private void GivenIHaveAUpstreamPath(string downstreamPath) | ||||
|         { | ||||
|             _downstreamUrlPath = downstreamPath; | ||||
|         } | ||||
|  | ||||
|         private void GivenIHaveAnDownstreamUrlTemplate(string downstreamUrlTemplate) | ||||
|         private void GivenIHaveAnUpstreamUrlTemplate(string downstreamUrlTemplate) | ||||
|         { | ||||
|             _downstreamPathTemplate = downstreamUrlTemplate; | ||||
|         } | ||||
| @@ -218,5 +199,10 @@ namespace Ocelot.UnitTests.UrlMatcher | ||||
|         { | ||||
|             _result.Match.ShouldBeTrue(); | ||||
|         } | ||||
|  | ||||
|         private void ThenTheResultIsFalse() | ||||
|         { | ||||
|             _result.Match.ShouldBeFalse(); | ||||
|         } | ||||
|     } | ||||
| }  | ||||
		Reference in New Issue
	
	Block a user
	 TomPallister
					TomPallister