@@ -21,8 +21,10 @@ public static class HealthCheckApplicationBuilderExtensions
21
21
/// <returns>A reference to the <paramref name="app"/> after the operation has completed.</returns>
22
22
/// <remarks>
23
23
/// <para>
24
- /// This method will use <see cref="MapExtensions.Map(IApplicationBuilder, PathString, Action{IApplicationBuilder})"/> to
25
- /// listen to health checks requests on the specified URL path.
24
+ /// If <paramref name="path"/> is set to <c>null</c> or the empty string then the health check middleware
25
+ /// will ignore the URL path and process all requests. If <paramref name="path"/> is set to a non-empty
26
+ /// value, the health check middleware will process requests with a URL that matches the provided value
27
+ /// of <paramref name="path"/> case-insensitively, allowing for an extra trailing slash ('/') character.
26
28
/// </para>
27
29
/// <para>
28
30
/// The health check middleware will use default settings from <see cref="IOptions{HealthCheckOptions}"/>.
@@ -48,8 +50,10 @@ public static IApplicationBuilder UseHealthChecks(this IApplicationBuilder app,
48
50
/// <returns>A reference to the <paramref name="app"/> after the operation has completed.</returns>
49
51
/// <remarks>
50
52
/// <para>
51
- /// This method will use <see cref="MapExtensions.Map(IApplicationBuilder, PathString, Action{IApplicationBuilder})"/> to
52
- /// listen to health checks requests on the specified URL path.
53
+ /// If <paramref name="path"/> is set to <c>null</c> or the empty string then the health check middleware
54
+ /// will ignore the URL path and process all requests. If <paramref name="path"/> is set to a non-empty
55
+ /// value, the health check middleware will process requests with a URL that matches the provided value
56
+ /// of <paramref name="path"/> case-insensitively, allowing for an extra trailing slash ('/') character.
53
57
/// </para>
54
58
/// </remarks>
55
59
public static IApplicationBuilder UseHealthChecks ( this IApplicationBuilder app , PathString path , HealthCheckOptions options )
@@ -77,8 +81,11 @@ public static IApplicationBuilder UseHealthChecks(this IApplicationBuilder app,
77
81
/// <returns>A reference to the <paramref name="app"/> after the operation has completed.</returns>
78
82
/// <remarks>
79
83
/// <para>
80
- /// This method will use <see cref="MapWhenExtensions.MapWhen(IApplicationBuilder, Func{HttpContext, bool}, Action{IApplicationBuilder})"/> to
81
- /// listen to health checks requests on the specified URL path and port.
84
+ /// If <paramref name="path"/> is set to <c>null</c> or the empty string then the health check middleware
85
+ /// will ignore the URL path and process all requests on the specified port. If <paramref name="path"/> is
86
+ /// set to a non-empty value, the health check middleware will process requests with a URL that matches the
87
+ /// provided value of <paramref name="path"/> case-insensitively, allowing for an extra trailing slash ('/')
88
+ /// character.
82
89
/// </para>
83
90
/// <para>
84
91
/// The health check middleware will use default settings from <see cref="IOptions{HealthCheckOptions}"/>.
@@ -104,8 +111,11 @@ public static IApplicationBuilder UseHealthChecks(this IApplicationBuilder app,
104
111
/// <returns>A reference to the <paramref name="app"/> after the operation has completed.</returns>
105
112
/// <remarks>
106
113
/// <para>
107
- /// This method will use <see cref="MapWhenExtensions.MapWhen(IApplicationBuilder, Func{HttpContext, bool}, Action{IApplicationBuilder})"/> to
108
- /// listen to health checks requests on the specified URL path and port.
114
+ /// If <paramref name="path"/> is set to <c>null</c> or the empty string then the health check middleware
115
+ /// will ignore the URL path and process all requests on the specified port. If <paramref name="path"/> is
116
+ /// set to a non-empty value, the health check middleware will process requests with a URL that matches the
117
+ /// provided value of <paramref name="path"/> case-insensitively, allowing for an extra trailing slash ('/')
118
+ /// character.
109
119
/// </para>
110
120
/// <para>
111
121
/// The health check middleware will use default settings from <see cref="IOptions{HealthCheckOptions}"/>.
@@ -142,8 +152,11 @@ public static IApplicationBuilder UseHealthChecks(this IApplicationBuilder app,
142
152
/// <returns>A reference to the <paramref name="app"/> after the operation has completed.</returns>
143
153
/// <remarks>
144
154
/// <para>
145
- /// This method will use <see cref="MapExtensions.Map(IApplicationBuilder, PathString, Action{IApplicationBuilder})"/> to
146
- /// listen to health checks requests on the specified URL path.
155
+ /// If <paramref name="path"/> is set to <c>null</c> or the empty string then the health check middleware
156
+ /// will ignore the URL path and process all requests on the specified port. If <paramref name="path"/> is
157
+ /// set to a non-empty value, the health check middleware will process requests with a URL that matches the
158
+ /// provided value of <paramref name="path"/> case-insensitively, allowing for an extra trailing slash ('/')
159
+ /// character.
147
160
/// </para>
148
161
/// </remarks>
149
162
public static IApplicationBuilder UseHealthChecks ( this IApplicationBuilder app , PathString path , int port , HealthCheckOptions options )
@@ -172,8 +185,11 @@ public static IApplicationBuilder UseHealthChecks(this IApplicationBuilder app,
172
185
/// <returns>A reference to the <paramref name="app"/> after the operation has completed.</returns>
173
186
/// <remarks>
174
187
/// <para>
175
- /// This method will use <see cref="MapExtensions.Map(IApplicationBuilder, PathString, Action{IApplicationBuilder})"/> to
176
- /// listen to health checks requests on the specified URL path.
188
+ /// If <paramref name="path"/> is set to <c>null</c> or the empty string then the health check middleware
189
+ /// will ignore the URL path and process all requests on the specified port. If <paramref name="path"/> is
190
+ /// set to a non-empty value, the health check middleware will process requests with a URL that matches the
191
+ /// provided value of <paramref name="path"/> case-insensitively, allowing for an extra trailing slash ('/')
192
+ /// character.
177
193
/// </para>
178
194
/// </remarks>
179
195
public static IApplicationBuilder UseHealthChecks ( this IApplicationBuilder app , PathString path , string port , HealthCheckOptions options )
@@ -204,16 +220,35 @@ public static IApplicationBuilder UseHealthChecks(this IApplicationBuilder app,
204
220
205
221
private static void UseHealthChecksCore ( IApplicationBuilder app , PathString path , int ? port , object [ ] args )
206
222
{
207
- if ( port == null )
208
- {
209
- app . Map ( path , b => b . UseMiddleware < HealthCheckMiddleware > ( args ) ) ;
210
- }
211
- else
223
+ // NOTE: we explicitly don't use Map here because it's really common for multiple health
224
+ // check middleware to overlap in paths. Ex: `/health`, `/health/detailed` - this is order
225
+ // sensititive with Map, and it's really surprising to people.
226
+ //
227
+ // See:
228
+ // https://github.com/aspnet/Diagnostics/issues/511
229
+ // https://github.com/aspnet/Diagnostics/issues/512
230
+ // https://github.com/aspnet/Diagnostics/issues/514
231
+
232
+ Func < HttpContext , bool > predicate = c =>
212
233
{
213
- app . MapWhen (
214
- c => c . Connection . LocalPort == port ,
215
- b0 => b0 . Map ( path , b1 => b1 . UseMiddleware < HealthCheckMiddleware > ( args ) ) ) ;
216
- }
234
+ return
235
+
236
+ // Process the port if we have one
237
+ ( port == null || c . Connection . LocalPort == port ) &&
238
+
239
+ // We allow you to listen on all URLs by providing the empty PathString.
240
+ ( ! path . HasValue ||
241
+
242
+ // If you do provide a PathString, want to handle all of the special cases that
243
+ // StartsWithSegments handles, but we also want it to have exact match semantics.
244
+ //
245
+ // Ex: /Foo/ == /Foo (true)
246
+ // Ex: /Foo/Bar == /Foo (false)
247
+ ( c . Request . Path . StartsWithSegments ( path , out var remaining ) &&
248
+ string . IsNullOrEmpty ( remaining ) ) ) ;
249
+ } ;
250
+
251
+ app . MapWhen ( predicate , b => b . UseMiddleware < HealthCheckMiddleware > ( args ) ) ;
217
252
}
218
253
}
219
254
}
0 commit comments