4949 * @author Rob Winch
5050 * @author Brian Clozel
5151 * @author Sebastien Deleuze
52+ * @author Mengqi Xu
5253 */
5354class ForwardedHeaderFilterTests {
5455
@@ -66,6 +67,8 @@ class ForwardedHeaderFilterTests {
6667
6768private static final String X_FORWARDED_FOR = "x-forwarded-for" ;
6869
70+ private static final String X_FORWARDED_BY = "x-forwarded-by" ;
71+
6972
7073private final ForwardedHeaderFilter filter = new ForwardedHeaderFilter ();
7174
@@ -93,6 +96,7 @@ void shouldFilter() {
9396testShouldFilter (X_FORWARDED_SSL );
9497testShouldFilter (X_FORWARDED_PREFIX );
9598testShouldFilter (X_FORWARDED_FOR );
99+ testShouldFilter (X_FORWARDED_BY );
96100}
97101
98102private void testShouldFilter (String headerName ) {
@@ -115,6 +119,7 @@ void forwardedRequest(String protocol) throws Exception {
115119this .request .addHeader (X_FORWARDED_PORT , "443" );
116120this .request .addHeader ("foo" , "bar" );
117121this .request .addHeader (X_FORWARDED_FOR , "[203.0.113.195]" );
122+ this .request .addHeader (X_FORWARDED_BY , "[203.0.113.196]" );
118123
119124this .filter .doFilter (this .request , new MockHttpServletResponse (), this .filterChain );
120125HttpServletRequest actual = (HttpServletRequest ) this .filterChain .getRequest ();
@@ -126,11 +131,13 @@ void forwardedRequest(String protocol) throws Exception {
126131assertThat (actual .getServerPort ()).isEqualTo (443 );
127132assertThat (actual .isSecure ()).isTrue ();
128133assertThat (actual .getRemoteAddr ()).isEqualTo (actual .getRemoteHost ()).isEqualTo ("[203.0.113.195]" );
134+ assertThat (actual .getLocalAddr ()).isEqualTo (actual .getLocalAddr ()).isEqualTo ("[203.0.113.196]" );
129135
130136assertThat (actual .getHeader (X_FORWARDED_PROTO )).isNull ();
131137assertThat (actual .getHeader (X_FORWARDED_HOST )).isNull ();
132138assertThat (actual .getHeader (X_FORWARDED_PORT )).isNull ();
133139assertThat (actual .getHeader (X_FORWARDED_FOR )).isNull ();
140+ assertThat (actual .getHeader (X_FORWARDED_BY )).isNull ();
134141assertThat (actual .getHeader ("foo" )).isEqualTo ("bar" );
135142}
136143
@@ -143,6 +150,7 @@ void forwardedRequestInRemoveOnlyMode() throws Exception {
143150this .request .addHeader (X_FORWARDED_SSL , "on" );
144151this .request .addHeader ("foo" , "bar" );
145152this .request .addHeader (X_FORWARDED_FOR , "203.0.113.195" );
153+ this .request .addHeader (X_FORWARDED_BY , "203.0.113.196" );
146154
147155this .filter .setRemoveOnly (true );
148156this .filter .doFilter (this .request , new MockHttpServletResponse (), this .filterChain );
@@ -156,12 +164,14 @@ void forwardedRequestInRemoveOnlyMode() throws Exception {
156164assertThat (actual .isSecure ()).isFalse ();
157165assertThat (actual .getRemoteAddr ()).isEqualTo (MockHttpServletRequest .DEFAULT_REMOTE_ADDR );
158166assertThat (actual .getRemoteHost ()).isEqualTo (MockHttpServletRequest .DEFAULT_REMOTE_HOST );
167+ assertThat (actual .getLocalAddr ()).isEqualTo (MockHttpServletRequest .DEFAULT_SERVER_ADDR );
159168
160169assertThat (actual .getHeader (X_FORWARDED_PROTO )).isNull ();
161170assertThat (actual .getHeader (X_FORWARDED_HOST )).isNull ();
162171assertThat (actual .getHeader (X_FORWARDED_PORT )).isNull ();
163172assertThat (actual .getHeader (X_FORWARDED_SSL )).isNull ();
164173assertThat (actual .getHeader (X_FORWARDED_FOR )).isNull ();
174+ assertThat (actual .getHeader (X_FORWARDED_BY )).isNull ();
165175assertThat (actual .getHeader ("foo" )).isEqualTo ("bar" );
166176}
167177
@@ -541,6 +551,83 @@ void forwardedForMultipleIdentifiers() throws Exception {
541551
542552}
543553
554+ @ Nested
555+ class ForwardedBy {
556+
557+ @ Test
558+ void xForwardedForEmpty () throws Exception {
559+ request .addHeader (X_FORWARDED_BY , "" );
560+ HttpServletRequest actual = filterAndGetWrappedRequest ();
561+
562+ assertThat (actual .getLocalAddr ()).isEqualTo (MockHttpServletRequest .DEFAULT_SERVER_ADDR );
563+ assertThat (actual .getLocalPort ()).isEqualTo (MockHttpServletRequest .DEFAULT_SERVER_PORT );
564+ }
565+
566+ @ Test
567+ void xForwardedForSingleIdentifier () throws Exception {
568+ request .addHeader (X_FORWARDED_BY , "203.0.113.195" );
569+ HttpServletRequest actual = filterAndGetWrappedRequest ();
570+
571+ assertThat (actual .getLocalAddr ()).isEqualTo (actual .getLocalAddr ()).isEqualTo ("203.0.113.195" );
572+ assertThat (actual .getLocalPort ()).isEqualTo (MockHttpServletRequest .DEFAULT_SERVER_PORT );
573+ }
574+
575+ @ Test
576+ void xForwardedForMultipleIdentifiers () throws Exception {
577+ request .addHeader (X_FORWARDED_BY , "203.0.113.195, 70.41.3.18, 150.172.238.178" );
578+ HttpServletRequest actual = filterAndGetWrappedRequest ();
579+
580+ assertThat (actual .getLocalAddr ()).isEqualTo (actual .getLocalAddr ()).isEqualTo ("203.0.113.195" );
581+ assertThat (actual .getLocalPort ()).isEqualTo (MockHttpServletRequest .DEFAULT_SERVER_PORT );
582+ }
583+
584+ @ Test
585+ void forwardedForIpV4Identifier () throws Exception {
586+ request .addHeader (FORWARDED , "By=203.0.113.195" );
587+ HttpServletRequest actual = filterAndGetWrappedRequest ();
588+
589+ assertThat (actual .getLocalAddr ()).isEqualTo (actual .getLocalAddr ()).isEqualTo ("203.0.113.195" );
590+ assertThat (actual .getLocalPort ()).isEqualTo (MockHttpServletRequest .DEFAULT_SERVER_PORT );
591+ }
592+
593+ @ Test
594+ void forwardedForIpV6Identifier () throws Exception {
595+ request .addHeader (FORWARDED , "By=\" [2001:db8:cafe::17]\" " );
596+ HttpServletRequest actual = filterAndGetWrappedRequest ();
597+
598+ assertThat (actual .getLocalAddr ()).isEqualTo (actual .getLocalAddr ()).isEqualTo ("[2001:db8:cafe::17]" );
599+ assertThat (actual .getLocalPort ()).isEqualTo (MockHttpServletRequest .DEFAULT_SERVER_PORT );
600+ }
601+
602+ @ Test
603+ void forwardedForIpV4IdentifierWithPort () throws Exception {
604+ request .addHeader (FORWARDED , "By=\" 203.0.113.195:47011\" " );
605+ HttpServletRequest actual = filterAndGetWrappedRequest ();
606+
607+ assertThat (actual .getLocalAddr ()).isEqualTo (actual .getLocalAddr ()).isEqualTo ("203.0.113.195" );
608+ assertThat (actual .getLocalPort ()).isEqualTo (47011 );
609+ }
610+
611+ @ Test
612+ void forwardedForIpV6IdentifierWithPort () throws Exception {
613+ request .addHeader (FORWARDED , "By=\" [2001:db8:cafe::17]:47011\" " );
614+ HttpServletRequest actual = filterAndGetWrappedRequest ();
615+
616+ assertThat (actual .getLocalAddr ()).isEqualTo (actual .getLocalAddr ()).isEqualTo ("[2001:db8:cafe::17]" );
617+ assertThat (actual .getLocalPort ()).isEqualTo (47011 );
618+ }
619+
620+ @ Test
621+ void forwardedForMultipleIdentifiers () throws Exception {
622+ request .addHeader (FORWARDED , "by=203.0.113.195;proto=http, by=\" [2001:db8:cafe::17]\" , by=unknown" );
623+ HttpServletRequest actual = filterAndGetWrappedRequest ();
624+
625+ assertThat (actual .getLocalAddr ()).isEqualTo (actual .getLocalAddr ()).isEqualTo ("203.0.113.195" );
626+ assertThat (actual .getLocalPort ()).isEqualTo (MockHttpServletRequest .DEFAULT_SERVER_PORT );
627+ }
628+
629+ }
630+
544631@ Nested
545632class SendRedirect {
546633
0 commit comments