MSDN recommends setting a time-out value in all regular expression pattern-matching operations.
How we can set match timeout in route attribute of asp.net core projects
[Route("[controller]/[action]/{test:regex(^(\\w+$)}")]
public string Get(string test)
{
//...
}
You could refer to the following sample to create a custom route constraint, then, set the Timeout.
Public class MyCustomConstraint : IRouteConstraint
{
private Regex _regex;
public MyCustomConstraint()
{
_regex = new Regex(@"^[1-9]*$",
RegexOptions.CultureInvariant | RegexOptions.IgnoreCase,
TimeSpan.FromMilliseconds(100));
}
public bool Match(HttpContext httpContext, IRouter route, string routeKey,
RouteValueDictionary values, RouteDirection routeDirection)
{
if (values.TryGetValue(routeKey, out object value))
{
var parameterValueString = Convert.ToString(value,
CultureInfo.InvariantCulture);
if (parameterValueString == null)
{
return false;
}
return _regex.IsMatch(parameterValueString);
}
return false;
}
}
Then, register the above constraint in the Startup.ConfigureServices method:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddRouting(options =>
{
options.ConstraintMap.Add("customName", typeof(MyCustomConstraint));
});
}
Then, apply the constrain in the action method, like this:
// GET /api/test/my/3
[HttpGet("my/{id:customName}")]
public IActionResult Get(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
The debug screenshot like this:
Besides, you can also set the timeout value for all Regex matching operations in an application domain by calling the AppDomain.SetData method, code in the Program.cs file:
public static void Main(string[] args)
{
AppDomain domain = AppDomain.CurrentDomain;
// Set a timeout interval of 200 milliseconds.
domain.SetData("REGEX_DEFAULT_MATCH_TIMEOUT", TimeSpan.FromMilliseconds(200));
CreateHostBuilder(args).Build().Run();
}
Then, there is no need to set the timeout in the custom route constraint, check this screenshot: