Skip to content

Commit d77b370

Browse files
authored
Add Endpoint extension methods to HttpContext (#1060)
1 parent 187e89f commit d77b370

File tree

2 files changed

+225
-0
lines changed

2 files changed

+225
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using Microsoft.AspNetCore.Http.Features;
6+
7+
namespace Microsoft.AspNetCore.Http
8+
{
9+
/// <summary>
10+
/// Extension methods to expose Endpoint on HttpContext.
11+
/// </summary>
12+
public static class EndpointHttpContextExtensions
13+
{
14+
/// <summary>
15+
/// Extension method for getting the <see cref="Endpoint"/> for the current request.
16+
/// </summary>
17+
/// <param name="context">The <see cref="HttpContext"/> context.</param>
18+
/// <returns>The <see cref="Endpoint"/>.</returns>
19+
public static Endpoint GetEndpoint(this HttpContext context)
20+
{
21+
if (context == null)
22+
{
23+
throw new ArgumentNullException(nameof(context));
24+
}
25+
26+
return context.Features.Get<IEndpointFeature>()?.Endpoint;
27+
}
28+
29+
/// <summary>
30+
/// Extension method for setting the <see cref="Endpoint"/> for the current request.
31+
/// </summary>
32+
/// <param name="context">The <see cref="HttpContext"/> context.</param>
33+
/// <param name="endpoint">The <see cref="Endpoint"/>.</param>
34+
public static void SetEndpoint(this HttpContext context, Endpoint endpoint)
35+
{
36+
if (context == null)
37+
{
38+
throw new ArgumentNullException(nameof(context));
39+
}
40+
41+
var feature = context.Features.Get<IEndpointFeature>();
42+
43+
if (endpoint != null)
44+
{
45+
if (feature == null)
46+
{
47+
feature = new EndpointFeature();
48+
context.Features.Set(feature);
49+
}
50+
51+
feature.Endpoint = endpoint;
52+
}
53+
else
54+
{
55+
if (feature == null)
56+
{
57+
// No endpoint to set and no feature on context. Do nothing
58+
return;
59+
}
60+
61+
feature.Endpoint = null;
62+
}
63+
}
64+
65+
private class EndpointFeature : IEndpointFeature
66+
{
67+
public Endpoint Endpoint { get; set; }
68+
}
69+
}
70+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
using Microsoft.AspNetCore.Http.Features;
9+
using Xunit;
10+
11+
namespace Microsoft.AspNetCore.Http.Abstractions.Tests
12+
{
13+
public class EndpointHttpContextExtensionsTests
14+
{
15+
[Fact]
16+
public void GetEndpoint_ContextWithoutFeature_ReturnsNull()
17+
{
18+
// Arrange
19+
var context = new DefaultHttpContext();
20+
21+
// Act
22+
var endpoint = context.GetEndpoint();
23+
24+
// Assert
25+
Assert.Null(endpoint);
26+
}
27+
28+
[Fact]
29+
public void GetEndpoint_ContextWithFeatureAndNullEndpoint_ReturnsNull()
30+
{
31+
// Arrange
32+
var context = new DefaultHttpContext();
33+
context.Features.Set<IEndpointFeature>(new EndpointFeature
34+
{
35+
Endpoint = null
36+
});
37+
38+
// Act
39+
var endpoint = context.GetEndpoint();
40+
41+
// Assert
42+
Assert.Null(endpoint);
43+
}
44+
45+
[Fact]
46+
public void GetEndpoint_ContextWithFeatureAndEndpoint_ReturnsNull()
47+
{
48+
// Arrange
49+
var context = new DefaultHttpContext();
50+
var initial = new Endpoint(c => Task.CompletedTask, EndpointMetadataCollection.Empty, "Test endpoint");
51+
context.Features.Set<IEndpointFeature>(new EndpointFeature
52+
{
53+
Endpoint = initial
54+
});
55+
56+
// Act
57+
var endpoint = context.GetEndpoint();
58+
59+
// Assert
60+
Assert.Equal(initial, endpoint);
61+
}
62+
63+
[Fact]
64+
public void SetEndpoint_NullOnContextWithoutFeature_NoFeatureSet()
65+
{
66+
// Arrange
67+
var context = new DefaultHttpContext();
68+
69+
// Act
70+
context.SetEndpoint(null);
71+
72+
// Assert
73+
Assert.Null(context.Features.Get<IEndpointFeature>());
74+
}
75+
76+
[Fact]
77+
public void SetEndpoint_EndpointOnContextWithoutFeature_FeatureWithEndpointSet()
78+
{
79+
// Arrange
80+
var context = new DefaultHttpContext();
81+
82+
// Act
83+
var endpoint = new Endpoint(c => Task.CompletedTask, EndpointMetadataCollection.Empty, "Test endpoint");
84+
context.SetEndpoint(endpoint);
85+
86+
// Assert
87+
var feature = context.Features.Get<IEndpointFeature>();
88+
Assert.NotNull(feature);
89+
Assert.Equal(endpoint, feature.Endpoint);
90+
}
91+
92+
[Fact]
93+
public void SetEndpoint_EndpointOnContextWithFeature_EndpointSetOnExistingFeature()
94+
{
95+
// Arrange
96+
var context = new DefaultHttpContext();
97+
var initialEndpoint = new Endpoint(c => Task.CompletedTask, EndpointMetadataCollection.Empty, "Test endpoint");
98+
var initialFeature = new EndpointFeature
99+
{
100+
Endpoint = initialEndpoint
101+
};
102+
context.Features.Set<IEndpointFeature>(initialFeature);
103+
104+
// Act
105+
var endpoint = new Endpoint(c => Task.CompletedTask, EndpointMetadataCollection.Empty, "Test endpoint");
106+
context.SetEndpoint(endpoint);
107+
108+
// Assert
109+
var feature = context.Features.Get<IEndpointFeature>();
110+
Assert.Equal(initialFeature, feature);
111+
Assert.Equal(endpoint, feature.Endpoint);
112+
}
113+
114+
[Fact]
115+
public void SetEndpoint_NullOnContextWithFeature_NullSetOnExistingFeature()
116+
{
117+
// Arrange
118+
var context = new DefaultHttpContext();
119+
var initialEndpoint = new Endpoint(c => Task.CompletedTask, EndpointMetadataCollection.Empty, "Test endpoint");
120+
var initialFeature = new EndpointFeature
121+
{
122+
Endpoint = initialEndpoint
123+
};
124+
context.Features.Set<IEndpointFeature>(initialFeature);
125+
126+
// Act
127+
context.SetEndpoint(null);
128+
129+
// Assert
130+
var feature = context.Features.Get<IEndpointFeature>();
131+
Assert.Equal(initialFeature, feature);
132+
Assert.Null(feature.Endpoint);
133+
}
134+
135+
[Fact]
136+
public void SetAndGetEndpoint_Roundtrip_EndpointIsRoundtrip()
137+
{
138+
// Arrange
139+
var context = new DefaultHttpContext();
140+
var initialEndpoint = new Endpoint(c => Task.CompletedTask, EndpointMetadataCollection.Empty, "Test endpoint");
141+
142+
// Act
143+
context.SetEndpoint(initialEndpoint);
144+
var endpoint = context.GetEndpoint();
145+
146+
// Assert
147+
Assert.Equal(initialEndpoint, endpoint);
148+
}
149+
150+
private class EndpointFeature : IEndpointFeature
151+
{
152+
public Endpoint Endpoint { get; set; }
153+
}
154+
}
155+
}

0 commit comments

Comments
 (0)