Skip to content

Commit 8fdc2e2

Browse files
Avoid LockRecursionException on IIS. Fixes #703
1 parent b27eaae commit 8fdc2e2

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

src/Microsoft.AspNet.WebApi.Versioning/System.Web.Http/HttpRequestMessageExtensions.cs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,30 @@ public static ApiVersionRequestProperties ApiVersionProperties( this HttpRequest
8181
throw new ArgumentNullException( nameof( request ) );
8282
}
8383

84-
if ( !request.Properties.TryGetValue( ApiVersionPropertiesKey, out ApiVersionRequestProperties properties ) )
84+
if ( request.Properties.TryGetValue( ApiVersionPropertiesKey, out ApiVersionRequestProperties properties ) )
8585
{
86-
var forceRouteConstraintEvaluation = !request.Properties.ContainsKey( RoutingContextKey );
86+
return properties;
87+
}
88+
89+
var forceRouteConstraintEvaluation = !request.Properties.ContainsKey( RoutingContextKey );
8790

88-
request.Properties[ApiVersionPropertiesKey] = properties = new ApiVersionRequestProperties( request );
91+
request.Properties[ApiVersionPropertiesKey] = properties = new ApiVersionRequestProperties( request );
8992

90-
if ( forceRouteConstraintEvaluation )
93+
if ( forceRouteConstraintEvaluation && request.GetConfiguration() is HttpConfiguration configuration )
94+
{
95+
// HACK: do NOT use 'HttpRouteCollection.GetRouteData' because it can result in a LockRecursionException when hosted on IIS
96+
// REF: https://github.com/microsoft/referencesource/blob/master/System.Web/Routing/RouteCollection.cs#L159
97+
var routes = configuration.Routes;
98+
var context = request.GetRequestContext();
99+
var virtualPathRoot = context?.VirtualPathRoot ?? routes.VirtualPathRoot ?? string.Empty;
100+
101+
// HACK: do NOT use a normal 'for' loop here because the IIS implementation does not support indexing
102+
foreach ( var route in routes )
91103
{
92-
request.GetConfiguration()?.Routes.GetRouteData( request );
104+
if ( route.GetRouteData( virtualPathRoot, request ) is not null )
105+
{
106+
break;
107+
}
93108
}
94109
}
95110

0 commit comments

Comments
 (0)