ClientAddressExtractor { public String clientAddressFor(HttpServletRequest request) { ImmutableList.Builder<String> builder = ImmutableList.builder(); for (Enumeration<String> e = request.getHeaders("X-FORWARDED-FOR"); e != null && e.hasMoreElements(); ) { String forwardedFor = e.nextElement(); builder.addAll(Splitter.on(',').trimResults().omitEmptyStrings().split(forwardedFor)); } if (request.getRemoteAddr() != null) { builder.add(request.getRemoteAddr()); } String clientAddress = null; ImmutableList<String> clientAddresses = builder.build(); for (String address : Lists.reverse(clientAddresses)) { try { if (!trustedNetworks.containsAddress(InetAddresses.forString(address))) { clientAddress = address; break; } clientAddress = address; } catch (IllegalArgumentException ignored) { break; } } if (clientAddress == null) { clientAddress = request.getRemoteAddr(); } return clientAddress; } ClientAddressExtractor(); @Inject  ClientAddressExtractor(InternalNetworkConfig config); String clientAddressFor(HttpServletRequest request);  }
@Test public void testIgnoreForwardedFor() { when(request.getRemoteAddr()).thenReturn("9.9.9.9"); when(request.getHeaders("X-FORWARDED-FOR")).thenReturn(Collections.enumeration(ImmutableList.of("1.1.1.1, 2.2.2.2", "3.3.3.3, 4.4.4.4"))); assertEquals(new ClientAddressExtractor().clientAddressFor(request), "9.9.9.9"); }
@Test public void testUseForwardedFor() { when(request.getRemoteAddr()).thenReturn("10.10.10.10"); when(request.getHeaders("X-FORWARDED-FOR")).thenReturn(Collections.enumeration(ImmutableList.of("1.1.1.1, 2.2.2.2", "3.3.3.3, 4.4.4.4"))); assertEquals(new ClientAddressExtractor().clientAddressFor(request), "4.4.4.4"); }
@Test public void testUseForwardedForTwoHops() { when(request.getRemoteAddr()).thenReturn("10.10.10.10"); when(request.getHeaders("X-FORWARDED-FOR")).thenReturn(Collections.enumeration(ImmutableList.of("1.1.1.1, 2.2.2.2", "3.3.3.3, 10.11.12.13"))); assertEquals(new ClientAddressExtractor().clientAddressFor(request), "3.3.3.3"); }
@Test public void testUseForwardedForThreeHops() { when(request.getRemoteAddr()).thenReturn("10.10.10.10"); when(request.getHeaders("X-FORWARDED-FOR")).thenReturn(Collections.enumeration(ImmutableList.of("1.1.1.1, 2.2.2.2", "10.14.15.16, 10.11.12.13"))); assertEquals(new ClientAddressExtractor().clientAddressFor(request), "2.2.2.2"); }
@Test public void testUseForwardedForInternal() { when(request.getRemoteAddr()).thenReturn("10.10.10.10"); when(request.getHeaders("X-FORWARDED-FOR")).thenReturn(Collections.enumeration(ImmutableList.of("10.11.12.13"))); assertEquals(new ClientAddressExtractor().clientAddressFor(request), "10.11.12.13"); }
@Test public void testUseForwardedForInternalTwoHops() { when(request.getRemoteAddr()).thenReturn("10.10.10.10"); when(request.getHeaders("X-FORWARDED-FOR")).thenReturn(Collections.enumeration(ImmutableList.of("10.14.15.16, 10.11.12.13"))); assertEquals(new ClientAddressExtractor().clientAddressFor(request), "10.14.15.16"); }
@Test public void testInvalidIpAddress() { when(request.getRemoteAddr()).thenReturn("10.10.10.10"); when(request.getHeaders("X-FORWARDED-FOR")).thenReturn(Collections.enumeration(ImmutableList.of("notanaddr, 10.14.15.16, 10.11.12.13"))); assertEquals(new ClientAddressExtractor().clientAddressFor(request), "10.14.15.16"); }
@Test(dataProvider = "addresses") public void testAddressUsed(String address, boolean isPrivate) { when(request.getRemoteAddr()).thenReturn(address); when(request.getHeaders("X-FORWARDED-FOR")).thenAnswer(invocation -> Collections.enumeration(ImmutableList.of("1.1.1.1, 2.2.2.2", "3.3.3.3, 4.4.4.4"))); assertEquals(new ClientAddressExtractor().clientAddressFor(request), isPrivate ? "4.4.4.4" : address); assertEquals(new ClientAddressExtractor(new InternalNetworkConfig()).clientAddressFor(request), isPrivate ? "4.4.4.4" : address); if (!isPrivate) { ClientAddressExtractor extractor = new ClientAddressExtractor( new InternalNetworkConfig().setInternalNetworks( CidrSet.fromString(address + "/32"))); assertEquals(extractor.clientAddressFor(request), "4.4.4.4"); } }