XForwardForProcessor extends AbstractProcessor<ExecutionContext> { @Override public void handle(ExecutionContext context) { final Request request = context.request(); String xForwardedForHeader = request.headers().getFirst(HttpHeaders.X_FORWARDED_FOR); if (xForwardedForHeader != null && ! xForwardedForHeader.isEmpty()) { String[] xForwardedForValues = commaDelimitedListToStringArray(xForwardedForHeader); if (xForwardedForValues.length > 0) { String xForwardFor = xForwardedForValues[0]; int idx = xForwardFor.indexOf(':'); String[] splits = xForwardFor.split(":"); xForwardFor = (idx == -1) || (splits.length > 2) ? xForwardFor.trim() : xForwardFor.substring(0, idx).trim(); ((MutableExecutionContext) context).request(new XForwardForRequest(request, xForwardFor)); request.metrics().setRemoteAddress(xForwardFor); } } next.handle(context); }  @Override void handle(ExecutionContext context);  }
@Test public void test_not_X_Forward_for_in_Header() throws InterruptedException { final CountDownLatch lock = new CountDownLatch(1); when(headers.getFirst(HttpHeaders.X_FORWARDED_FOR)).thenReturn(null); when(request.remoteAddress()).thenReturn("192.168.0.1"); new XForwardForProcessor() .handler(context -> { Assert.assertFalse(context.request() instanceof XForwardForRequest); Assert.assertEquals("192.168.0.1", context.request().remoteAddress()); Assert.assertNull(context.request().metrics().getRemoteAddress()); lock.countDown(); }) .handle(context); Assert.assertTrue(lock.await(10000, TimeUnit.MILLISECONDS)); }
@Test public void test_with_one_X_Forward_for_in_Header() throws InterruptedException { final CountDownLatch lock = new CountDownLatch(1); when(headers.getFirst(HttpHeaders.X_FORWARDED_FOR)).thenReturn("197.225.30.74"); when(request.remoteAddress()).thenReturn("192.168.0.1"); new XForwardForProcessor() .handler(context -> { Assert.assertTrue(context.request() instanceof XForwardForRequest); Assert.assertEquals("197.225.30.74", context.request().remoteAddress()); Assert.assertEquals("197.225.30.74", context.request().metrics().getRemoteAddress()); lock.countDown(); }) .handle(context); Assert.assertTrue(lock.await(10000, TimeUnit.MILLISECONDS)); }
@Test public void test_with_one_X_Forward_for_in_Header_withPort() throws InterruptedException { final CountDownLatch lock = new CountDownLatch(1); when(headers.getFirst(HttpHeaders.X_FORWARDED_FOR)).thenReturn("197.225.30.74:5000"); when(request.remoteAddress()).thenReturn("192.168.0.1"); new XForwardForProcessor() .handler(context -> { Assert.assertTrue(context.request() instanceof XForwardForRequest); Assert.assertEquals("197.225.30.74", context.request().remoteAddress()); Assert.assertEquals("197.225.30.74", context.request().metrics().getRemoteAddress()); lock.countDown(); }) .handle(context); Assert.assertTrue(lock.await(10000, TimeUnit.MILLISECONDS)); }
@Test public void test_with_many_X_Forward_for_in_Header() throws InterruptedException { final CountDownLatch lock = new CountDownLatch(1); when(headers.getFirst(HttpHeaders.X_FORWARDED_FOR)).thenReturn("197.225.30.74, 10.0.0.1, 10.0.0.2"); when(request.remoteAddress()).thenReturn("192.168.0.1"); new XForwardForProcessor() .handler(context -> { Assert.assertTrue(context.request() instanceof XForwardForRequest); Assert.assertEquals("197.225.30.74", context.request().remoteAddress()); Assert.assertEquals("197.225.30.74", context.request().metrics().getRemoteAddress()); lock.countDown(); }) .handle(context); Assert.assertTrue(lock.await(10000, TimeUnit.MILLISECONDS)); }
@Test public void test_with_many_X_Forward_for_in_Header_withPorts() throws InterruptedException { final CountDownLatch lock = new CountDownLatch(1); when(headers.getFirst(HttpHeaders.X_FORWARDED_FOR)).thenReturn("197.225.30.74:5000, 10.0.0.1, 10.0.0.2"); when(request.remoteAddress()).thenReturn("192.168.0.1"); new XForwardForProcessor() .handler(context -> { Assert.assertTrue(context.request() instanceof XForwardForRequest); Assert.assertEquals("197.225.30.74", context.request().remoteAddress()); Assert.assertEquals("197.225.30.74", context.request().metrics().getRemoteAddress()); lock.countDown(); }) .handle(context); Assert.assertTrue(lock.await(10000, TimeUnit.MILLISECONDS)); }
@Test public void test_with_one_X_Forward_for_in_Header_withIPv6() throws InterruptedException { final CountDownLatch lock = new CountDownLatch(1); when(headers.getFirst(HttpHeaders.X_FORWARDED_FOR)).thenReturn("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); when(request.remoteAddress()).thenReturn("192.168.0.1"); new XForwardForProcessor() .handler(context -> { Assert.assertTrue(context.request() instanceof XForwardForRequest); Assert.assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", context.request().remoteAddress()); Assert.assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", context.request().metrics().getRemoteAddress()); lock.countDown(); }) .handle(context); Assert.assertTrue(lock.await(10000, TimeUnit.MILLISECONDS)); }
@Test public void test_with_one_X_Forward_for_in_Header_withIPv6_hexadecimalFormat() throws InterruptedException { final CountDownLatch lock = new CountDownLatch(1); when(headers.getFirst(HttpHeaders.X_FORWARDED_FOR)).thenReturn("2001:db8:85a3:0:0:8a2e:370:7334"); when(request.remoteAddress()).thenReturn("192.168.0.1"); new XForwardForProcessor() .handler(context -> { Assert.assertTrue(context.request() instanceof XForwardForRequest); Assert.assertEquals("2001:db8:85a3:0:0:8a2e:370:7334", context.request().remoteAddress()); Assert.assertEquals("2001:db8:85a3:0:0:8a2e:370:7334", context.request().metrics().getRemoteAddress()); lock.countDown(); }) .handle(context); Assert.assertTrue(lock.await(10000, TimeUnit.MILLISECONDS)); }
@Test public void test_with_one_X_Forward_for_in_Header_withIPv6_hexadecimalFormat_consecutiveColons() throws InterruptedException { final CountDownLatch lock = new CountDownLatch(1); when(headers.getFirst(HttpHeaders.X_FORWARDED_FOR)).thenReturn("2001:db8:85a3::8a2e:370:7334"); when(request.remoteAddress()).thenReturn("192.168.0.1"); new XForwardForProcessor() .handler(context -> { Assert.assertTrue(context.request() instanceof XForwardForRequest); Assert.assertEquals("2001:db8:85a3::8a2e:370:7334", context.request().remoteAddress()); Assert.assertEquals("2001:db8:85a3::8a2e:370:7334", context.request().metrics().getRemoteAddress()); lock.countDown(); }) .handle(context); Assert.assertTrue(lock.await(10000, TimeUnit.MILLISECONDS)); }