package org.projectodd.restafari.container.protocols.websocket;

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
import io.netty.util.ReferenceCountUtil;
import org.projectodd.restafari.container.protocols.PipelineConfigurator;

/**
 * @author Bob McWhirter
 */
public class WebSocketHandshakerHandler extends SimpleChannelInboundHandler<Object> {

    private static final String WEBSOCKETS_PREFIX = "/_websockets";

    public WebSocketHandshakerHandler(PipelineConfigurator configurator) {
        this.configurator = configurator;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {

        FullHttpRequest req = (FullHttpRequest) msg;

        if (req.getUri().startsWith(WEBSOCKETS_PREFIX)) {
            WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(WEBSOCKETS_PREFIX, null, false);
            WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req);
            if (handshaker == null) {
                WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel());
            } else {
                ChannelFuture future = handshaker.handshake(ctx.channel(), req);
                future.addListener(f -> {
                    this.configurator.switchToWebSockets(ctx.pipeline());
                });
            }
        } else {
            ReferenceCountUtil.retain( msg );
            this.configurator.switchToPlainHttp(ctx.pipeline());
            ChannelHandlerContext agg = ctx.pipeline().context(HttpObjectAggregator.class);
            agg.fireChannelRead( msg );
        }
    }

    private PipelineConfigurator configurator;
}

@@ -249,16 +249,64 @@
 equest;%0A
+import io.netty.handler.codec.http.HttpHeaders;%0A
 import i
@@ -354,16 +354,16 @@
 egator;%0A
-
 import i
@@ -790,20 +790,19 @@
 ETS_
-PREFIX
+UPGRADE
  = %22
-/_
 webs
@@ -806,17 +806,16 @@
 ebsocket
-s
 %22;%0A%0A    
@@ -1092,25 +1092,24 @@
 t) msg;%0A
-%0A
         
 if (req.
@@ -1104,53 +1104,116 @@
     
-if (req.getUri().startsWith(WEBSOCKETS_PREFIX
+String upgrade = req.headers().get(HttpHeaders.Names.UPGRADE);%0A        if (WEBSOCKETS_UPGRADE.equals(upgrade
 )) %7B
@@ -1311,25 +1311,20 @@
 ory(
-WEBSOCKETS_PREFIX
+req.getUri()
 , nu

Use 'Upgrade' header instead of requiring /_websockets to be part of the path.