use of io.netty.handler.codec.haproxy.HAProxyMessage in project zuul by Netflix.
the class ClientRequestReceiver method channelReadInternal.
private void channelReadInternal(final ChannelHandlerContext ctx, Object msg) throws Exception {
// a response to the client channel.
if (msg instanceof LastHttpContent) {
ctx.channel().attr(ATTR_LAST_CONTENT_RECEIVED).set(Boolean.TRUE);
}
if (msg instanceof HttpRequest) {
clientRequest = (HttpRequest) msg;
zuulRequest = buildZuulHttpRequest(clientRequest, ctx);
// Handle invalid HTTP requests.
if (clientRequest.decoderResult().isFailure()) {
LOG.warn("Invalid http request. clientRequest = {} , uri = {}, info = {}", clientRequest, clientRequest.uri(), ChannelUtils.channelInfoForLogging(ctx.channel()), clientRequest.decoderResult().cause());
StatusCategoryUtils.setStatusCategory(zuulRequest.getContext(), ZuulStatusCategory.FAILURE_CLIENT_BAD_REQUEST);
RejectionUtils.rejectByClosingConnection(ctx, ZuulStatusCategory.FAILURE_CLIENT_BAD_REQUEST, "decodefailure", clientRequest, /* injectedLatencyMillis= */
null);
return;
} else if (zuulRequest.hasBody() && zuulRequest.getBodyLength() > zuulRequest.getMaxBodySize()) {
String errorMsg = "Request too large. " + "clientRequest = " + clientRequest.toString() + ", uri = " + String.valueOf(clientRequest.uri()) + ", info = " + ChannelUtils.channelInfoForLogging(ctx.channel());
final ZuulException ze = new ZuulException(errorMsg);
ze.setStatusCode(HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE.code());
StatusCategoryUtils.setStatusCategory(zuulRequest.getContext(), ZuulStatusCategory.FAILURE_CLIENT_BAD_REQUEST);
zuulRequest.getContext().setError(ze);
zuulRequest.getContext().setShouldSendErrorResponse(true);
} else if (zuulRequest.getHeaders().getAll(HttpHeaderNames.HOST.toString()).size() > 1) {
LOG.debug("Multiple Host headers. clientRequest = {} , uri = {}, info = {}", clientRequest, clientRequest.uri(), ChannelUtils.channelInfoForLogging(ctx.channel()));
final ZuulException ze = new ZuulException("Multiple Host headers");
ze.setStatusCode(HttpResponseStatus.BAD_REQUEST.code());
StatusCategoryUtils.setStatusCategory(zuulRequest.getContext(), ZuulStatusCategory.FAILURE_CLIENT_BAD_REQUEST);
zuulRequest.getContext().setError(ze);
zuulRequest.getContext().setShouldSendErrorResponse(true);
}
handleExpect100Continue(ctx, clientRequest);
// Send the request down the filter pipeline
ctx.fireChannelRead(zuulRequest);
} else if (msg instanceof HttpContent) {
if ((zuulRequest != null) && (!zuulRequest.getContext().isCancelled())) {
ctx.fireChannelRead(msg);
} else {
// We already sent response for this request, these are laggard request body chunks that are still arriving
ReferenceCountUtil.release(msg);
}
} else if (msg instanceof HAProxyMessage) {
// do nothing, should already be handled by ElbProxyProtocolHandler
LOG.debug("Received HAProxyMessage for Proxy Protocol IP: {}", ((HAProxyMessage) msg).sourceAddress());
ReferenceCountUtil.release(msg);
} else {
LOG.debug("Received unrecognized message type. " + msg.getClass().getName());
ReferenceCountUtil.release(msg);
}
}
use of io.netty.handler.codec.haproxy.HAProxyMessage in project zuul by Netflix.
the class HAProxyMessageChannelHandler method channelRead.
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof HAProxyMessage) {
HAProxyMessage hapm = (HAProxyMessage) msg;
Channel channel = ctx.channel();
channel.attr(ATTR_HAPROXY_MESSAGE).set(hapm);
ctx.channel().closeFuture().addListener((ChannelFutureListener) future -> hapm.release());
channel.attr(ATTR_HAPROXY_VERSION).set(hapm.protocolVersion());
// Get the real host and port that the client connected to ELB with.
String destinationAddress = hapm.destinationAddress();
if (destinationAddress != null) {
channel.attr(SourceAddressChannelHandler.ATTR_LOCAL_ADDRESS).set(destinationAddress);
SocketAddress addr;
out: {
switch(hapm.proxiedProtocol()) {
case UNKNOWN:
throw new IllegalArgumentException("unknown proxy protocl" + destinationAddress);
case TCP4:
case TCP6:
InetSocketAddress inetAddr = new InetSocketAddress(InetAddresses.forString(destinationAddress), hapm.destinationPort());
addr = inetAddr;
// setting PPv2 explicitly because SourceAddressChannelHandler.ATTR_LOCAL_ADDR could be PPv2 or not
channel.attr(SourceAddressChannelHandler.ATTR_PROXY_PROTOCOL_DESTINATION_ADDRESS).set(inetAddr);
Attrs attrs = ctx.channel().attr(Server.CONN_DIMENSIONS).get();
if (inetAddr.getAddress() instanceof Inet4Address) {
HAPM_DEST_IP_VERSION.put(attrs, "v4");
} else if (inetAddr.getAddress() instanceof Inet6Address) {
HAPM_DEST_IP_VERSION.put(attrs, "v6");
} else {
HAPM_DEST_IP_VERSION.put(attrs, "unknown");
}
HAPM_DEST_PORT.put(attrs, hapm.destinationPort());
break out;
// TODO: implement
case UNIX_STREAM:
case UDP4:
case UDP6:
case UNIX_DGRAM:
throw new IllegalArgumentException("unknown proxy protocol" + destinationAddress);
}
throw new AssertionError(hapm.proxiedProtocol());
}
channel.attr(SourceAddressChannelHandler.ATTR_LOCAL_ADDR).set(addr);
}
// Get the real client IP from the ProxyProtocol message sent by the ELB, and overwrite the SourceAddress
// channel attribute.
String sourceAddress = hapm.sourceAddress();
if (sourceAddress != null) {
channel.attr(SourceAddressChannelHandler.ATTR_SOURCE_ADDRESS).set(sourceAddress);
SocketAddress addr;
out: {
switch(hapm.proxiedProtocol()) {
case UNKNOWN:
throw new IllegalArgumentException("unknown proxy protocl" + sourceAddress);
case TCP4:
case TCP6:
InetSocketAddress inetAddr;
addr = inetAddr = new InetSocketAddress(InetAddresses.forString(sourceAddress), hapm.sourcePort());
Attrs attrs = ctx.channel().attr(Server.CONN_DIMENSIONS).get();
if (inetAddr.getAddress() instanceof Inet4Address) {
HAPM_SRC_IP_VERSION.put(attrs, "v4");
} else if (inetAddr.getAddress() instanceof Inet6Address) {
HAPM_SRC_IP_VERSION.put(attrs, "v6");
} else {
HAPM_SRC_IP_VERSION.put(attrs, "unknown");
}
break out;
// TODO: implement
case UNIX_STREAM:
case UDP4:
case UDP6:
case UNIX_DGRAM:
throw new IllegalArgumentException("unknown proxy protocol" + sourceAddress);
}
throw new AssertionError(hapm.proxiedProtocol());
}
channel.attr(SourceAddressChannelHandler.ATTR_REMOTE_ADDR).set(addr);
}
// TODO - fire an additional event to notify interested parties that we now know the IP?
// Remove ourselves (this handler) from the channel now, as no more work to do.
ctx.pipeline().remove(this);
// Do not continue propagating the message.
return;
}
}
use of io.netty.handler.codec.haproxy.HAProxyMessage in project netty by netty.
the class HAProxyClient method main.
public static void main(String[] args) throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class).handler(new HAProxyHandler());
// Start the connection attempt.
Channel ch = b.connect(HOST, PORT).sync().channel();
HAProxyMessage message = new HAProxyMessage(HAProxyProtocolVersion.V2, HAProxyCommand.PROXY, HAProxyProxiedProtocol.TCP4, "127.0.0.1", "127.0.0.2", 8000, 9000);
ch.writeAndFlush(message).sync();
ch.writeAndFlush(Unpooled.copiedBuffer("Hello World!", CharsetUtil.US_ASCII)).sync();
ch.writeAndFlush(Unpooled.copiedBuffer("Bye now!", CharsetUtil.US_ASCII)).sync();
ch.close().sync();
} finally {
group.shutdownGracefully();
}
}
use of io.netty.handler.codec.haproxy.HAProxyMessage in project zuul by Netflix.
the class ElbProxyProtocolChannelHandlerTest method detectsSplitPpv1Message.
@Ignore
@Test
public void detectsSplitPpv1Message() {
EmbeddedChannel channel = new EmbeddedChannel();
// This is normally done by Server.
channel.attr(Server.CONN_DIMENSIONS).set(Attrs.newInstance());
channel.pipeline().addLast(ElbProxyProtocolChannelHandler.NAME, new ElbProxyProtocolChannelHandler(registry, true));
ByteBuf buf1 = Unpooled.wrappedBuffer("PROXY TCP4".getBytes(StandardCharsets.US_ASCII));
channel.writeInbound(buf1);
ByteBuf buf2 = Unpooled.wrappedBuffer("192.168.0.1 124.123.111.111 10008 443\r\n".getBytes(StandardCharsets.US_ASCII));
channel.writeInbound(buf2);
Object msg = channel.readInbound();
assertTrue(msg instanceof HAProxyMessage);
buf1.release();
buf2.release();
((HAProxyMessage) msg).release();
// The handler should remove itself.
assertNull(channel.pipeline().context(ElbProxyProtocolChannelHandler.class));
}
use of io.netty.handler.codec.haproxy.HAProxyMessage in project reactor-netty by reactor.
the class HAProxyMessageReader method channelRead.
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof HAProxyMessage) {
HAProxyMessage proxyMessage = (HAProxyMessage) msg;
if (proxyMessage.sourceAddress() != null && proxyMessage.sourcePort() != 0) {
InetSocketAddress remoteAddress = AddressUtils.createUnresolved(proxyMessage.sourceAddress(), proxyMessage.sourcePort());
ctx.channel().attr(REMOTE_ADDRESS_FROM_PROXY_PROTOCOL).set(remoteAddress);
}
proxyMessage.release();
ctx.channel().pipeline().remove(this);
ctx.read();
} else {
super.channelRead(ctx, msg);
}
}
Aggregations