Merged branch 'm0mus-issue_4540' into 'jetty-10.0.x'.
This commit is contained in:
commit
7ce14a419f
|
@ -45,6 +45,7 @@ import org.junit.jupiter.api.Test;
|
||||||
import static org.eclipse.jetty.client.ProxyProtocolClientConnectionFactory.V1;
|
import static org.eclipse.jetty.client.ProxyProtocolClientConnectionFactory.V1;
|
||||||
import static org.eclipse.jetty.client.ProxyProtocolClientConnectionFactory.V2;
|
import static org.eclipse.jetty.client.ProxyProtocolClientConnectionFactory.V2;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
@ -165,6 +166,7 @@ public class HttpClientProxyProtocolTest
|
||||||
@Test
|
@Test
|
||||||
public void testClientProxyProtocolV2WithVectors() throws Exception
|
public void testClientProxyProtocolV2WithVectors() throws Exception
|
||||||
{
|
{
|
||||||
|
int typeTLS = 0x20;
|
||||||
String tlsVersion = "TLSv1.3";
|
String tlsVersion = "TLSv1.3";
|
||||||
byte[] tlsVersionBytes = tlsVersion.getBytes(StandardCharsets.US_ASCII);
|
byte[] tlsVersionBytes = tlsVersion.getBytes(StandardCharsets.US_ASCII);
|
||||||
startServer(new EmptyServerHandler()
|
startServer(new EmptyServerHandler()
|
||||||
|
@ -176,7 +178,10 @@ public class HttpClientProxyProtocolTest
|
||||||
assertTrue(endPoint instanceof ProxyConnectionFactory.ProxyEndPoint);
|
assertTrue(endPoint instanceof ProxyConnectionFactory.ProxyEndPoint);
|
||||||
ProxyConnectionFactory.ProxyEndPoint proxyEndPoint = (ProxyConnectionFactory.ProxyEndPoint)endPoint;
|
ProxyConnectionFactory.ProxyEndPoint proxyEndPoint = (ProxyConnectionFactory.ProxyEndPoint)endPoint;
|
||||||
if (target.equals("/tls_version"))
|
if (target.equals("/tls_version"))
|
||||||
|
{
|
||||||
|
assertNotNull(proxyEndPoint.getTLV(typeTLS));
|
||||||
assertEquals(tlsVersion, proxyEndPoint.getAttribute(ProxyConnectionFactory.TLS_VERSION));
|
assertEquals(tlsVersion, proxyEndPoint.getAttribute(ProxyConnectionFactory.TLS_VERSION));
|
||||||
|
}
|
||||||
response.setContentType(MimeTypes.Type.TEXT_PLAIN.asString());
|
response.setContentType(MimeTypes.Type.TEXT_PLAIN.asString());
|
||||||
response.getOutputStream().print(request.getRemotePort());
|
response.getOutputStream().print(request.getRemotePort());
|
||||||
}
|
}
|
||||||
|
@ -186,7 +191,6 @@ public class HttpClientProxyProtocolTest
|
||||||
int serverPort = connector.getLocalPort();
|
int serverPort = connector.getLocalPort();
|
||||||
|
|
||||||
int clientPort = ThreadLocalRandom.current().nextInt(1024, 65536);
|
int clientPort = ThreadLocalRandom.current().nextInt(1024, 65536);
|
||||||
int typeTLS = 0x20;
|
|
||||||
byte[] dataTLS = new byte[1 + 4 + (1 + 2 + tlsVersionBytes.length)];
|
byte[] dataTLS = new byte[1 + 4 + (1 + 2 + tlsVersionBytes.length)];
|
||||||
dataTLS[0] = 0x01; // CLIENT_SSL
|
dataTLS[0] = 0x01; // CLIENT_SSL
|
||||||
dataTLS[5] = 0x21; // SUBTYPE_SSL_VERSION
|
dataTLS[5] = 0x21; // SUBTYPE_SSL_VERSION
|
||||||
|
|
|
@ -95,7 +95,17 @@ import org.eclipse.jetty.util.thread.Invocable;
|
||||||
*/
|
*/
|
||||||
public interface EndPoint extends Closeable
|
public interface EndPoint extends Closeable
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Marks an <code>EndPoint</code> that wraps another <code>EndPoint</code>.
|
||||||
|
*/
|
||||||
|
public interface Wrapper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return The wrapped <code>EndPoint</code>
|
||||||
|
*/
|
||||||
|
EndPoint unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The local Inet address to which this <code>EndPoint</code> is bound, or <code>null</code>
|
* @return The local Inet address to which this <code>EndPoint</code> is bound, or <code>null</code>
|
||||||
* if this <code>EndPoint</code> does not represent a network connection.
|
* if this <code>EndPoint</code> does not represent a network connection.
|
||||||
|
|
|
@ -457,7 +457,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
|
||||||
return getEndPoint().flush(output);
|
return getEndPoint().flush(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DecryptedEndPoint extends AbstractEndPoint
|
public class DecryptedEndPoint extends AbstractEndPoint implements EndPoint.Wrapper
|
||||||
{
|
{
|
||||||
private final Callback _incompleteWriteCallback = new IncompleteWriteCallback();
|
private final Callback _incompleteWriteCallback = new IncompleteWriteCallback();
|
||||||
private Throwable _failure;
|
private Throwable _failure;
|
||||||
|
@ -469,6 +469,12 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
|
||||||
super.setIdleTimeout(-1);
|
super.setIdleTimeout(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EndPoint unwrap()
|
||||||
|
{
|
||||||
|
return getEndPoint();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getIdleTimeout()
|
public long getIdleTimeout()
|
||||||
{
|
{
|
||||||
|
@ -682,7 +688,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_underflown = false;
|
_underflown = false;
|
||||||
unwrapResult = unwrap(_sslEngine, _encryptedInput, appIn);
|
unwrapResult = SslConnection.this.unwrap(_sslEngine, _encryptedInput, appIn);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -1554,5 +1560,6 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
|
||||||
return String.format("SSL@%h.DEP.writeCallback", SslConnection.this);
|
return String.format("SSL@%h.DEP.writeCallback", SslConnection.this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@ import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.ReadPendingException;
|
import java.nio.channels.ReadPendingException;
|
||||||
import java.nio.channels.WritePendingException;
|
import java.nio.channels.WritePendingException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.AbstractConnection;
|
import org.eclipse.jetty.io.AbstractConnection;
|
||||||
import org.eclipse.jetty.io.Connection;
|
import org.eclipse.jetty.io.Connection;
|
||||||
|
@ -366,6 +368,7 @@ public class ProxyConnectionFactory extends DetectorConnectionFactory
|
||||||
{
|
{
|
||||||
0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A
|
0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A
|
||||||
};
|
};
|
||||||
|
|
||||||
private final String _nextProtocol;
|
private final String _nextProtocol;
|
||||||
private int _maxProxyHeader = 1024;
|
private int _maxProxyHeader = 1024;
|
||||||
|
|
||||||
|
@ -545,7 +548,6 @@ public class ProxyConnectionFactory extends DetectorConnectionFactory
|
||||||
|
|
||||||
private void parseBodyAndUpgrade() throws IOException
|
private void parseBodyAndUpgrade() throws IOException
|
||||||
{
|
{
|
||||||
// stop reading when bufferRemainingReserve bytes are remaining in the buffer
|
|
||||||
int nonProxyRemaining = _buffer.remaining() - _length;
|
int nonProxyRemaining = _buffer.remaining() - _length;
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Proxy v2 parsing body, length = {}, buffer = {}", _length, BufferUtil.toHexSummary(_buffer));
|
LOG.debug("Proxy v2 parsing body, length = {}, buffer = {}", _length, BufferUtil.toHexSummary(_buffer));
|
||||||
|
@ -609,53 +611,30 @@ public class ProxyConnectionFactory extends DetectorConnectionFactory
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug(String.format("Proxy v2 T=%x L=%d V=%s for %s", type, length, TypeUtil.toHexString(value), this));
|
LOG.debug(String.format("Proxy v2 T=%x L=%d V=%s for %s", type, length, TypeUtil.toHexString(value), this));
|
||||||
|
|
||||||
switch (type)
|
// PP2_TYPE_NOOP is only used for byte alignment, skip them.
|
||||||
|
if (type != ProxyEndPoint.PP2_TYPE_NOOP)
|
||||||
|
proxyEndPoint.putTLV(type, value);
|
||||||
|
|
||||||
|
if (type == ProxyEndPoint.PP2_TYPE_SSL)
|
||||||
{
|
{
|
||||||
case 0x20: // PP2_TYPE_SSL
|
int client = value[0] & 0xFF;
|
||||||
|
if (client == ProxyEndPoint.PP2_TYPE_SSL_PP2_CLIENT_SSL)
|
||||||
{
|
{
|
||||||
int client = value[0] & 0xFF;
|
int i = 5; // Index of the first sub_tlv, after verify.
|
||||||
switch (client)
|
while (i < length)
|
||||||
{
|
{
|
||||||
case 0x01: // PP2_CLIENT_SSL
|
int subType = value[i++] & 0xFF;
|
||||||
|
int subLength = (value[i++] & 0xFF) * 256 + (value[i++] & 0xFF);
|
||||||
|
byte[] subValue = new byte[subLength];
|
||||||
|
System.arraycopy(value, i, subValue, 0, subLength);
|
||||||
|
i += subLength;
|
||||||
|
if (subType == ProxyEndPoint.PP2_SUBTYPE_SSL_VERSION)
|
||||||
{
|
{
|
||||||
int i = 5; // Index of the first sub_tlv, after verify.
|
String tlsVersion = new String(subValue, StandardCharsets.US_ASCII);
|
||||||
while (i < length)
|
proxyEndPoint.setAttribute(TLS_VERSION, tlsVersion);
|
||||||
{
|
|
||||||
int subType = value[i++] & 0xFF;
|
|
||||||
int subLength = (value[i++] & 0xFF) * 256 + (value[i++] & 0xFF);
|
|
||||||
byte[] subValue = new byte[subLength];
|
|
||||||
System.arraycopy(value, i, subValue, 0, subLength);
|
|
||||||
i += subLength;
|
|
||||||
switch (subType)
|
|
||||||
{
|
|
||||||
case 0x21: // PP2_SUBTYPE_SSL_VERSION
|
|
||||||
String tlsVersion = new String(subValue, StandardCharsets.US_ASCII);
|
|
||||||
proxyEndPoint.setAttribute(TLS_VERSION, tlsVersion);
|
|
||||||
break;
|
|
||||||
case 0x22: // PP2_SUBTYPE_SSL_CN
|
|
||||||
case 0x23: // PP2_SUBTYPE_SSL_CIPHER
|
|
||||||
case 0x24: // PP2_SUBTYPE_SSL_SIG_ALG
|
|
||||||
case 0x25: // PP2_SUBTYPE_SSL_KEY_ALG
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case 0x02: // PP2_CLIENT_CERT_CONN
|
|
||||||
case 0x04: // PP2_CLIENT_CERT_SESS
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case 0x01: // PP2_TYPE_ALPN
|
|
||||||
case 0x02: // PP2_TYPE_AUTHORITY
|
|
||||||
case 0x03: // PP2_TYPE_CRC32C
|
|
||||||
case 0x04: // PP2_TYPE_NOOP
|
|
||||||
case 0x30: // PP2_TYPE_NETNS
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,71 +730,106 @@ public class ProxyConnectionFactory extends DetectorConnectionFactory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ProxyEndPoint extends AttributesMap implements EndPoint
|
public static class ProxyEndPoint extends AttributesMap implements EndPoint, EndPoint.Wrapper
|
||||||
{
|
{
|
||||||
private final EndPoint _endp;
|
private static final int PP2_TYPE_NOOP = 0x04;
|
||||||
|
private static final int PP2_TYPE_SSL = 0x20;
|
||||||
|
private static final int PP2_TYPE_SSL_PP2_CLIENT_SSL = 0x01;
|
||||||
|
private static final int PP2_SUBTYPE_SSL_VERSION = 0x21;
|
||||||
|
|
||||||
|
private final EndPoint _endPoint;
|
||||||
private final InetSocketAddress _remote;
|
private final InetSocketAddress _remote;
|
||||||
private final InetSocketAddress _local;
|
private final InetSocketAddress _local;
|
||||||
|
private Map<Integer, byte[]> _tlvs;
|
||||||
|
|
||||||
public ProxyEndPoint(EndPoint endp, InetSocketAddress remote, InetSocketAddress local)
|
public ProxyEndPoint(EndPoint endPoint, InetSocketAddress remote, InetSocketAddress local)
|
||||||
{
|
{
|
||||||
_endp = endp;
|
_endPoint = endPoint;
|
||||||
_remote = remote;
|
_remote = remote;
|
||||||
_local = local;
|
_local = local;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EndPoint unwrap()
|
||||||
|
{
|
||||||
|
return _endPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Sets a TLV vector, see section 2.2.7 of the PROXY protocol specification.</p>
|
||||||
|
*
|
||||||
|
* @param type the TLV type
|
||||||
|
* @param value the TLV value
|
||||||
|
*/
|
||||||
|
private void putTLV(int type, byte[] value)
|
||||||
|
{
|
||||||
|
if (_tlvs == null)
|
||||||
|
_tlvs = new HashMap<>();
|
||||||
|
_tlvs.put(type, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Gets a TLV vector, see section 2.2.7 of the PROXY protocol specification.</p>
|
||||||
|
*
|
||||||
|
* @param type the TLV type
|
||||||
|
* @return the TLV value or null if not present.
|
||||||
|
*/
|
||||||
|
public byte[] getTLV(int type)
|
||||||
|
{
|
||||||
|
return _tlvs != null ? _tlvs.get(type) : null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close(Throwable cause)
|
public void close(Throwable cause)
|
||||||
{
|
{
|
||||||
_endp.close(cause);
|
_endPoint.close(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int fill(ByteBuffer buffer) throws IOException
|
public int fill(ByteBuffer buffer) throws IOException
|
||||||
{
|
{
|
||||||
return _endp.fill(buffer);
|
return _endPoint.fill(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fillInterested(Callback callback) throws ReadPendingException
|
public void fillInterested(Callback callback) throws ReadPendingException
|
||||||
{
|
{
|
||||||
_endp.fillInterested(callback);
|
_endPoint.fillInterested(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean flush(ByteBuffer... buffer) throws IOException
|
public boolean flush(ByteBuffer... buffer) throws IOException
|
||||||
{
|
{
|
||||||
return _endp.flush(buffer);
|
return _endPoint.flush(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Connection getConnection()
|
public Connection getConnection()
|
||||||
{
|
{
|
||||||
return _endp.getConnection();
|
return _endPoint.getConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setConnection(Connection connection)
|
public void setConnection(Connection connection)
|
||||||
{
|
{
|
||||||
_endp.setConnection(connection);
|
_endPoint.setConnection(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getCreatedTimeStamp()
|
public long getCreatedTimeStamp()
|
||||||
{
|
{
|
||||||
return _endp.getCreatedTimeStamp();
|
return _endPoint.getCreatedTimeStamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getIdleTimeout()
|
public long getIdleTimeout()
|
||||||
{
|
{
|
||||||
return _endp.getIdleTimeout();
|
return _endPoint.getIdleTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIdleTimeout(long idleTimeout)
|
public void setIdleTimeout(long idleTimeout)
|
||||||
{
|
{
|
||||||
_endp.setIdleTimeout(idleTimeout);
|
_endPoint.setIdleTimeout(idleTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -833,49 +847,49 @@ public class ProxyConnectionFactory extends DetectorConnectionFactory
|
||||||
@Override
|
@Override
|
||||||
public Object getTransport()
|
public Object getTransport()
|
||||||
{
|
{
|
||||||
return _endp.getTransport();
|
return _endPoint.getTransport();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFillInterested()
|
public boolean isFillInterested()
|
||||||
{
|
{
|
||||||
return _endp.isFillInterested();
|
return _endPoint.isFillInterested();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInputShutdown()
|
public boolean isInputShutdown()
|
||||||
{
|
{
|
||||||
return _endp.isInputShutdown();
|
return _endPoint.isInputShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOpen()
|
public boolean isOpen()
|
||||||
{
|
{
|
||||||
return _endp.isOpen();
|
return _endPoint.isOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOutputShutdown()
|
public boolean isOutputShutdown()
|
||||||
{
|
{
|
||||||
return _endp.isOutputShutdown();
|
return _endPoint.isOutputShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClose(Throwable cause)
|
public void onClose(Throwable cause)
|
||||||
{
|
{
|
||||||
_endp.onClose(cause);
|
_endPoint.onClose(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOpen()
|
public void onOpen()
|
||||||
{
|
{
|
||||||
_endp.onOpen();
|
_endPoint.onOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void shutdownOutput()
|
public void shutdownOutput()
|
||||||
{
|
{
|
||||||
_endp.shutdownOutput();
|
_endPoint.shutdownOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -886,25 +900,25 @@ public class ProxyConnectionFactory extends DetectorConnectionFactory
|
||||||
hashCode(),
|
hashCode(),
|
||||||
_remote,
|
_remote,
|
||||||
_local,
|
_local,
|
||||||
_endp);
|
_endPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tryFillInterested(Callback callback)
|
public boolean tryFillInterested(Callback callback)
|
||||||
{
|
{
|
||||||
return _endp.tryFillInterested(callback);
|
return _endPoint.tryFillInterested(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void upgrade(Connection newConnection)
|
public void upgrade(Connection newConnection)
|
||||||
{
|
{
|
||||||
_endp.upgrade(newConnection);
|
_endPoint.upgrade(newConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(Callback callback, ByteBuffer... buffers) throws WritePendingException
|
public void write(Callback callback, ByteBuffer... buffers) throws WritePendingException
|
||||||
{
|
{
|
||||||
_endp.write(callback, buffers);
|
_endPoint.write(callback, buffers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,13 @@ import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
|
import org.eclipse.jetty.server.ProxyConnectionFactory.ProxyEndPoint;
|
||||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||||
import org.eclipse.jetty.util.TypeUtil;
|
import org.eclipse.jetty.util.TypeUtil;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
@ -118,15 +121,29 @@ public class ProxyProtocolTest
|
||||||
{
|
{
|
||||||
final String remoteAddr = "192.168.0.1";
|
final String remoteAddr = "192.168.0.1";
|
||||||
final int remotePort = 12345;
|
final int remotePort = 12345;
|
||||||
|
final byte[] customE0 = new byte[] {1, 2};
|
||||||
|
final byte[] customE1 = new byte[] {-1, -1, -1};
|
||||||
|
|
||||||
start(new AbstractHandler()
|
start(new AbstractHandler()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||||
{
|
{
|
||||||
if (remoteAddr.equals(request.getRemoteAddr()) &&
|
if (validateEndPoint(baseRequest) &&
|
||||||
|
remoteAddr.equals(request.getRemoteAddr()) &&
|
||||||
remotePort == request.getRemotePort())
|
remotePort == request.getRemotePort())
|
||||||
baseRequest.setHandled(true);
|
baseRequest.setHandled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean validateEndPoint(Request request)
|
||||||
|
{
|
||||||
|
HttpConnection con = (HttpConnection)request.getAttribute(HttpConnection.class.getName());
|
||||||
|
EndPoint endPoint = con.getEndPoint();
|
||||||
|
ProxyEndPoint proxyEndPoint = (ProxyEndPoint)endPoint;
|
||||||
|
return Arrays.equals(customE0, proxyEndPoint.getTLV(0xE0)) &&
|
||||||
|
Arrays.equals(customE1, proxyEndPoint.getTLV(0xE1)) &&
|
||||||
|
proxyEndPoint.getTLV(0xE2) == null;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
try (Socket socket = new Socket("localhost", connector.getLocalPort()))
|
try (Socket socket = new Socket("localhost", connector.getLocalPort()))
|
||||||
|
@ -141,8 +158,8 @@ public class ProxyProtocolTest
|
||||||
// 0x1 : AF_INET 0x1 : STREAM. Address length is 2*4 + 2*2 = 12 bytes.
|
// 0x1 : AF_INET 0x1 : STREAM. Address length is 2*4 + 2*2 = 12 bytes.
|
||||||
"11" +
|
"11" +
|
||||||
|
|
||||||
// length of remaining header (4+4+2+2+6+3 = 21)
|
// length of remaining header (4+4+2+2+3+6+5+6 = 32)
|
||||||
"0015" +
|
"0020" +
|
||||||
|
|
||||||
// uint32_t src_addr; uint32_t dst_addr; uint16_t src_port; uint16_t dst_port;
|
// uint32_t src_addr; uint32_t dst_addr; uint16_t src_port; uint16_t dst_port;
|
||||||
"C0A80001" +
|
"C0A80001" +
|
||||||
|
@ -154,7 +171,13 @@ public class ProxyProtocolTest
|
||||||
"040000" +
|
"040000" +
|
||||||
|
|
||||||
// NOOP value ABCDEF
|
// NOOP value ABCDEF
|
||||||
"040003ABCDEF";
|
"040003ABCDEF" +
|
||||||
|
|
||||||
|
// Custom 0xEO {0x01,0x02}
|
||||||
|
"E000020102" +
|
||||||
|
|
||||||
|
// Custom 0xE1 {0xFF,0xFF,0xFF}
|
||||||
|
"E10003FFFFFF";
|
||||||
|
|
||||||
String request1 =
|
String request1 =
|
||||||
"GET /1 HTTP/1.1\r\n" +
|
"GET /1 HTTP/1.1\r\n" +
|
||||||
|
@ -193,4 +216,5 @@ public class ProxyProtocolTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue