@@ -104,7 +104,7 @@ public async Task XForwardedForFirstValueIsInvalid(int limit, string header, str
104104 [ InlineData ( 2 , "13.113.113.13:34567, 12.112.112.12:23456, 11.111.111.11:12345" , "12.112.112.12" , 23456 , "13.113.113.13:34567" , true ) ]
105105 [ InlineData ( 3 , "13.113.113.13:34567, 12.112.112.12:23456, 11.111.111.11:12345" , "13.113.113.13" , 34567 , "" , false ) ]
106106 [ InlineData ( 3 , "13.113.113.13:34567, 12.112.112.12:23456, 11.111.111.11:12345" , "13.113.113.13" , 34567 , "" , true ) ]
107- public async Task XForwardedForForwardLimit ( int limit , string header , string expectedIp , int expectedPort , string remainingHeader , bool requireSymmetry )
107+ public async Task XForwardedForForwardLimit_Obsolete ( int limit , string header , string expectedIp , int expectedPort , string remainingHeader , bool requireSymmetry )
108108 {
109109 using var host = new HostBuilder ( )
110110 . ConfigureWebHost ( webHostBuilder =>
@@ -123,6 +123,61 @@ public async Task XForwardedForForwardLimit(int limit, string header, string exp
123123#pragma warning disable ASPDEPR005 // KnownNetworks is obsolete
124124 options . KnownNetworks . Clear ( ) ;
125125#pragma warning restore ASPDEPR005 // KnownNetworks is obsolete
126+ app . UseForwardedHeaders ( options ) ;
127+ } ) ;
128+ } ) . Build ( ) ;
129+
130+ await host . StartAsync ( ) ;
131+
132+ var server = host . GetTestServer ( ) ;
133+
134+ var context = await server . SendAsync ( c =>
135+ {
136+ c . Request . Headers [ "X-Forwarded-For" ] = header ;
137+ c . Connection . RemoteIpAddress = IPAddress . Parse ( "10.0.0.1" ) ;
138+ c . Connection . RemotePort = 99 ;
139+ } ) ;
140+
141+ Assert . Equal ( expectedIp , context . Connection . RemoteIpAddress . ToString ( ) ) ;
142+ Assert . Equal ( expectedPort , context . Connection . RemotePort ) ;
143+ Assert . Equal ( remainingHeader , context . Request . Headers [ "X-Forwarded-For" ] . ToString ( ) ) ;
144+ }
145+
146+ [ Theory ]
147+ [ InlineData ( 1 , "11.111.111.11:12345" , "11.111.111.11" , 12345 , "" , false ) ]
148+ [ InlineData ( 1 , "11.111.111.11:12345" , "11.111.111.11" , 12345 , "" , true ) ]
149+ [ InlineData ( 10 , "11.111.111.11:12345" , "11.111.111.11" , 12345 , "" , false ) ]
150+ [ InlineData ( 10 , "11.111.111.11:12345" , "11.111.111.11" , 12345 , "" , true ) ]
151+ [ InlineData ( 1 , "12.112.112.12:23456, 11.111.111.11:12345" , "11.111.111.11" , 12345 , "12.112.112.12:23456" , false ) ]
152+ [ InlineData ( 1 , "12.112.112.12:23456, 11.111.111.11:12345" , "11.111.111.11" , 12345 , "12.112.112.12:23456" , true ) ]
153+ [ InlineData ( 2 , "12.112.112.12:23456, 11.111.111.11:12345" , "12.112.112.12" , 23456 , "" , false ) ]
154+ [ InlineData ( 2 , "12.112.112.12:23456, 11.111.111.11:12345" , "12.112.112.12" , 23456 , "" , true ) ]
155+ [ InlineData ( 10 , "12.112.112.12:23456, 11.111.111.11:12345" , "12.112.112.12" , 23456 , "" , false ) ]
156+ [ InlineData ( 10 , "12.112.112.12:23456, 11.111.111.11:12345" , "12.112.112.12" , 23456 , "" , true ) ]
157+ [ InlineData ( 10 , "12.112.112.12.23456, 11.111.111.11:12345" , "11.111.111.11" , 12345 , "12.112.112.12.23456" , false ) ] // Invalid 2nd value
158+ [ InlineData ( 10 , "12.112.112.12.23456, 11.111.111.11:12345" , "11.111.111.11" , 12345 , "12.112.112.12.23456" , true ) ] // Invalid 2nd value
159+ [ InlineData ( 10 , "13.113.113.13:34567, 12.112.112.12.23456, 11.111.111.11:12345" , "11.111.111.11" , 12345 , "13.113.113.13:34567,12.112.112.12.23456" , false ) ] // Invalid 2nd value
160+ [ InlineData ( 10 , "13.113.113.13:34567, 12.112.112.12.23456, 11.111.111.11:12345" , "11.111.111.11" , 12345 , "13.113.113.13:34567,12.112.112.12.23456" , true ) ] // Invalid 2nd value
161+ [ InlineData ( 2 , "13.113.113.13:34567, 12.112.112.12:23456, 11.111.111.11:12345" , "12.112.112.12" , 23456 , "13.113.113.13:34567" , false ) ]
162+ [ InlineData ( 2 , "13.113.113.13:34567, 12.112.112.12:23456, 11.111.111.11:12345" , "12.112.112.12" , 23456 , "13.113.113.13:34567" , true ) ]
163+ [ InlineData ( 3 , "13.113.113.13:34567, 12.112.112.12:23456, 11.111.111.11:12345" , "13.113.113.13" , 34567 , "" , false ) ]
164+ [ InlineData ( 3 , "13.113.113.13:34567, 12.112.112.12:23456, 11.111.111.11:12345" , "13.113.113.13" , 34567 , "" , true ) ]
165+ public async Task XForwardedForForwardLimit ( int limit , string header , string expectedIp , int expectedPort , string remainingHeader , bool requireSymmetry )
166+ {
167+ using var host = new HostBuilder ( )
168+ . ConfigureWebHost ( webHostBuilder =>
169+ {
170+ webHostBuilder
171+ . UseTestServer ( )
172+ . Configure ( app =>
173+ {
174+ var options = new ForwardedHeadersOptions
175+ {
176+ ForwardedHeaders = ForwardedHeaders . XForwardedFor ,
177+ RequireHeaderSymmetry = requireSymmetry ,
178+ ForwardLimit = limit ,
179+ } ;
180+ options . KnownProxies . Clear ( ) ;
126181 options . KnownIPNetworks . Clear ( ) ;
127182 app . UseForwardedHeaders ( options ) ;
128183 } ) ;
@@ -847,7 +902,7 @@ public async Task XForwardedProtoOverrideCanBeIndependentOfXForwardedForCount(in
847902 [ InlineData ( "h2, h1" , "" , "::1" , true , "http" ) ]
848903 [ InlineData ( "h2, h1" , "F::, D::" , "::1" , true , "h1" ) ]
849904 [ InlineData ( "h2, h1" , "E::, D::" , "F::" , true , "http" ) ]
850- public async Task XForwardedProtoOverrideLimitedByLoopback ( string protoHeader , string forHeader , string remoteIp , bool loopback , string expected )
905+ public async Task XForwardedProtoOverrideLimitedByLoopback_Obsolete ( string protoHeader , string forHeader , string remoteIp , bool loopback , string expected )
851906 {
852907 using var host = new HostBuilder ( )
853908 . ConfigureWebHost ( webHostBuilder =>
@@ -867,6 +922,56 @@ public async Task XForwardedProtoOverrideLimitedByLoopback(string protoHeader, s
867922#pragma warning disable ASPDEPR005 // KnownNetworks is obsolete
868923 options . KnownNetworks . Clear ( ) ;
869924#pragma warning restore ASPDEPR005 // KnownNetworks is obsolete
925+ options . KnownProxies . Clear ( ) ;
926+ }
927+ app . UseForwardedHeaders ( options ) ;
928+ } ) ;
929+ } ) . Build ( ) ;
930+
931+ await host . StartAsync ( ) ;
932+
933+ var server = host . GetTestServer ( ) ;
934+
935+ var context = await server . SendAsync ( c =>
936+ {
937+ c . Request . Headers [ "X-Forwarded-Proto" ] = protoHeader ;
938+ c . Request . Headers [ "X-Forwarded-For" ] = forHeader ;
939+ c . Connection . RemoteIpAddress = IPAddress . Parse ( remoteIp ) ;
940+ } ) ;
941+
942+ Assert . Equal ( expected , context . Request . Scheme ) ;
943+ }
944+
945+ [ Theory ]
946+ [ InlineData ( "" , "" , "::1" , false , "http" ) ]
947+ [ InlineData ( "h1" , "" , "::1" , false , "http" ) ]
948+ [ InlineData ( "h1" , "F::" , "::1" , false , "h1" ) ]
949+ [ InlineData ( "h1" , "F::" , "E::" , false , "h1" ) ]
950+ [ InlineData ( "" , "" , "::1" , true , "http" ) ]
951+ [ InlineData ( "h1" , "" , "::1" , true , "http" ) ]
952+ [ InlineData ( "h1" , "F::" , "::1" , true , "h1" ) ]
953+ [ InlineData ( "h1" , "" , "F::" , true , "http" ) ]
954+ [ InlineData ( "h1" , "E::" , "F::" , true , "http" ) ]
955+ [ InlineData ( "h2, h1" , "" , "::1" , true , "http" ) ]
956+ [ InlineData ( "h2, h1" , "F::, D::" , "::1" , true , "h1" ) ]
957+ [ InlineData ( "h2, h1" , "E::, D::" , "F::" , true , "http" ) ]
958+ public async Task XForwardedProtoOverrideLimitedByLoopback ( string protoHeader , string forHeader , string remoteIp , bool loopback , string expected )
959+ {
960+ using var host = new HostBuilder ( )
961+ . ConfigureWebHost ( webHostBuilder =>
962+ {
963+ webHostBuilder
964+ . UseTestServer ( )
965+ . Configure ( app =>
966+ {
967+ var options = new ForwardedHeadersOptions
968+ {
969+ ForwardedHeaders = ForwardedHeaders . XForwardedProto | ForwardedHeaders . XForwardedFor ,
970+ RequireHeaderSymmetry = true ,
971+ ForwardLimit = 5 ,
972+ } ;
973+ if ( ! loopback )
974+ {
870975 options . KnownIPNetworks . Clear ( ) ;
871976 options . KnownProxies . Clear ( ) ;
872977 }
@@ -1127,7 +1232,7 @@ public async Task XForwardForIPv4ToIPv6Mapping(string forHeader, string knownPro
11271232 [ Theory ]
11281233 [ InlineData ( 1 , "httpa, httpb, httpc" , "httpc" , "httpa,httpb" ) ]
11291234 [ InlineData ( 2 , "httpa, httpb, httpc" , "httpb" , "httpa" ) ]
1130- public async Task ForwardersWithDIOptionsRunsOnce ( int limit , string header , string expectedScheme , string remainingHeader )
1235+ public async Task ForwardersWithDIOptionsRunsOnce_Obsolete ( int limit , string header , string expectedScheme , string remainingHeader )
11311236 {
11321237 using var host = new HostBuilder ( )
11331238 . ConfigureWebHost ( webHostBuilder =>
@@ -1143,6 +1248,45 @@ public async Task ForwardersWithDIOptionsRunsOnce(int limit, string header, stri
11431248#pragma warning disable ASPDEPR005 // KnownNetworks is obsolete
11441249 options . KnownNetworks . Clear ( ) ;
11451250#pragma warning restore ASPDEPR005 // KnownNetworks is obsolete
1251+ options . ForwardLimit = limit ;
1252+ } ) ;
1253+ } )
1254+ . Configure ( app =>
1255+ {
1256+ app . UseForwardedHeaders ( ) ;
1257+ app . UseForwardedHeaders ( ) ;
1258+ } ) ;
1259+ } ) . Build ( ) ;
1260+
1261+ await host . StartAsync ( ) ;
1262+
1263+ var server = host . GetTestServer ( ) ;
1264+
1265+ var context = await server . SendAsync ( c =>
1266+ {
1267+ c . Request . Headers [ "X-Forwarded-Proto" ] = header ;
1268+ } ) ;
1269+
1270+ Assert . Equal ( expectedScheme , context . Request . Scheme ) ;
1271+ Assert . Equal ( remainingHeader , context . Request . Headers [ "X-Forwarded-Proto" ] . ToString ( ) ) ;
1272+ }
1273+
1274+ [ Theory ]
1275+ [ InlineData ( 1 , "httpa, httpb, httpc" , "httpc" , "httpa,httpb" ) ]
1276+ [ InlineData ( 2 , "httpa, httpb, httpc" , "httpb" , "httpa" ) ]
1277+ public async Task ForwardersWithDIOptionsRunsOnce ( int limit , string header , string expectedScheme , string remainingHeader )
1278+ {
1279+ using var host = new HostBuilder ( )
1280+ . ConfigureWebHost ( webHostBuilder =>
1281+ {
1282+ webHostBuilder
1283+ . UseTestServer ( )
1284+ . ConfigureServices ( services =>
1285+ {
1286+ services . Configure < ForwardedHeadersOptions > ( options =>
1287+ {
1288+ options . ForwardedHeaders = ForwardedHeaders . XForwardedProto ;
1289+ options . KnownProxies . Clear ( ) ;
11461290 options . KnownIPNetworks . Clear ( ) ;
11471291 options . ForwardLimit = limit ;
11481292 } ) ;
@@ -1170,7 +1314,7 @@ public async Task ForwardersWithDIOptionsRunsOnce(int limit, string header, stri
11701314 [ Theory ]
11711315 [ InlineData ( 1 , "httpa, httpb, httpc" , "httpb" , "httpa" ) ]
11721316 [ InlineData ( 2 , "httpa, httpb, httpc" , "httpa" , "" ) ]
1173- public async Task ForwardersWithDirectOptionsRunsTwice ( int limit , string header , string expectedScheme , string remainingHeader )
1317+ public async Task ForwardersWithDirectOptionsRunsTwice_Obsolete ( int limit , string header , string expectedScheme , string remainingHeader )
11741318 {
11751319 using var host = new HostBuilder ( )
11761320 . ConfigureWebHost ( webHostBuilder =>
@@ -1188,6 +1332,42 @@ public async Task ForwardersWithDirectOptionsRunsTwice(int limit, string header,
11881332#pragma warning disable ASPDEPR005 // KnownNetworks is obsolete
11891333 options . KnownNetworks . Clear ( ) ;
11901334#pragma warning restore ASPDEPR005 // KnownNetworks is obsolete
1335+ app . UseForwardedHeaders ( options ) ;
1336+ app . UseForwardedHeaders ( options ) ;
1337+ } ) ;
1338+ } ) . Build ( ) ;
1339+
1340+ await host . StartAsync ( ) ;
1341+
1342+ var server = host . GetTestServer ( ) ;
1343+
1344+ var context = await server . SendAsync ( c =>
1345+ {
1346+ c . Request . Headers [ "X-Forwarded-Proto" ] = header ;
1347+ } ) ;
1348+
1349+ Assert . Equal ( expectedScheme , context . Request . Scheme ) ;
1350+ Assert . Equal ( remainingHeader , context . Request . Headers [ "X-Forwarded-Proto" ] . ToString ( ) ) ;
1351+ }
1352+
1353+ [ Theory ]
1354+ [ InlineData ( 1 , "httpa, httpb, httpc" , "httpb" , "httpa" ) ]
1355+ [ InlineData ( 2 , "httpa, httpb, httpc" , "httpa" , "" ) ]
1356+ public async Task ForwardersWithDirectOptionsRunsTwice ( int limit , string header , string expectedScheme , string remainingHeader )
1357+ {
1358+ using var host = new HostBuilder ( )
1359+ . ConfigureWebHost ( webHostBuilder =>
1360+ {
1361+ webHostBuilder
1362+ . UseTestServer ( )
1363+ . Configure ( app =>
1364+ {
1365+ var options = new ForwardedHeadersOptions
1366+ {
1367+ ForwardedHeaders = ForwardedHeaders . XForwardedProto ,
1368+ ForwardLimit = limit ,
1369+ } ;
1370+ options . KnownProxies . Clear ( ) ;
11911371 options . KnownIPNetworks . Clear ( ) ;
11921372 app . UseForwardedHeaders ( options ) ;
11931373 app . UseForwardedHeaders ( options ) ;
0 commit comments