Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Instrumentation.AspNet] Fix multiple routes of same template in attribute-based routing #2250

Merged
merged 8 commits into from
Nov 18, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ internal sealed class HttpRequestRouteHelper
{
// WebAPI attribute routing flows here. Use reflection to not take a dependency on microsoft.aspnet.webapi.core\[version]\lib\[framework]\System.Web.Http.

if (msSubRoutes is Array attributeRouting && attributeRouting.Length == 1)
if (msSubRoutes is Array attributeRouting && attributeRouting.Length >= 1)
{
// There could be more than one subroute, each with a different method.
// But the template is the same across them, so we simply take the template
// from the first route.
var subRouteData = attributeRouting.GetValue(0);

_ = this.routeFetcher.TryFetch(subRouteData, out var route);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public enum QueryRedactionDisableBehavior
[InlineData("https://localhost:443/about_attr_route/10", "https", "/about_attr_route/10", null, null, "localhost", 443, "HEAD", "HEAD", null, 2, "about_attr_route/{customerId}", "HEAD about_attr_route/{customerId}")]
[InlineData("http://localhost:1880/api/weatherforecast", "http", "/api/weatherforecast", null, null, "localhost", 1880, "GET", "GET", null, 3, "api/{controller}/{id}", "GET api/{controller}/{id}")]
[InlineData("https://localhost:1843/subroute/10", "https", "/subroute/10", null, null, "localhost", 1843, "GET", "GET", null, 4, "subroute/{customerId}", "GET subroute/{customerId}")]
[InlineData("https://localhost:1843/subroute/10", "https", "/subroute/10", null, null, "localhost", 1843, "GET", "GET", null, 5, "subroute/{customerId}", "GET subroute/{customerId}")]
[InlineData("http://localhost/api/value", "http", "/api/value", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "/api/value")] // Request will be filtered
[InlineData("http://localhost/api/value", "http", "/api/value", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "{ThrowException}")] // Filter user code will throw an exception
[InlineData("http://localhost/", "http", "/", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, null, true, "System.InvalidOperationException")] // Test RecordException option
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using System.Net.Http;
using System.Web;
using System.Web.Routing;

Expand Down Expand Up @@ -40,6 +41,75 @@ public static HttpContext BuildHttpContext(string url, int routeType, string? ro
"MS_SubRoutes",
value);
break;
case 5: // Multi-method attribute routing WebAPI.
routeData = new RouteData();
var multiMethodSubroutes = new[]
{
new
{
Route = new
{
RouteTemplate = routeTemplate,
DataTokens = new Dictionary<string, object>
{
["actions"] = new[]
{
new
{
SupportedHttpMethods = new[]
{
HttpMethod.Get,
},
},
},
},
},
},
new
{
Route = new
{
RouteTemplate = routeTemplate,
DataTokens = new Dictionary<string, object>
{
["actions"] = new[]
{
new
{
SupportedHttpMethods = new[]
{
HttpMethod.Put,
},
},
},
},
},
},
new
{
Route = new
{
RouteTemplate = routeTemplate,
DataTokens = new Dictionary<string, object>
{
["actions"] = new[]
{
new
{
SupportedHttpMethods = new[]
{
HttpMethod.Delete,
},
},
},
},
},
},
};
routeData.Values.Add(
"MS_SubRoutes",
multiMethodSubroutes);
Kielek marked this conversation as resolved.
Show resolved Hide resolved
break;
default:
throw new NotSupportedException();
}
Expand Down