mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 06:48:16 +08:00
@ -1,84 +1,93 @@
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Values;
|
||||
|
||||
namespace Ocelot.Configuration.Creator
|
||||
{
|
||||
public class UpstreamTemplatePatternCreator : IUpstreamTemplatePatternCreator
|
||||
{
|
||||
private const string RegExMatchOneOrMoreOfEverything = ".+";
|
||||
private const string RegExMatchEndString = "$";
|
||||
private const string RegExIgnoreCase = "(?i)";
|
||||
private const string RegExForwardSlashOnly = "^/$";
|
||||
private const string RegExForwardSlashAndOnePlaceHolder = "^/.*";
|
||||
|
||||
public UpstreamPathTemplate Create(IReRoute reRoute)
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Values;
|
||||
|
||||
namespace Ocelot.Configuration.Creator
|
||||
{
|
||||
public class UpstreamTemplatePatternCreator : IUpstreamTemplatePatternCreator
|
||||
{
|
||||
private const string RegExMatchOneOrMoreOfEverything = ".+";
|
||||
private const string RegExMatchOneOrMoreOfEverythingUntilNextForwardSlash = "[^/]+";
|
||||
private const string RegExMatchEndString = "$";
|
||||
private const string RegExIgnoreCase = "(?i)";
|
||||
private const string RegExForwardSlashOnly = "^/$";
|
||||
private const string RegExForwardSlashAndOnePlaceHolder = "^/.*";
|
||||
|
||||
public UpstreamPathTemplate Create(IReRoute reRoute)
|
||||
{
|
||||
var upstreamTemplate = reRoute.UpstreamPathTemplate;
|
||||
|
||||
|
||||
var placeholders = new List<string>();
|
||||
|
||||
for (var i = 0; i < upstreamTemplate.Length; i++)
|
||||
{
|
||||
if (IsPlaceHolder(upstreamTemplate, i))
|
||||
{
|
||||
var postitionOfPlaceHolderClosingBracket = upstreamTemplate.IndexOf('}', i);
|
||||
var difference = postitionOfPlaceHolderClosingBracket - i + 1;
|
||||
var placeHolderName = upstreamTemplate.Substring(i, difference);
|
||||
placeholders.Add(placeHolderName);
|
||||
|
||||
//hack to handle /{url} case
|
||||
if(ForwardSlashAndOnePlaceHolder(upstreamTemplate, placeholders, postitionOfPlaceHolderClosingBracket))
|
||||
{
|
||||
return new UpstreamPathTemplate(RegExForwardSlashAndOnePlaceHolder, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
var placeholders = new List<string>();
|
||||
|
||||
for (var i = 0; i < upstreamTemplate.Length; i++)
|
||||
{
|
||||
if (IsPlaceHolder(upstreamTemplate, i))
|
||||
{
|
||||
var postitionOfPlaceHolderClosingBracket = upstreamTemplate.IndexOf('}', i);
|
||||
var difference = postitionOfPlaceHolderClosingBracket - i + 1;
|
||||
var placeHolderName = upstreamTemplate.Substring(i, difference);
|
||||
placeholders.Add(placeHolderName);
|
||||
|
||||
//hack to handle /{url} case
|
||||
if(ForwardSlashAndOnePlaceHolder(upstreamTemplate, placeholders, postitionOfPlaceHolderClosingBracket))
|
||||
{
|
||||
return new UpstreamPathTemplate(RegExForwardSlashAndOnePlaceHolder, 0, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var containsQueryString = false;
|
||||
|
||||
if (upstreamTemplate.Contains("?"))
|
||||
{
|
||||
containsQueryString = true;
|
||||
upstreamTemplate = upstreamTemplate.Replace("?", "\\?");
|
||||
}
|
||||
|
||||
foreach (var placeholder in placeholders)
|
||||
{
|
||||
upstreamTemplate = upstreamTemplate.Replace(placeholder, RegExMatchOneOrMoreOfEverything);
|
||||
}
|
||||
|
||||
if (upstreamTemplate == "/")
|
||||
{
|
||||
return new UpstreamPathTemplate(RegExForwardSlashOnly, reRoute.Priority, containsQueryString);
|
||||
}
|
||||
|
||||
if(upstreamTemplate.EndsWith("/"))
|
||||
{
|
||||
upstreamTemplate = upstreamTemplate.Remove(upstreamTemplate.Length -1, 1) + "(/|)";
|
||||
}
|
||||
|
||||
var route = reRoute.ReRouteIsCaseSensitive
|
||||
? $"^{upstreamTemplate}{RegExMatchEndString}"
|
||||
: $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}";
|
||||
|
||||
return new UpstreamPathTemplate(route, reRoute.Priority, containsQueryString);
|
||||
}
|
||||
|
||||
private bool ForwardSlashAndOnePlaceHolder(string upstreamTemplate, List<string> placeholders, int postitionOfPlaceHolderClosingBracket)
|
||||
{
|
||||
if(upstreamTemplate.Substring(0, 2) == "/{" && placeholders.Count == 1 && upstreamTemplate.Length == postitionOfPlaceHolderClosingBracket + 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsPlaceHolder(string upstreamTemplate, int i)
|
||||
{
|
||||
return upstreamTemplate[i] == '{';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var containsQueryString = false;
|
||||
|
||||
if (upstreamTemplate.Contains("?"))
|
||||
{
|
||||
containsQueryString = true;
|
||||
upstreamTemplate = upstreamTemplate.Replace("?", "\\?");
|
||||
}
|
||||
|
||||
for (int i = 0; i < placeholders.Count; i++)
|
||||
{
|
||||
var indexOfPlaceholder = upstreamTemplate.IndexOf(placeholders[i]);
|
||||
var indexOfNextForwardSlash = upstreamTemplate.IndexOf("/", indexOfPlaceholder);
|
||||
if(indexOfNextForwardSlash < indexOfPlaceholder || (containsQueryString && upstreamTemplate.IndexOf("?") < upstreamTemplate.IndexOf(placeholders[i])))
|
||||
{
|
||||
upstreamTemplate = upstreamTemplate.Replace(placeholders[i], RegExMatchOneOrMoreOfEverything);
|
||||
}
|
||||
else
|
||||
{
|
||||
upstreamTemplate = upstreamTemplate.Replace(placeholders[i], RegExMatchOneOrMoreOfEverythingUntilNextForwardSlash);
|
||||
}
|
||||
}
|
||||
|
||||
if (upstreamTemplate == "/")
|
||||
{
|
||||
return new UpstreamPathTemplate(RegExForwardSlashOnly, reRoute.Priority, containsQueryString);
|
||||
}
|
||||
|
||||
if(upstreamTemplate.EndsWith("/"))
|
||||
{
|
||||
upstreamTemplate = upstreamTemplate.Remove(upstreamTemplate.Length -1, 1) + "(/|)";
|
||||
}
|
||||
|
||||
var route = reRoute.ReRouteIsCaseSensitive
|
||||
? $"^{upstreamTemplate}{RegExMatchEndString}"
|
||||
: $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}";
|
||||
|
||||
return new UpstreamPathTemplate(route, reRoute.Priority, containsQueryString);
|
||||
}
|
||||
|
||||
private bool ForwardSlashAndOnePlaceHolder(string upstreamTemplate, List<string> placeholders, int postitionOfPlaceHolderClosingBracket)
|
||||
{
|
||||
if(upstreamTemplate.Substring(0, 2) == "/{" && placeholders.Count == 1 && upstreamTemplate.Length == postitionOfPlaceHolderClosingBracket + 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsPlaceHolder(string upstreamTemplate, int i)
|
||||
{
|
||||
return upstreamTemplate[i] == '{';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user