SEBWIN-314: Completed implementation of simplified filter rule.
This commit is contained in:
parent
6d1b282b33
commit
d3272814bd
3 changed files with 909 additions and 215 deletions
|
@ -89,7 +89,7 @@ namespace SafeExamBrowser.Browser.UnitTests.Filters
|
|||
|
||||
filterComponent = path;
|
||||
if (filterComponent != null &&
|
||||
!Regex.IsMatch(URLToFilter.AbsolutePath.Trim(new char[] { '/' }), filterComponent.ToString(), RegexOptions.IgnoreCase))
|
||||
!Regex.IsMatch(URLToFilter.AbsolutePath.TrimEnd(new char[] { '/' }), filterComponent.ToString(), RegexOptions.IgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -404,8 +404,8 @@ namespace SafeExamBrowser.Browser.UnitTests.Filters
|
|||
this.password = regexMatch.Groups[3].Value;
|
||||
this.host = regexMatch.Groups[4].Value;
|
||||
|
||||
// Treat a special case when a query is interpreted as part of the host address
|
||||
if (this.host.Contains("?"))
|
||||
// Treat a special case when a query or fragment is interpreted as part of the host address
|
||||
if (this.host.Contains("?") || this.host.Contains("#"))
|
||||
{
|
||||
string splitURLRegexPattern2 = @"([^\?#]*)?(?:\?([^#]*))?(?:#(.*))?";
|
||||
Regex splitURLRegex2 = new Regex(splitURLRegexPattern2);
|
||||
|
@ -434,7 +434,7 @@ namespace SafeExamBrowser.Browser.UnitTests.Filters
|
|||
this.port = UInt16.Parse(portNumber);
|
||||
}
|
||||
|
||||
this.path = regexMatch.Groups[6].Value.Trim(new char[] { '/' });
|
||||
this.path = regexMatch.Groups[6].Value.TrimEnd(new char[] { '/' });
|
||||
this.query = regexMatch.Groups[7].Value;
|
||||
this.fragment = regexMatch.Groups[8].Value;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,16 +15,15 @@ namespace SafeExamBrowser.Browser.Filters.Rules
|
|||
{
|
||||
internal class SimplifiedRule : IRule
|
||||
{
|
||||
private const string URL_DELIMITER_PATTERN = @"(?:([^\:]*)\:\/\/)?(?:([^\:\@]*)(?:\:([^\@]*))?\@)?(?:([^\/\:]*))?(?:\:([0-9\*]*))?([^\?#]*)?(?:\?([^#]*))?(?:#(.*))?";
|
||||
private const string URL_DELIMITER_PATTERN = @"(?:([^\:]*)\://)?(?:([^\:\@]*)(?:\:([^\@]*))?\@)?(?:([^/\:\?#]*))?(?:\:([0-9\*]*))?([^\?#]*)?(?:\?([^#]*))?(?:#(.*))?";
|
||||
|
||||
private Regex fragment;
|
||||
private Regex host;
|
||||
private Regex password;
|
||||
private Regex path;
|
||||
private int? port;
|
||||
private Regex query;
|
||||
private Regex scheme;
|
||||
private Regex user;
|
||||
private Regex userInfo;
|
||||
|
||||
public FilterResult Result { get; private set; }
|
||||
|
||||
|
@ -41,14 +40,13 @@ namespace SafeExamBrowser.Browser.Filters.Rules
|
|||
var url = new Uri(request.Url, UriKind.Absolute);
|
||||
var isMatch = true;
|
||||
|
||||
//isMatch &= scheme == default(Regex) || ...;
|
||||
//isMatch &= user == default(Regex) || ...;
|
||||
//isMatch &= password == default(Regex) || ...;
|
||||
isMatch &= scheme == default(Regex) || scheme.IsMatch(url.Scheme);
|
||||
isMatch &= userInfo == default(Regex) || userInfo.IsMatch(url.UserInfo);
|
||||
isMatch &= host.IsMatch(url.Host);
|
||||
isMatch &= !port.HasValue || port == url.Port;
|
||||
//isMatch &= path == default(Regex) || ...;
|
||||
//isMatch &= query == default(Regex) || ...;
|
||||
//isMatch &= fragment == default(Regex) || ...;
|
||||
isMatch &= path == default(Regex) || path.IsMatch(url.AbsolutePath);
|
||||
isMatch &= query == default(Regex) || query.IsMatch(url.Query);
|
||||
isMatch &= fragment == default(Regex) || fragment.IsMatch(url.Fragment);
|
||||
|
||||
return isMatch;
|
||||
}
|
||||
|
@ -57,36 +55,58 @@ namespace SafeExamBrowser.Browser.Filters.Rules
|
|||
{
|
||||
var match = Regex.Match(expression, URL_DELIMITER_PATTERN);
|
||||
|
||||
//ParseScheme(match.Groups[1].Value);
|
||||
//ParseUser(match.Groups[2].Value);
|
||||
//ParsePassword(match.Groups[3].Value);
|
||||
ParseScheme(match.Groups[1].Value);
|
||||
ParseUserInfo(match.Groups[2].Value, match.Groups[3].Value);
|
||||
ParseHost(match.Groups[4].Value);
|
||||
ParsePort(match.Groups[5].Value);
|
||||
//ParsePath(match.Groups[6].Value);
|
||||
//ParseQuery(match.Groups[7].Value);
|
||||
//ParseFragment(match.Groups[8].Value);
|
||||
ParsePath(match.Groups[6].Value);
|
||||
ParseQuery(match.Groups[7].Value);
|
||||
ParseFragment(match.Groups[8].Value);
|
||||
}
|
||||
|
||||
private void ParseScheme(string expression)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(expression))
|
||||
{
|
||||
expression = Regex.Escape(expression);
|
||||
expression = ReplaceWildcard(expression);
|
||||
|
||||
scheme = Build(expression);
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseUserInfo(string username, string password)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(username))
|
||||
{
|
||||
var expression = default(string);
|
||||
|
||||
username = Regex.Escape(username);
|
||||
password = Regex.Escape(password);
|
||||
|
||||
expression = string.IsNullOrEmpty(password) ? $@"{username}(:.*)?" : $@"{username}:{password}";
|
||||
expression = ReplaceWildcard(expression);
|
||||
|
||||
userInfo = Build(expression);
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseHost(string expression)
|
||||
{
|
||||
var hasToplevelDomain = Regex.IsMatch(expression, @"\.+");
|
||||
var hasSubdomain = Regex.IsMatch(expression, @"\.{2,}");
|
||||
var allowOnlyExactSubdomain = expression.StartsWith(".");
|
||||
|
||||
if (allowOnlyExactSubdomain)
|
||||
{
|
||||
expression = expression.Substring(1);
|
||||
}
|
||||
var matchExactSubdomain = expression.StartsWith(".");
|
||||
|
||||
expression = matchExactSubdomain ? expression.Substring(1) : expression;
|
||||
expression = Regex.Escape(expression);
|
||||
expression = ReplaceWildcard(expression);
|
||||
|
||||
if (!hasToplevelDomain)
|
||||
{
|
||||
expression = $@"{expression}(\.[a-z]+)";
|
||||
expression = $@"{expression}(\.[a-z]+)?";
|
||||
}
|
||||
|
||||
if (!hasSubdomain && !allowOnlyExactSubdomain)
|
||||
if (!hasSubdomain && !matchExactSubdomain)
|
||||
{
|
||||
expression = $@"(.+?\.)*{expression}";
|
||||
}
|
||||
|
@ -102,6 +122,51 @@ namespace SafeExamBrowser.Browser.Filters.Rules
|
|||
}
|
||||
}
|
||||
|
||||
private void ParsePath(string expression)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(expression))
|
||||
{
|
||||
expression = Regex.Escape(expression);
|
||||
expression = ReplaceWildcard(expression);
|
||||
expression = expression.EndsWith("/") ? $@"{expression}?" : $@"{expression}/?";
|
||||
|
||||
path = Build(expression);
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseQuery(string expression)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(expression))
|
||||
{
|
||||
var noQueryAllowed = expression == ".";
|
||||
|
||||
if (noQueryAllowed)
|
||||
{
|
||||
expression = @"\??";
|
||||
}
|
||||
else
|
||||
{
|
||||
expression = Regex.Escape(expression);
|
||||
expression = ReplaceWildcard(expression);
|
||||
expression = $@"\??{expression}";
|
||||
}
|
||||
|
||||
query = Build(expression);
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseFragment(string expression)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(expression))
|
||||
{
|
||||
expression = Regex.Escape(expression);
|
||||
expression = ReplaceWildcard(expression);
|
||||
expression = $"#?{expression}";
|
||||
|
||||
fragment = Build(expression);
|
||||
}
|
||||
}
|
||||
|
||||
private Regex Build(string expression)
|
||||
{
|
||||
return new Regex($"^{expression}$", RegexOptions.IgnoreCase);
|
||||
|
@ -109,7 +174,7 @@ namespace SafeExamBrowser.Browser.Filters.Rules
|
|||
|
||||
private string ReplaceWildcard(string expression)
|
||||
{
|
||||
return expression.Replace(@"\*", ".*?");
|
||||
return expression.Replace(@"\*", ".*");
|
||||
}
|
||||
|
||||
private void ValidateExpression(string expression)
|
||||
|
|
Loading…
Reference in a new issue