in src/Microsoft.OpenApi/Services/OpenApiFilterService.cs [194:269]
private static IDictionary<OperationType, OpenApiOperation> GetOpenApiOperations(OpenApiUrlTreeNode rootNode, string relativeUrl, string label)
{
if (relativeUrl.Equals("/", StringComparison.Ordinal) && rootNode.HasOperations(label))
{
return rootNode.PathItems[label].Operations;
}
var urlSegments = relativeUrl.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
IDictionary<OperationType, OpenApiOperation> operations = null;
var targetChild = rootNode;
/* This will help keep track of whether we've skipped a segment
* in the target url due to a possible parameter naming mismatch
* with the corresponding OpenApiUrlTreeNode target child segment.
*/
var parameterNameOffset = 0;
for (var i = 0; i < urlSegments?.Length; i++)
{
var tempTargetChild = targetChild?.Children?
.FirstOrDefault(x => x.Key.Equals(urlSegments[i],
StringComparison.OrdinalIgnoreCase)).Value;
// Segment name mismatch
if (tempTargetChild == null)
{
if (i == 0)
{
/* If no match and we are at the 1st segment of the relative url,
* exit; no need to continue matching subsequent segments.
*/
break;
}
/* Attempt to get the parameter segment from the children of the current node:
* We are assuming a failed match because of different parameter namings
* between the relative url segment and the corresponding OpenApiUrlTreeNode segment name
* ex.: matching '/users/12345/messages' with '/users/{user-id}/messages'
*/
tempTargetChild = targetChild?.Children?
.FirstOrDefault(x => x.Value.IsParameter).Value;
/* If no parameter segment exists in the children of the
* current node or we've already skipped a parameter
* segment in the relative url from the last pass,
* then exit; there's no match.
*/
if (tempTargetChild == null || parameterNameOffset > 0)
{
break;
}
/* To help us know we've skipped a
* corresponding segment in the relative url.
*/
parameterNameOffset++;
}
else
{
parameterNameOffset = 0;
}
// Move to the next segment
targetChild = tempTargetChild;
// We want the operations of the last segment of the path.
if (i == urlSegments.Length - 1 && targetChild.HasOperations(label))
{
operations = targetChild.PathItems[label].Operations;
}
}
return operations;
}