ClientIPParser { String parse(String remoteAddress, String xForwardedFor) { if (Strings.isBlank(xForwardedFor)) return remoteAddress; int foundForwardedIPs = 1; int index = xForwardedFor.length() - 1; int start; int end = index + 1; while (true) { char ch = xForwardedFor.charAt(index); if (ch == ',') { foundForwardedIPs++; if (foundForwardedIPs > maxForwardedIPs) { start = index + 1; break; } else { end = index; } } if (index == 0) { start = index; break; } index--; } String node = xForwardedFor.substring(start, end).trim(); return extractIP(node); }   public int maxForwardedIPs; }
@Test void withoutProxy() { assertThat(parser.parse("127.0.0.1", null)).isEqualTo("127.0.0.1"); assertThat(parser.parse("127.0.0.1", "")).isEqualTo("127.0.0.1"); }
@Test void withProxy() { assertThat(parser.parse("127.0.0.1", "108.0.0.1")).isEqualTo("108.0.0.1"); assertThat(parser.parse("127.0.0.1", " 108.0.0.1 ")).isEqualTo("108.0.0.1"); assertThat(parser.parse("127.0.0.1", "108.0.0.1, 10.10.10.10")).isEqualTo("108.0.0.1"); }
@Test void exceedMaxForwardedIPs() { assertThat(parser.parse("10.0.0.1", "192.168.0.1,108.0.0.1,10.0.0.1")).isEqualTo("108.0.0.1"); assertThat(parser.parse("10.0.0.1", "192.168.0.1, 192.168.0.1, 108.0.0.1, 10.0.0.1")).isEqualTo("108.0.0.1"); parser.maxForwardedIPs = 1; assertThat(parser.parse("10.0.0.1", "192.168.0.1,108.0.0.1,10.0.0.1")).isEqualTo("10.0.0.1"); assertThat(parser.parse("10.0.0.1", "192.168.0.1, 192.168.0.1, 108.0.0.1, 10.0.0.1")).isEqualTo("10.0.0.1"); parser.maxForwardedIPs = 2; assertThat(parser.parse("10.0.0.1", "192.168.0.1, 192.168.0.2, 192.168.0.3")).isEqualTo("192.168.0.2"); parser.maxForwardedIPs = 3; assertThat(parser.parse("10.0.0.1", "192.168.0.1, 192.168.0.2, 192.168.0.3, 192.168.0.4")).isEqualTo("192.168.0.2"); }
@Test void illegalXForwardedFor() { assertThat(parser.parse("10.0.0.1", ",108.0.0.1,10.0.0.1")).isEqualTo("108.0.0.1"); assertThat(parser.parse("10.0.0.1", "text , 108.0.0.1, 10.0.0.1")).isEqualTo("108.0.0.1"); assertThatThrownBy(() -> parser.parse("10.0.0.1", "text , 10.0.0.1")) .isInstanceOf(BadRequestException.class) .hasMessageContaining("invalid client ip address"); }