package io.nodyn.http.server;

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.LastHttpContent;
import io.nodyn.CallbackResult;
import io.nodyn.net.AbstractServerHandler;
import io.nodyn.net.NetServerWrap;
import io.nodyn.net.SocketWrap;


/**
 * @author Bob McWhirter
 */
public class KeepAliveHandler extends AbstractServerHandler {

    boolean keepAlive = true;

    public KeepAliveHandler(NetServerWrap server) {
        super(server);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if ( msg instanceof HttpRequest ) {
            String connectionHeader = ((HttpRequest) msg).headers().get( HttpHeaders.Names.CONNECTION );
            if ( connectionHeader != null ) {
                if ( "close".equals( connectionHeader ) ) {
                    this.keepAlive = false;
                }
            }
        }
        super.channelRead(ctx, msg);
    }

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        if ( msg instanceof LastHttpContent ) {
            if ( this.keepAlive ) {
                promise.addListener( new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture future) throws Exception {
                        future.channel().pipeline().remove( "discard" );
                        future.channel().pipeline().remove( "trailers" );
                        future.channel().pipeline().remove( "incoming.data" );
                        future.channel().config().setAutoRead(true);
                    }
                });
            } else {
                promise.addListener( ChannelFutureListener.CLOSE );
            }
        }
        super.write(ctx, msg, promise);
    }
}

@@ -52,155 +52,9 @@
 nel.
-ChannelFuture;%0Aimport io.netty.channel.ChannelFutureListener;%0Aimport io.netty.channel.ChannelHandlerContext;%0Aimport io.netty.channel.ChannelPromise
+*
 ;%0Aim
@@ -1455,44 +1455,167 @@
     
-future.channel().pipeline().remove( 
+ChannelPipeline pipeline = future.channel().pipeline();%0A                        ChannelHandler handler = null;%0A%0A                        handler = pipeline.get(
 %22dis
@@ -1619,17 +1619,16 @@
 discard%22
- 
 );%0A     
@@ -1650,33 +1650,69 @@
     
-future.channel().
+if ( handler != null ) %7B%0A                            
 pipeline
 ().r
@@ -1699,34 +1699,32 @@
         pipeline
-()
 .remove( %22traile
@@ -1720,71 +1720,193 @@
 ve( 
-%22trailers%22 );%0A                        future.channel().
+handler );%0A                        %7D%0A%0A                        handler = pipeline.get( %22trailers%22 );%0A                        if ( handler != null ) %7B%0A                            
 pipeline
 ().r
@@ -1901,18 +1901,16 @@
 pipeline
-()
 .remove(
@@ -1914,26 +1914,244 @@
 ve( 
-%22incoming.data%22 );
+handler );%0A                        %7D%0A%0A                        handler = pipeline.get( %22incoming.data%22 );%0A                        if ( handler != null ) %7B%0A                            pipeline.remove( handler );%0A                        %7D%0A
 %0A   

Make keep-alive handler more robus to reconfiguring the pipeline.