11using Microsoft . AspNetCore . Builder ;
2+ using Microsoft . AspNetCore . Diagnostics . HealthChecks ;
3+ using Microsoft . AspNetCore . Http ;
24using Microsoft . AspNetCore . HttpLogging ;
35using Microsoft . AspNetCore . HttpOverrides ;
46using Microsoft . Extensions . Configuration ;
@@ -13,27 +15,53 @@ namespace NetLah.Extensions.HttpOverrides;
1315public static class HttpOverridesExtensions
1416{
1517 private static readonly Lazy < ILogger ? > _loggerLazy = new ( ( ) => AppLogReference . GetAppLogLogger ( typeof ( HttpOverridesExtensions ) . Namespace ) ) ;
18+ private static HealthCheckAppOptions _healthCheckAppOptions = default ! ;
1619 private static bool _isForwardedHeadersEnabled ;
1720 private static bool _isHttpLoggingEnabled ;
1821
19- public static WebApplicationBuilder AddHttpOverrides ( this WebApplicationBuilder webApplicationBuilder , string httpOverridesSectionName = Config . HttpOverridesKey , string httpLoggingSectionName = Config . HttpLoggingKey )
22+ public static WebApplicationBuilder AddHttpOverrides ( this WebApplicationBuilder webApplicationBuilder ,
23+ string httpOverridesSectionName = DefaultConfiguration . HttpOverridesKey ,
24+ string httpLoggingSectionName = DefaultConfiguration . HttpLoggingKey ,
25+ string healthCheckSectionName = DefaultConfiguration . HealthCheckKey )
2026 {
21- webApplicationBuilder . Services . AddHttpOverrides ( webApplicationBuilder . Configuration , httpOverridesSectionName , httpLoggingSectionName ) ;
27+ webApplicationBuilder . Services . AddHttpOverrides ( webApplicationBuilder . Configuration , httpOverridesSectionName , httpLoggingSectionName , healthCheckSectionName ) ;
2228 return webApplicationBuilder ;
2329 }
2430
2531 public static IServiceCollection AddHttpOverrides ( this IServiceCollection services , IConfiguration configuration ,
26- string httpOverridesSectionName = Config . HttpOverridesKey , string httpLoggingSectionName = Config . HttpLoggingKey )
32+ string httpOverridesSectionName = DefaultConfiguration . HttpOverridesKey ,
33+ string httpLoggingSectionName = DefaultConfiguration . HttpLoggingKey ,
34+ string healthCheckSectionName = DefaultConfiguration . HealthCheckKey )
2735 {
28- ILogger ? logger = null ;
36+ ILogger ? logger = null ;
2937
3038 void EnsureLogger ( )
3139 {
3240 logger ??= _loggerLazy . Value ;
3341 logger ??= NullLogger . Instance ;
3442 }
3543
36- _isForwardedHeadersEnabled = configuration [ Config . AspNetCoreForwardedHeadersEnabledKey ] . IsTrue ( ) ;
44+ var healthCheckConfigurationSection = string . IsNullOrEmpty ( healthCheckSectionName ) ? configuration : configuration . GetSection ( healthCheckSectionName ) ;
45+ var healthCheckAppOptions = _healthCheckAppOptions = healthCheckConfigurationSection . Get < HealthCheckAppOptions > ( ) ?? new HealthCheckAppOptions ( ) ;
46+ if ( healthCheckAppOptions . IsEnabled )
47+ {
48+ EnsureLogger ( ) ;
49+ if ( healthCheckConfigurationSection . GetChildren ( ) . Any ( ) )
50+ {
51+ logger ? . LogDebug ( "Attempt to load HealthCheckOptions from configuration" ) ;
52+ services . Configure < HealthCheckOptions > ( healthCheckConfigurationSection ) ;
53+ }
54+ else
55+ {
56+ logger ? . LogDebug ( "Add HealthChecks" ) ;
57+ }
58+
59+ services . Configure < HealthCheckAppOptions > ( healthCheckConfigurationSection ) ;
60+
61+ services . AddHealthChecks ( ) ; // Registers health checks services
62+ }
63+
64+ _isForwardedHeadersEnabled = configuration [ DefaultConfiguration . AspNetCoreForwardedHeadersEnabledKey ] . IsTrue ( ) ;
3765
3866 if ( ! _isForwardedHeadersEnabled )
3967 {
@@ -45,7 +73,7 @@ void EnsureLogger()
4573
4674 services . Configure < ForwardedHeadersOptions > ( options =>
4775 {
48- if ( httpOverridesConfigurationSection [ Config . ClearForwardLimitKey ] . IsTrue ( ) )
76+ if ( httpOverridesConfigurationSection [ DefaultConfiguration . ClearForwardLimitKey ] . IsTrue ( ) )
4977 {
5078 options . ForwardLimit = null ;
5179 }
@@ -56,7 +84,7 @@ void EnsureLogger()
5684 } ) ;
5785 }
5886
59- var httpLoggingEnabledKey = string . IsNullOrEmpty ( httpLoggingSectionName ) ? Config . HttpLoggingEnabledKey : $ "{ httpLoggingSectionName } :Enabled";
87+ var httpLoggingEnabledKey = string . IsNullOrEmpty ( httpLoggingSectionName ) ? DefaultConfiguration . HttpLoggingEnabledKey : $ "{ httpLoggingSectionName } :Enabled";
6088 _isHttpLoggingEnabled = configuration [ httpLoggingEnabledKey ] . IsTrue ( ) ;
6189
6290 if ( _isHttpLoggingEnabled )
@@ -66,8 +94,8 @@ void EnsureLogger()
6694
6795 var httpLoggingConfigurationSection = string . IsNullOrEmpty ( httpLoggingSectionName ) ? configuration : configuration . GetSection ( httpLoggingSectionName ) ;
6896 services . Configure < HttpLoggingOptions > ( httpLoggingConfigurationSection ) ;
69- var isClearRequestHeaders = httpLoggingConfigurationSection [ Config . ClearRequestHeadersKey ] . IsTrue ( ) ;
70- var isClearResponseHeaders = httpLoggingConfigurationSection [ Config . ClearResponseHeadersKey ] . IsTrue ( ) ;
97+ var isClearRequestHeaders = httpLoggingConfigurationSection [ DefaultConfiguration . ClearRequestHeadersKey ] . IsTrue ( ) ;
98+ var isClearResponseHeaders = httpLoggingConfigurationSection [ DefaultConfiguration . ClearResponseHeadersKey ] . IsTrue ( ) ;
7199 var httpLoggingConfig = httpLoggingConfigurationSection . Get < HttpLoggingConfig > ( ) ;
72100 var requestHeaders = httpLoggingConfig ? . RequestHeaders . SplitSet ( ) ?? new HashSet < string > ( ) ;
73101 var responseHeaders = httpLoggingConfig ? . ResponseHeaders . SplitSet ( ) ?? new HashSet < string > ( ) ;
@@ -95,14 +123,62 @@ void EnsureLogger()
95123 return services ;
96124 }
97125
98- public static IApplicationBuilder UseHttpOverrides ( this IApplicationBuilder app , ILogger ? logger = null )
126+ public static WebApplication UseHttpOverrides ( this WebApplication app , ILogger ? logger = null )
99127 {
100128 logger ??= _loggerLazy . Value ;
101129 logger ??= NullLogger . Instance ;
102- var sp = app . ApplicationServices ;
130+ var sp = app . Services ;
103131 var optionsForwardedHeadersOptions = sp . GetRequiredService < IOptions < ForwardedHeadersOptions > > ( ) ;
104132 var fho = optionsForwardedHeadersOptions . Value ;
105133
134+ if ( _healthCheckAppOptions . IsEnabled )
135+ {
136+ if ( _healthCheckAppOptions . IsAzureAppServiceContainer )
137+ {
138+ var mainHealthChecksPath = string . IsNullOrEmpty ( _healthCheckAppOptions . Path ) ? DefaultConfiguration . HealthChecksPath : _healthCheckAppOptions . Path ;
139+ _healthCheckAppOptions . Paths = new [ ] { mainHealthChecksPath , DefaultConfiguration . HealthChecksAzureAppServiceContainer } ;
140+ }
141+
142+ var port = _healthCheckAppOptions . Port ;
143+ if ( _healthCheckAppOptions . Paths is { } pathArrays && pathArrays . Length > 0 )
144+ {
145+ var paths = pathArrays . Select ( p => ( PathString ) p ) . ToArray ( ) ;
146+ logger . LogDebug ( "Use HealthChecks Port:{port} {paths}" , port , paths ) ;
147+
148+ bool predicate ( HttpContext c )
149+ {
150+ if ( port == null || c . Connection . LocalPort == port )
151+ {
152+ foreach ( var path in paths )
153+ {
154+ if ( c . Request . Path . StartsWithSegments ( path , out var remaining ) &&
155+ string . IsNullOrEmpty ( remaining ) )
156+ {
157+ return true ;
158+ }
159+ }
160+ }
161+
162+ return false ;
163+ }
164+
165+ app . MapWhen ( predicate , b => b . UseMiddleware < HealthCheckMiddleware > ( Array . Empty < object > ( ) ) ) ;
166+ }
167+ else
168+ {
169+ var healthChecksPath = StringHelper . NormalizeNull ( _healthCheckAppOptions . Path ) ;
170+ logger . LogDebug ( "Use HealthChecks Port:{port} {path}" , port , healthChecksPath ) ;
171+ if ( port . HasValue )
172+ {
173+ app . UseHealthChecks ( healthChecksPath , port . Value ) ;
174+ }
175+ else
176+ {
177+ app . UseHealthChecks ( healthChecksPath ) ;
178+ }
179+ }
180+ }
181+
106182 var hostFilteringOptions = sp . GetRequiredService < IOptions < Microsoft . AspNetCore . HostFiltering . HostFilteringOptions > > ( ) ;
107183 if ( hostFilteringOptions ? . Value is { } hostFiltering )
108184 {
@@ -111,7 +187,7 @@ public static IApplicationBuilder UseHttpOverrides(this IApplicationBuilder app,
111187
112188 if ( _isForwardedHeadersEnabled )
113189 {
114- var bypassNetLahHttpOverridesMessage = $ "Bypass HttpOverrides configuration settings because { Config . AspNetCoreForwardedHeadersEnabledKey } is True";
190+ var bypassNetLahHttpOverridesMessage = $ "Bypass HttpOverrides configuration settings because { DefaultConfiguration . AspNetCoreForwardedHeadersEnabledKey } is True";
115191#pragma warning disable CA2254 // Template should be a static expression
116192 logger . LogInformation ( bypassNetLahHttpOverridesMessage ) ;
117193#pragma warning restore CA2254 // Template should be a static expression
@@ -167,8 +243,8 @@ public static IApplicationBuilder UseHttpOverrides(this IApplicationBuilder app,
167243
168244 private static void ProcessKnownNetworks ( IConfiguration configuration , ForwardedHeadersOptions options )
169245 {
170- var knownNetworks = configuration [ Config . KnownNetworksKey ] ;
171- if ( knownNetworks != null || configuration [ Config . ClearKnownNetworksKey ] . IsTrue ( ) )
246+ var knownNetworks = configuration [ DefaultConfiguration . KnownNetworksKey ] ;
247+ if ( knownNetworks != null || configuration [ DefaultConfiguration . ClearKnownNetworksKey ] . IsTrue ( ) )
172248 {
173249 options . KnownNetworks . Clear ( ) ;
174250 }
@@ -193,8 +269,8 @@ private static void ProcessKnownNetworks(IConfiguration configuration, Forwarded
193269
194270 private static void ProcessKnownProxies ( IConfiguration configuration , ForwardedHeadersOptions options )
195271 {
196- var knownProxies = configuration [ Config . KnownProxiesKey ] ;
197- if ( knownProxies != null || configuration [ Config . ClearKnownProxiesKey ] . IsTrue ( ) )
272+ var knownProxies = configuration [ DefaultConfiguration . KnownProxiesKey ] ;
273+ if ( knownProxies != null || configuration [ DefaultConfiguration . ClearKnownProxiesKey ] . IsTrue ( ) )
198274 {
199275 options . KnownProxies . Clear ( ) ;
200276 }
0 commit comments