#451 started implementing querystring support in templates (#459)

* #451 started implementing querystring support in templates

* #451 ocelot.json back to normal and specified in docs query string wont work in upstream template

* Revert "#451 ocelot.json back to normal and specified in docs query string wont work in upstream template"

This reverts commit 563193f7b2f78bad6109484fe77f3c87de831005.

* #451 ocelot.json back to normal and specified in docs query string wont work in upstream template
This commit is contained in:
Tom Pallister
2018-07-10 18:00:17 +01:00
committed by GitHub
parent 89c3887d36
commit 75f9a8f9be
6 changed files with 1005 additions and 836 deletions

View File

@ -1,84 +1,112 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging;
using Ocelot.Middleware;
using System;
using System.Linq;
using Ocelot.DownstreamRouteFinder.Middleware;
using Ocelot.Responses;
using Ocelot.Values;
namespace Ocelot.DownstreamUrlCreator.Middleware
{
public class DownstreamUrlCreatorMiddleware : OcelotMiddleware
{
private readonly OcelotRequestDelegate _next;
private readonly IDownstreamPathPlaceholderReplacer _replacer;
public DownstreamUrlCreatorMiddleware(OcelotRequestDelegate next,
IOcelotLoggerFactory loggerFactory,
IDownstreamPathPlaceholderReplacer replacer)
:base(loggerFactory.CreateLogger<DownstreamUrlCreatorMiddleware>())
{
_next = next;
_replacer = replacer;
}
public async Task Invoke(DownstreamContext context)
{
var dsPath = _replacer
.Replace(context.DownstreamReRoute.DownstreamPathTemplate, context.TemplatePlaceholderNameAndValues);
if (dsPath.IsError)
{
Logger.LogDebug("IDownstreamPathPlaceholderReplacer returned an error, setting pipeline error");
SetPipelineError(context, dsPath.Errors);
return;
}
context.DownstreamRequest.Scheme = context.DownstreamReRoute.DownstreamScheme;
if (ServiceFabricRequest(context))
{
var pathAndQuery = CreateServiceFabricUri(context, dsPath);
context.DownstreamRequest.AbsolutePath = pathAndQuery.path;
context.DownstreamRequest.Query = pathAndQuery.query;
}
else
{
context.DownstreamRequest.AbsolutePath = dsPath.Data.Value;
}
Logger.LogDebug($"Downstream url is {context.DownstreamRequest}");
await _next.Invoke(context);
}
private (string path, string query) CreateServiceFabricUri(DownstreamContext context, Response<DownstreamPath> dsPath)
{
var query = context.DownstreamRequest.Query;
var serviceFabricPath = $"/{context.DownstreamReRoute.ServiceName + dsPath.Data.Value}";
if (RequestForStatefullService(query))
{
return (serviceFabricPath, query);
}
var split = string.IsNullOrEmpty(query) ? "?" : "&";
return (serviceFabricPath, $"{query}{split}cmd=instance");
}
private static bool ServiceFabricRequest(DownstreamContext context)
{
return context.Configuration.ServiceProviderConfiguration.Type == "ServiceFabric" && context.DownstreamReRoute.UseServiceDiscovery;
}
private static bool RequestForStatefullService(string query)
{
return query.Contains("PartitionKind") && query.Contains("PartitionKey");
}
}
}
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging;
using Ocelot.Middleware;
using System;
using System.Linq;
using Ocelot.DownstreamRouteFinder.Middleware;
using Ocelot.Responses;
using Ocelot.Values;
namespace Ocelot.DownstreamUrlCreator.Middleware
{
public class DownstreamUrlCreatorMiddleware : OcelotMiddleware
{
private readonly OcelotRequestDelegate _next;
private readonly IDownstreamPathPlaceholderReplacer _replacer;
public DownstreamUrlCreatorMiddleware(OcelotRequestDelegate next,
IOcelotLoggerFactory loggerFactory,
IDownstreamPathPlaceholderReplacer replacer)
:base(loggerFactory.CreateLogger<DownstreamUrlCreatorMiddleware>())
{
_next = next;
_replacer = replacer;
}
public async Task Invoke(DownstreamContext context)
{
var response = _replacer
.Replace(context.DownstreamReRoute.DownstreamPathTemplate, context.TemplatePlaceholderNameAndValues);
if (response.IsError)
{
Logger.LogDebug("IDownstreamPathPlaceholderReplacer returned an error, setting pipeline error");
SetPipelineError(context, response.Errors);
return;
}
context.DownstreamRequest.Scheme = context.DownstreamReRoute.DownstreamScheme;
if (ServiceFabricRequest(context))
{
var pathAndQuery = CreateServiceFabricUri(context, response);
context.DownstreamRequest.AbsolutePath = pathAndQuery.path;
context.DownstreamRequest.Query = pathAndQuery.query;
}
else
{
var dsPath = response.Data;
if(ContainsQueryString(dsPath))
{
context.DownstreamRequest.AbsolutePath = GetPath(dsPath);
context.DownstreamRequest.Query = GetQueryString(dsPath);
// todo - do we need to add anything from the request query string onto the query from the
// templae?
}
else
{
context.DownstreamRequest.AbsolutePath = dsPath.Value;
}
}
Logger.LogDebug($"Downstream url is {context.DownstreamRequest}");
await _next.Invoke(context);
}
private string GetPath(DownstreamPath dsPath)
{
return dsPath.Value.Substring(0, dsPath.Value.IndexOf("?"));
}
private string GetQueryString(DownstreamPath dsPath)
{
return dsPath.Value.Substring(dsPath.Value.IndexOf("?"));
}
private bool ContainsQueryString(DownstreamPath dsPath)
{
return dsPath.Value.Contains("?");
}
private (string path, string query) CreateServiceFabricUri(DownstreamContext context, Response<DownstreamPath> dsPath)
{
var query = context.DownstreamRequest.Query;
var serviceFabricPath = $"/{context.DownstreamReRoute.ServiceName + dsPath.Data.Value}";
if (RequestForStatefullService(query))
{
return (serviceFabricPath, query);
}
var split = string.IsNullOrEmpty(query) ? "?" : "&";
return (serviceFabricPath, $"{query}{split}cmd=instance");
}
private static bool ServiceFabricRequest(DownstreamContext context)
{
return context.Configuration.ServiceProviderConfiguration.Type == "ServiceFabric" && context.DownstreamReRoute.UseServiceDiscovery;
}
private static bool RequestForStatefullService(string query)
{
return query.Contains("PartitionKind") && query.Contains("PartitionKey");
}
}
}