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
6768 private static final String X_FORWARDED_FOR = "x-forwarded-for" ;
6869
70+ private static final String X_FORWARDED_BY = "x-forwarded-by" ;
71+
6972
7073 private final ForwardedHeaderFilter filter = new ForwardedHeaderFilter ();
7174
@@ -93,6 +96,7 @@ void shouldFilter() {
9396 testShouldFilter (X_FORWARDED_SSL );
9497 testShouldFilter (X_FORWARDED_PREFIX );
9598 testShouldFilter (X_FORWARDED_FOR );
99+ testShouldFilter (X_FORWARDED_BY );
96100 }
97101
98102 private void testShouldFilter (String headerName ) {
@@ -115,6 +119,7 @@ void forwardedRequest(String protocol) throws Exception {
115119 this .request .addHeader (X_FORWARDED_PORT , "443" );
116120 this .request .addHeader ("foo" , "bar" );
117121 this .request .addHeader (X_FORWARDED_FOR , "[203.0.113.195]" );
122+ this .request .addHeader (X_FORWARDED_BY , "[203.0.113.196]" );
118123
119124 this .filter .doFilter (this .request , new MockHttpServletResponse (), this .filterChain );
120125 HttpServletRequest actual = (HttpServletRequest ) this .filterChain .getRequest ();
@@ -126,11 +131,13 @@ void forwardedRequest(String protocol) throws Exception {
126131 assertThat (actual .getServerPort ()).isEqualTo (443 );
127132 assertThat (actual .isSecure ()).isTrue ();
128133 assertThat (actual .getRemoteAddr ()).isEqualTo (actual .getRemoteHost ()).isEqualTo ("[203.0.113.195]" );
134+ assertThat (actual .getLocalAddr ()).isEqualTo (actual .getLocalAddr ()).isEqualTo ("[203.0.113.196]" );
129135
130136 assertThat (actual .getHeader (X_FORWARDED_PROTO )).isNull ();
131137 assertThat (actual .getHeader (X_FORWARDED_HOST )).isNull ();
132138 assertThat (actual .getHeader (X_FORWARDED_PORT )).isNull ();
133139 assertThat (actual .getHeader (X_FORWARDED_FOR )).isNull ();
140+ assertThat (actual .getHeader (X_FORWARDED_BY )).isNull ();
134141 assertThat (actual .getHeader ("foo" )).isEqualTo ("bar" );
135142 }
136143
@@ -143,6 +150,7 @@ void forwardedRequestInRemoveOnlyMode() throws Exception {
143150 this .request .addHeader (X_FORWARDED_SSL , "on" );
144151 this .request .addHeader ("foo" , "bar" );
145152 this .request .addHeader (X_FORWARDED_FOR , "203.0.113.195" );
153+ this .request .addHeader (X_FORWARDED_BY , "203.0.113.196" );
146154
147155 this .filter .setRemoveOnly (true );
148156 this .filter .doFilter (this .request , new MockHttpServletResponse (), this .filterChain );
@@ -156,12 +164,14 @@ void forwardedRequestInRemoveOnlyMode() throws Exception {
156164 assertThat (actual .isSecure ()).isFalse ();
157165 assertThat (actual .getRemoteAddr ()).isEqualTo (MockHttpServletRequest .DEFAULT_REMOTE_ADDR );
158166 assertThat (actual .getRemoteHost ()).isEqualTo (MockHttpServletRequest .DEFAULT_REMOTE_HOST );
167+ assertThat (actual .getLocalAddr ()).isEqualTo (MockHttpServletRequest .DEFAULT_SERVER_ADDR );
159168
160169 assertThat (actual .getHeader (X_FORWARDED_PROTO )).isNull ();
161170 assertThat (actual .getHeader (X_FORWARDED_HOST )).isNull ();
162171 assertThat (actual .getHeader (X_FORWARDED_PORT )).isNull ();
163172 assertThat (actual .getHeader (X_FORWARDED_SSL )).isNull ();
164173 assertThat (actual .getHeader (X_FORWARDED_FOR )).isNull ();
174+ assertThat (actual .getHeader (X_FORWARDED_BY )).isNull ();
165175 assertThat (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
545632 class SendRedirect {
546633
0 commit comments