proxy v2 skip address length bytes when LOCAL command is specified

Signed-off-by: Ludovic Orban <lorban@bitronix.be>
This commit is contained in:
Ludovic Orban 2020-05-04 17:46:12 +02:00
parent 0ab2b42055
commit d34cb2598b
3 changed files with 114 additions and 0 deletions

View File

@ -662,6 +662,10 @@ public class ProxyConnectionFactory extends DetectorConnectionFactory
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 {} {}", getEndPoint(), proxyEndPoint.toString());
}
else
{
_buffer.position(_buffer.position() + _length);
}
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 parsing dynamic packet part is now done, upgrading to {}", _nextProtocol);

View File

@ -151,6 +151,39 @@ public class ProxyConnectionTest
assertThat(response, Matchers.containsString("remote=ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:12345"));
}
@ParameterizedTest
@MethodSource("requestProcessors")
public void testLocalV2(RequestProcessor p) throws Exception
{
String proxy =
// Preamble
"0D0A0D0A000D0A515549540A" +
// V2, LOCAL
"20" +
// 0x1 : AF_INET 0x1 : STREAM.
"11" +
// Address length is 16.
"0010" +
// gibberish
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
;
String http = "GET /path HTTP/1.1\n" +
"Host: server:80\n" +
"Connection: close\n" +
"\n";
String response = p.sendRequestWaitingForResponse(TypeUtil.fromHexString(proxy), http.getBytes(StandardCharsets.US_ASCII));
assertThat(response, Matchers.containsString("HTTP/1.1 200"));
assertThat(response, Matchers.containsString("pathInfo=/path"));
assertThat(response, Matchers.containsString("local=0.0.0.0:0"));
assertThat(response, Matchers.containsString("remote=0.0.0.0:0"));
}
@ParameterizedTest
@MethodSource("requestProcessors")
public void testMissingField(RequestProcessor p) throws Exception

View File

@ -193,4 +193,81 @@ public class ProxyProtocolTest
}
}
}
@Test
public void testProxyProtocolV2Local() throws Exception
{
start(new AbstractHandler()
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
}
});
try (Socket socket = new Socket("localhost", connector.getLocalPort()))
{
String proxy =
// Preamble
"0D0A0D0A000D0A515549540A" +
// V2, LOCAL
"20" +
// 0x1 : AF_INET 0x1 : STREAM. Address length is 2*4 + 2*2 = 12 bytes.
"11" +
// length of remaining header (4+4+2+2+6+3 = 21)
"0015" +
// uint32_t src_addr; uint32_t dst_addr; uint16_t src_port; uint16_t dst_port;
"C0A80001" +
"7f000001" +
"3039" +
"1F90" +
// NOOP value 0
"040000" +
// NOOP value ABCDEF
"040003ABCDEF";
String request1 =
"GET /1 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n";
OutputStream output = socket.getOutputStream();
output.write(TypeUtil.fromHexString(proxy));
output.write(request1.getBytes(StandardCharsets.UTF_8));
output.flush();
InputStream input = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
String response1 = reader.readLine();
assertTrue(response1.startsWith("HTTP/1.1 200 "));
while (true)
{
if (reader.readLine().isEmpty())
break;
}
// Send a second request to verify that the proxied IP is retained.
String request2 =
"GET /2 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Connection: close\r\n" +
"\r\n";
output.write(request2.getBytes(StandardCharsets.UTF_8));
output.flush();
String response2 = reader.readLine();
assertTrue(response2.startsWith("HTTP/1.1 200 "));
while (true)
{
if (reader.readLine() == null)
break;
}
}
}
}