2222import com .google .common .net .InetAddresses ;
2323import io .netty .channel .ChannelHandlerContext ;
2424import io .netty .channel .SimpleChannelInboundHandler ;
25+ import io .netty .handler .codec .http .FullHttpRequest ;
2526import io .netty .handler .codec .http .HttpHeaders ;
2627import io .netty .handler .codec .http .HttpRequest ;
28+ import io .netty .util .ReferenceCountUtil ;
2729import org .graylog2 .utilities .IpSubnet ;
2830import org .slf4j .Logger ;
2931import org .slf4j .LoggerFactory ;
3941import java .util .Set ;
4042import java .util .stream .Collectors ;
4143
42- public class HttpForwardedForHandler extends SimpleChannelInboundHandler <HttpRequest > {
44+ public class HttpForwardedForHandler extends SimpleChannelInboundHandler <FullHttpRequest > {
4345 private static final Logger LOG = LoggerFactory .getLogger (HttpForwardedForHandler .class );
4446
4547 // Splits comma-separated forwarded-elements
@@ -81,7 +83,7 @@ public HttpForwardedForHandler(boolean enableForwardedFor, boolean enableRealIpH
8183 }
8284
8385 @ Override
84- protected void channelRead0 (ChannelHandlerContext ctx , HttpRequest msg ) throws Exception {
86+ protected void channelRead0 (ChannelHandlerContext ctx , FullHttpRequest msg ) throws Exception {
8587 String originalIp = null ;
8688
8789 // if we choose to trust X-Forwarded-For or Forwarded headers
@@ -149,10 +151,16 @@ protected void channelRead0(ChannelHandlerContext ctx, HttpRequest msg) throws E
149151 if (!InetAddresses .isInetAddress (originalIp )) {
150152 LOG .warn ("Ignoring non-literal IP value for original IP address: {}" , originalIp );
151153 }
152- final InetAddress inetAddress = InetAddresses .forString (originalIp );
153- ctx .channel ().attr (RawMessageHandler .ORIGINAL_IP_KEY ).setIfAbsent (new InetSocketAddress (inetAddress , 0 ));
154+ try {
155+ final InetAddress inetAddress = InetAddresses .forString (originalIp );
156+ ctx .channel ().attr (RawMessageHandler .ORIGINAL_IP_KEY ).setIfAbsent (new InetSocketAddress (inetAddress , 0 ));
157+ } catch (IllegalArgumentException e ) {
158+ LOG .warn ("The address extracted for forwarded IP address is not a valid IP literal: {}" , originalIp );
159+ }
154160 }
155- ctx .fireChannelRead (msg );
161+ // our http channel handlers are using FullHttpMessage instances, so we need to retain them, even though we are
162+ // only using header values here (otherwise we'll get ref count exceptions upstream)
163+ ctx .fireChannelRead (msg .retain ());
156164 }
157165
158166 private Optional <String > findOriginalIpAndCheckProxies (List <String > ipChain ) throws UnknownHostException {
@@ -164,6 +172,9 @@ private Optional<String> findOriginalIpAndCheckProxies(List<String> ipChain) thr
164172 LOG .debug ("Ignoring invalid X-Forwarded-For header, list of proxies is empty" );
165173 return Optional .empty ();
166174 } else {
175+ if (!iterator .hasNext ()) {
176+ LOG .debug ("Forwarded-For list only contains a single entry, cannot check relaying proxy addresses." );
177+ }
167178 // go through the remainder of the list, which should all be proxy addresses we trust
168179 // if we hit one that we don't trust, bail out and don't use the candidate IP
169180 while (iterator .hasNext ()) {
0 commit comments