org.eclipse.jetty.server.ProxyConnectionFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ReadPendingException;
import java.nio.channels.WritePendingException;
import java.nio.charset.StandardCharsets;
import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.AttributesMap;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* ConnectionFactory for the PROXY Protocol.
* This factory can be placed in front of any other connection factory
* to process the proxy v1 or v2 line before the normal protocol handling
*
* @see http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt
*
* @deprecated The Eclipse Jetty and Apache Felix Http Jetty packages are no longer supported.
*/
@Deprecated(since = "2021-05-27")
public class ProxyConnectionFactory extends DetectorConnectionFactory {
public static final String TLS_VERSION = "TLS_VERSION";
private static final Logger LOG = Log.getLogger(ProxyConnectionFactory.class);
public ProxyConnectionFactory() {
this(null);
}
public ProxyConnectionFactory(String nextProtocol) {
super(new ProxyV1ConnectionFactory(nextProtocol), new ProxyV2ConnectionFactory(nextProtocol));
}
private static ConnectionFactory findNextConnectionFactory(String nextProtocol, Connector connector, String currentProtocol, EndPoint endp) {
currentProtocol = "[" + currentProtocol + "]";
if (LOG.isDebugEnabled())
LOG.debug("finding connection factory following {} for protocol {}", currentProtocol, nextProtocol);
String nextProtocolToFind = nextProtocol;
if (nextProtocol == null)
nextProtocolToFind = AbstractConnectionFactory.findNextProtocol(connector, currentProtocol);
if (nextProtocolToFind == null)
throw new IllegalStateException("Cannot find protocol following '" + currentProtocol + "' in connector's protocol list " + connector.getProtocols() + " for " + endp);
ConnectionFactory connectionFactory = connector.getConnectionFactory(nextProtocolToFind);
if (connectionFactory == null)
throw new IllegalStateException("Cannot find protocol '" + nextProtocol + "' in connector's protocol list " + connector.getProtocols() + " for " + endp);
if (LOG.isDebugEnabled())
LOG.debug("found next connection factory {} for protocol {}", connectionFactory, nextProtocol);
return connectionFactory;
}
public int getMaxProxyHeader() {
ProxyV2ConnectionFactory v2 = getBean(ProxyV2ConnectionFactory.class);
return v2.getMaxProxyHeader();
}
public void setMaxProxyHeader(int maxProxyHeader) {
ProxyV2ConnectionFactory v2 = getBean(ProxyV2ConnectionFactory.class);
v2.setMaxProxyHeader(maxProxyHeader);
}
// @deprecated The Eclipse Jetty and Apache Felix Http Jetty packages are no longer supported.
@Deprecated(since = "2021-05-27")
private static class ProxyV1ConnectionFactory extends AbstractConnectionFactory implements Detecting {
private static final byte[] SIGNATURE = "PROXY".getBytes(StandardCharsets.US_ASCII);
private final String _nextProtocol;
private ProxyV1ConnectionFactory(String nextProtocol) {
super("proxy");
this._nextProtocol = nextProtocol;
}
@Override
public Detection detect(ByteBuffer buffer) {
if (LOG.isDebugEnabled())
LOG.debug("Proxy v1 attempting detection with {} bytes", buffer.remaining());
if (buffer.remaining() < SIGNATURE.length) {
if (LOG.isDebugEnabled())
LOG.debug("Proxy v1 detection requires more bytes");
return Detection.NEED_MORE_BYTES;
}
for (int i = 0; i < SIGNATURE.length; i++) {
byte signatureByte = SIGNATURE[i];
byte byteInBuffer = buffer.get(i);
if (byteInBuffer != signatureByte) {
if (LOG.isDebugEnabled())
LOG.debug("Proxy v1 detection unsuccessful");
return Detection.NOT_RECOGNIZED;
}
}
if (LOG.isDebugEnabled())
LOG.debug("Proxy v1 detection succeeded");
return Detection.RECOGNIZED;
}
@Override
public Connection newConnection(Connector connector, EndPoint endp) {
ConnectionFactory nextConnectionFactory = findNextConnectionFactory(_nextProtocol, connector, getProtocol(), endp);
return configure(new ProxyProtocolV1Connection(endp, connector, nextConnectionFactory), connector, endp);
}
// @deprecated The Eclipse Jetty and Apache Felix Http Jetty packages are no longer supported.
@Deprecated(since = "2021-05-27")
private static class ProxyProtocolV1Connection extends AbstractConnection implements Connection.UpgradeFrom, Connection.UpgradeTo {
// 0 1 2 3 4 5 6
// 98765432109876543210987654321
// PROXY P R.R.R.R L.L.L.L R Lrn
private static final int CR_INDEX = 6;
private static final int LF_INDEX = 7;
private final Connector _connector;
private final ConnectionFactory _next;
private final ByteBuffer _buffer;
private final StringBuilder _builder = new StringBuilder();
private final String[] _fields = new String[6];
private int _index;
private int _length;
private ProxyProtocolV1Connection(EndPoint endp, Connector connector, ConnectionFactory next) {
super(endp, connector.getExecutor());
_connector = connector;
_next = next;
_buffer = _connector.getByteBufferPool().acquire(getInputBufferSize(), true);
}
@Override
public void onFillable() {
if (LOG.isDebugEnabled())
LOG.debug("Proxy v1 onFillable current index = ", _index);
try {
while (_index < LF_INDEX) {
// Read data
int fill = getEndPoint().fill(_buffer);
if (LOG.isDebugEnabled())
LOG.debug("Proxy v1 filled buffer with {} bytes", fill);
if (fill < 0) {
_connector.getByteBufferPool().release(_buffer);
getEndPoint().shutdownOutput();
return;
}
if (fill == 0) {
fillInterested();
return;
}
if (parse())
break;
}
if (LOG.isDebugEnabled())
LOG.debug("Proxy v1 onFillable parsing done, now upgrading");
upgrade();
} catch (Throwable x) {
LOG.warn("Proxy v1 error for {}", getEndPoint(), x);
releaseAndClose();
}
}
@Override
public void onOpen() {
super.onOpen();
try {
while (_index < LF_INDEX) {
if (!parse()) {
if (LOG.isDebugEnabled())
LOG.debug("Proxy v1 onOpen parsing ran out of bytes, marking as fillInterested");
fillInterested();
return;
}
}
if (LOG.isDebugEnabled())
LOG.debug("Proxy v1 onOpen parsing done, now upgrading");
upgrade();
} catch (Throwable x) {
LOG.warn("Proxy v1 error for {}", getEndPoint(), x);
releaseAndClose();
}
}
@Override
public ByteBuffer onUpgradeFrom() {
if (_buffer.hasRemaining()) {
ByteBuffer unconsumed = ByteBuffer.allocateDirect(_buffer.remaining());
unconsumed.put(_buffer);
unconsumed.flip();
_connector.getByteBufferPool().release(_buffer);
return unconsumed;
}
return null;
}
@Override
public void onUpgradeTo(ByteBuffer buffer) {
if (LOG.isDebugEnabled())
LOG.debug("Proxy v1 copying unconsumed buffer {}", BufferUtil.toDetailString(buffer));
BufferUtil.append(_buffer, buffer);
}
/**
* @return true when parsing is done, false when more bytes are needed.
*/
private boolean parse() throws IOException {
if (LOG.isDebugEnabled())
LOG.debug("Proxy v1 parsing {}", BufferUtil.toDetailString(_buffer));
_length += _buffer.remaining();
// Parse fields
while (_buffer.hasRemaining()) {
byte b = _buffer.get();
if (_index < CR_INDEX) {
if (b == ' ' || b == '\r') {
_fields[_index++] = _builder.toString();
_builder.setLength(0);
if (b == '\r')
_index = CR_INDEX;
} else if (b < ' ') {
throw new IOException("Proxy v1 bad character " + (b & 0xFF));
} else {
_builder.append((char) b);
}
} else {
if (b == '\n') {
_index = LF_INDEX;
if (LOG.isDebugEnabled())
LOG.debug("Proxy v1 parsing is done");
return true;
}
throw new IOException("Proxy v1 bad CRLF " + (b & 0xFF));
}
}
// Not enough bytes.
if (LOG.isDebugEnabled())
LOG.debug("Proxy v1 parsing requires more bytes");
return false;
}
private void releaseAndClose() {
if (LOG.isDebugEnabled())
LOG.debug("Proxy v1 releasing buffer and closing");
_connector.getByteBufferPool().release(_buffer);
close();
}
private void upgrade() {
int proxyLineLength = _length - _buffer.remaining();
if (LOG.isDebugEnabled())
LOG.debug("Proxy v1 pre-upgrade packet length (including CRLF) is {}", proxyLineLength);
if (proxyLineLength >= 110) {
LOG.warn("Proxy v1 PROXY line too long {} for {}", proxyLineLength, getEndPoint());
releaseAndClose();
return;
}
// Check proxy
if (!"PROXY".equals(_fields[0])) {
LOG.warn("Proxy v1 not PROXY protocol for {}", getEndPoint());
releaseAndClose();
return;
}
String srcIP = _fields[2];
String srcPort = _fields[4];
String dstIP = _fields[3];
String dstPort = _fields[5];
// If UNKNOWN, we must ignore the information sent, so use the EndPoint's.
boolean unknown = "UNKNOWN".equalsIgnoreCase(_fields[1]);
if (unknown) {
srcIP = getEndPoint().getRemoteAddress().getAddress().getHostAddress();
srcPort = String.valueOf(getEndPoint().getRemoteAddress().getPort());
dstIP = getEndPoint().getLocalAddress().getAddress().getHostAddress();
dstPort = String.valueOf(getEndPoint().getLocalAddress().getPort());
}
InetSocketAddress remote = new InetSocketAddress(srcIP, Integer.parseInt(srcPort));
InetSocketAddress local = new InetSocketAddress(dstIP, Integer.parseInt(dstPort));
if (LOG.isDebugEnabled())
LOG.debug("Proxy v1 next protocol '{}' for {} r={} l={}", _next, getEndPoint(), remote, local);
EndPoint endPoint = new ProxyEndPoint(getEndPoint(), remote, local);
upgradeToConnectionFactory(_next, _connector, endPoint);
}
}
}
// @deprecated The Eclipse Jetty and Apache Felix Http Jetty packages are no longer supported.
@Deprecated(since = "2021-05-27")
private static class ProxyV2ConnectionFactory extends AbstractConnectionFactory implements Detecting {
private enum Family {
UNSPEC, INET, INET6, UNIX
}
private enum Transport {
UNSPEC, STREAM, DGRAM
}
private static final byte[] SIGNATURE = new byte[] { 0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A };
private final String _nextProtocol;
private int _maxProxyHeader = 1024;
private ProxyV2ConnectionFactory(String nextProtocol) {
super("proxy");
this._nextProtocol = nextProtocol;
}
@Override
public Detection detect(ByteBuffer buffer) {
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 attempting detection with {} bytes", buffer.remaining());
if (buffer.remaining() < SIGNATURE.length) {
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 detection requires more bytes");
return Detection.NEED_MORE_BYTES;
}
for (int i = 0; i < SIGNATURE.length; i++) {
byte signatureByte = SIGNATURE[i];
byte byteInBuffer = buffer.get(i);
if (byteInBuffer != signatureByte) {
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 detection unsuccessful");
return Detection.NOT_RECOGNIZED;
}
}
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 detection succeeded");
return Detection.RECOGNIZED;
}
public int getMaxProxyHeader() {
return _maxProxyHeader;
}
public void setMaxProxyHeader(int maxProxyHeader) {
_maxProxyHeader = maxProxyHeader;
}
@Override
public Connection newConnection(Connector connector, EndPoint endp) {
ConnectionFactory nextConnectionFactory = findNextConnectionFactory(_nextProtocol, connector, getProtocol(), endp);
return configure(new ProxyProtocolV2Connection(endp, connector, nextConnectionFactory), connector, endp);
}
// @deprecated The Eclipse Jetty and Apache Felix Http Jetty packages are no longer supported.
@Deprecated(since = "2021-05-27")
private class ProxyProtocolV2Connection extends AbstractConnection implements Connection.UpgradeFrom, Connection.UpgradeTo {
private static final int HEADER_LENGTH = 16;
private final Connector _connector;
private final ConnectionFactory _next;
private final ByteBuffer _buffer;
private boolean _local;
private Family _family;
private int _length;
private boolean _headerParsed;
protected ProxyProtocolV2Connection(EndPoint endp, Connector connector, ConnectionFactory next) {
super(endp, connector.getExecutor());
_connector = connector;
_next = next;
_buffer = _connector.getByteBufferPool().acquire(getInputBufferSize(), true);
}
@Override
public void onUpgradeTo(ByteBuffer buffer) {
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 copying unconsumed buffer {}", BufferUtil.toDetailString(buffer));
BufferUtil.append(_buffer, buffer);
}
@Override
public void onOpen() {
super.onOpen();
try {
parseHeader();
if (_headerParsed && _buffer.remaining() >= _length) {
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 onOpen parsing fixed length packet part done, now upgrading");
parseBodyAndUpgrade();
} else {
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 onOpen parsing fixed length packet ran out of bytes, marking as fillInterested");
fillInterested();
}
} catch (Exception x) {
LOG.warn("Proxy v2 error for {}", getEndPoint(), x);
releaseAndClose();
}
}
@Override
public void onFillable() {
try {
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 onFillable header parsed? ", _headerParsed);
while (!_headerParsed) {
// Read data
int fill = getEndPoint().fill(_buffer);
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 filled buffer with {} bytes", fill);
if (fill < 0) {
_connector.getByteBufferPool().release(_buffer);
getEndPoint().shutdownOutput();
return;
}
if (fill == 0) {
fillInterested();
return;
}
parseHeader();
}
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 onFillable header parsed, length = {}, buffer = {}", _length, BufferUtil.toDetailString(_buffer));
while (_buffer.remaining() < _length) {
// Read data
int fill = getEndPoint().fill(_buffer);
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 filled buffer with {} bytes", fill);
if (fill < 0) {
_connector.getByteBufferPool().release(_buffer);
getEndPoint().shutdownOutput();
return;
}
if (fill == 0) {
fillInterested();
return;
}
}
parseBodyAndUpgrade();
} catch (Throwable x) {
LOG.warn("Proxy v2 error for " + getEndPoint(), x);
releaseAndClose();
}
}
@Override
public ByteBuffer onUpgradeFrom() {
if (_buffer.hasRemaining()) {
ByteBuffer unconsumed = ByteBuffer.allocateDirect(_buffer.remaining());
unconsumed.put(_buffer);
unconsumed.flip();
_connector.getByteBufferPool().release(_buffer);
return unconsumed;
}
return null;
}
private void parseBodyAndUpgrade() throws IOException {
// stop reading when bufferRemainingReserve bytes are remaining in the buffer
int nonProxyRemaining = _buffer.remaining() - _length;
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 parsing body, length = {}, buffer = {}", _length, BufferUtil.toHexSummary(_buffer));
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 body {} from {} for {}", _next, BufferUtil.toHexSummary(_buffer), this);
// Do we need to wrap the endpoint?
EndPoint endPoint = getEndPoint();
if (!_local) {
InetAddress src;
InetAddress dst;
int sp;
int dp;
switch(_family) {
case INET:
{
byte[] addr = new byte[4];
_buffer.get(addr);
src = Inet4Address.getByAddress(addr);
_buffer.get(addr);
dst = Inet4Address.getByAddress(addr);
sp = _buffer.getChar();
dp = _buffer.getChar();
break;
}
case INET6:
{
byte[] addr = new byte[16];
_buffer.get(addr);
src = Inet6Address.getByAddress(addr);
_buffer.get(addr);
dst = Inet6Address.getByAddress(addr);
sp = _buffer.getChar();
dp = _buffer.getChar();
break;
}
default:
throw new IllegalStateException();
}
// Extract Addresses
InetSocketAddress remote = new InetSocketAddress(src, sp);
InetSocketAddress local = new InetSocketAddress(dst, dp);
ProxyEndPoint proxyEndPoint = new ProxyEndPoint(endPoint, remote, local);
endPoint = proxyEndPoint;
// Any additional info?
while (_buffer.remaining() > nonProxyRemaining) {
int type = 0xff & _buffer.get();
int length = _buffer.getChar();
byte[] value = new byte[length];
_buffer.get(value);
if (LOG.isDebugEnabled())
LOG.debug(String.format("Proxy v2 T=%x L=%d V=%s for %s", type, length, TypeUtil.toHexString(value), this));
switch(type) {
case // PP2_TYPE_SSL
0x20:
{
int client = value[0] & 0xFF;
switch(client) {
case // PP2_CLIENT_SSL
0x01:
{
// Index of the first sub_tlv, after verify.
int i = 5;
while (i < length) {
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 // PP2_SUBTYPE_SSL_VERSION
0x21:
String tlsVersion = new String(subValue, StandardCharsets.US_ASCII);
proxyEndPoint.setAttribute(TLS_VERSION, tlsVersion);
break;
// PP2_SUBTYPE_SSL_CN
case 0x22:
// PP2_SUBTYPE_SSL_CIPHER
case 0x23:
// PP2_SUBTYPE_SSL_SIG_ALG
case 0x24:
// PP2_SUBTYPE_SSL_KEY_ALG
case 0x25:
default:
break;
}
}
break;
}
// PP2_CLIENT_CERT_CONN
case 0x02:
// PP2_CLIENT_CERT_SESS
case 0x04:
default:
break;
}
break;
}
// PP2_TYPE_ALPN
case 0x01:
// PP2_TYPE_AUTHORITY
case 0x02:
// PP2_TYPE_CRC32C
case 0x03:
// PP2_TYPE_NOOP
case 0x04:
// PP2_TYPE_NETNS
case 0x30:
default:
break;
}
}
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);
upgradeToConnectionFactory(_next, _connector, endPoint);
}
private void parseHeader() throws IOException {
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 parsing fixed length packet part, buffer = {}", BufferUtil.toDetailString(_buffer));
if (_buffer.remaining() < HEADER_LENGTH)
return;
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 header {} for {}", BufferUtil.toHexSummary(_buffer), this);
// struct proxy_hdr_v2 {
// uint8_t sig[12]; /* hex 0D 0A 0D 0A 00 0D 0A 51 55 49 54 0A */
// uint8_t ver_cmd; /* protocol version and command */
// uint8_t fam; /* protocol family and address */
// uint16_t len; /* number of following bytes part of the header */
// };
for (byte signatureByte : SIGNATURE) {
if (_buffer.get() != signatureByte)
throw new IOException("Proxy v2 bad PROXY signature");
}
int versionAndCommand = 0xFF & _buffer.get();
if ((versionAndCommand & 0xF0) != 0x20)
throw new IOException("Proxy v2 bad PROXY version");
_local = (versionAndCommand & 0xF) == 0x00;
int transportAndFamily = 0xFF & _buffer.get();
switch(transportAndFamily >> 4) {
case 0:
_family = Family.UNSPEC;
break;
case 1:
_family = Family.INET;
break;
case 2:
_family = Family.INET6;
break;
case 3:
_family = Family.UNIX;
break;
default:
throw new IOException("Proxy v2 bad PROXY family");
}
Transport transport;
switch(0xF & transportAndFamily) {
case 0:
transport = Transport.UNSPEC;
break;
case 1:
transport = Transport.STREAM;
break;
case 2:
transport = Transport.DGRAM;
break;
default:
throw new IOException("Proxy v2 bad PROXY family");
}
_length = _buffer.getChar();
if (!_local && (_family == Family.UNSPEC || _family == Family.UNIX || transport != Transport.STREAM))
throw new IOException(String.format("Proxy v2 unsupported PROXY mode 0x%x,0x%x", versionAndCommand, transportAndFamily));
if (_length > getMaxProxyHeader())
throw new IOException(String.format("Proxy v2 Unsupported PROXY mode 0x%x,0x%x,0x%x", versionAndCommand, transportAndFamily, _length));
if (LOG.isDebugEnabled())
LOG.debug("Proxy v2 fixed length packet part is now parsed");
_headerParsed = true;
}
private void releaseAndClose() {
_connector.getByteBufferPool().release(_buffer);
close();
}
}
}
// @deprecated The Eclipse Jetty and Apache Felix Http Jetty packages are no longer supported.
@Deprecated(since = "2021-05-27")
public static class ProxyEndPoint extends AttributesMap implements EndPoint {
private final EndPoint _endp;
private final InetSocketAddress _remote;
private final InetSocketAddress _local;
public ProxyEndPoint(EndPoint endp, InetSocketAddress remote, InetSocketAddress local) {
_endp = endp;
_remote = remote;
_local = local;
}
public EndPoint unwrap() {
return _endp;
}
@Override
public void close() {
_endp.close();
}
@Override
public int fill(ByteBuffer buffer) throws IOException {
return _endp.fill(buffer);
}
@Override
public void fillInterested(Callback callback) throws ReadPendingException {
_endp.fillInterested(callback);
}
@Override
public boolean flush(ByteBuffer... buffer) throws IOException {
return _endp.flush(buffer);
}
@Override
public Connection getConnection() {
return _endp.getConnection();
}
@Override
public void setConnection(Connection connection) {
_endp.setConnection(connection);
}
@Override
public long getCreatedTimeStamp() {
return _endp.getCreatedTimeStamp();
}
@Override
public long getIdleTimeout() {
return _endp.getIdleTimeout();
}
@Override
public void setIdleTimeout(long idleTimeout) {
_endp.setIdleTimeout(idleTimeout);
}
@Override
public InetSocketAddress getLocalAddress() {
return _local;
}
@Override
public InetSocketAddress getRemoteAddress() {
return _remote;
}
@Override
public Object getTransport() {
return _endp.getTransport();
}
@Override
public boolean isFillInterested() {
return _endp.isFillInterested();
}
@Override
public boolean isInputShutdown() {
return _endp.isInputShutdown();
}
@Override
public boolean isOpen() {
return _endp.isOpen();
}
@Override
public boolean isOptimizedForDirectBuffers() {
return _endp.isOptimizedForDirectBuffers();
}
@Override
public boolean isOutputShutdown() {
return _endp.isOutputShutdown();
}
@Override
public void onClose() {
_endp.onClose();
}
@Override
public void onOpen() {
_endp.onOpen();
}
@Override
public void shutdownOutput() {
_endp.shutdownOutput();
}
@Override
public String toString() {
return String.format("%s@%x[remote=%s,local=%s,endpoint=%s]", getClass().getSimpleName(), hashCode(), _remote, _local, _endp);
}
@Override
public boolean tryFillInterested(Callback callback) {
return _endp.tryFillInterested(callback);
}
@Override
public void upgrade(Connection newConnection) {
_endp.upgrade(newConnection);
}
@Override
public void write(Callback callback, ByteBuffer... buffers) throws WritePendingException {
_endp.write(callback, buffers);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy