From 324ba369e0aae54c02c99f1af0ec78346b4754ef Mon Sep 17 00:00:00 2001 From: Jeff Smick Date: Sun, 9 Sep 2012 08:50:31 -0700 Subject: [PATCH] Upgrade connection after completed response Channel handlers above the HttpEncoder may delay the repsonse being written to the socket. We need to wait for the response to complete before upgrading the pipeline. --- .../WebSocketClientHandshaker00.java | 10 +++++++- .../WebSocketClientHandshaker08.java | 10 +++++++- .../WebSocketClientHandshaker13.java | 10 +++++++- .../WebSocketServerHandshaker00.java | 23 ++++++++++++------- .../WebSocketServerHandshaker08.java | 19 +++++++++------ .../WebSocketServerHandshaker13.java | 19 +++++++++------ 6 files changed, 66 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketClientHandshaker00.java b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketClientHandshaker00.java index 7efcb5f5ad..9aa38a5e3f 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketClientHandshaker00.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketClientHandshaker00.java @@ -23,6 +23,8 @@ import java.util.Map; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelFutureListener; +import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.handler.codec.http.DefaultHttpRequest; import org.jboss.netty.handler.codec.http.HttpHeaders.Names; import org.jboss.netty.handler.codec.http.HttpHeaders.Values; @@ -185,7 +187,13 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker { ChannelFuture future = channel.write(request); - channel.getPipeline().replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket00FrameEncoder()); + future.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) { + ChannelPipeline p = future.getChannel().getPipeline(); + p.replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket00FrameEncoder()); + } + }); return future; } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java index 711f99ff73..cf82f19139 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java @@ -20,6 +20,8 @@ import java.util.Map; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelFutureListener; +import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.handler.codec.http.DefaultHttpRequest; import org.jboss.netty.handler.codec.http.HttpHeaders.Names; import org.jboss.netty.handler.codec.http.HttpHeaders.Values; @@ -171,7 +173,13 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker { ChannelFuture future = channel.write(request); - channel.getPipeline().replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket08FrameEncoder(true)); + future.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) { + ChannelPipeline p = future.getChannel().getPipeline(); + p.replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket08FrameEncoder(true)); + } + }); return future; } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java index 9b3e3e2c5e..a5b5669ea3 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java @@ -20,6 +20,8 @@ import java.util.Map; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelFutureListener; +import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.handler.codec.http.DefaultHttpRequest; import org.jboss.netty.handler.codec.http.HttpHeaders.Names; import org.jboss.netty.handler.codec.http.HttpHeaders.Values; @@ -167,7 +169,13 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker { ChannelFuture future = channel.write(request); - channel.getPipeline().replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket13FrameEncoder(true)); + future.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) { + ChannelPipeline p = future.getChannel().getPipeline(); + p.replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket13FrameEncoder(true)); + } + }); return future; } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00.java b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00.java index d9746ced36..f4c2dd1d2d 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00.java @@ -23,6 +23,7 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.handler.codec.http.DefaultHttpResponse; import org.jboss.netty.handler.codec.http.HttpChunkAggregator; @@ -184,17 +185,23 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker { } } - // Upgrade the connection and send the handshake response. - ChannelPipeline p = channel.getPipeline(); - if (p.get(HttpChunkAggregator.class) != null) { - p.remove(HttpChunkAggregator.class); - } - p.replace(HttpRequestDecoder.class, "wsdecoder", - new WebSocket00FrameDecoder(getMaxFramePayloadLength())); ChannelFuture future = channel.write(res); - p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket00FrameEncoder()); + // Upgrade the connection and send the handshake response. + future.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) { + ChannelPipeline p = future.getChannel().getPipeline(); + if (p.get(HttpChunkAggregator.class) != null) { + p.remove(HttpChunkAggregator.class); + } + p.replace(HttpRequestDecoder.class, "wsdecoder", + new WebSocket00FrameDecoder(getMaxFramePayloadLength())); + + p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket00FrameEncoder()); + } + }); return future; } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshaker08.java b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshaker08.java index 34acfba03e..48baa7822b 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshaker08.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshaker08.java @@ -170,14 +170,19 @@ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker { ChannelFuture future = channel.write(res); // Upgrade the connection and send the handshake response. - ChannelPipeline p = channel.getPipeline(); - if (p.get(HttpChunkAggregator.class) != null) { - p.remove(HttpChunkAggregator.class); - } + future.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) { + ChannelPipeline p = future.getChannel().getPipeline(); + if (p.get(HttpChunkAggregator.class) != null) { + p.remove(HttpChunkAggregator.class); + } - p.replace(HttpRequestDecoder.class, "wsdecoder", - new WebSocket08FrameDecoder(true, allowExtensions, getMaxFramePayloadLength())); - p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket08FrameEncoder(false)); + p.replace(HttpRequestDecoder.class, "wsdecoder", + new WebSocket08FrameDecoder(true, allowExtensions, getMaxFramePayloadLength())); + p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket08FrameEncoder(false)); + } + }); return future; } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13.java b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13.java index 78f561d8ca..a4bbc1ce08 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13.java @@ -177,14 +177,19 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker { ChannelFuture future = channel.write(res); // Upgrade the connection and send the handshake response. - ChannelPipeline p = channel.getPipeline(); - if (p.get(HttpChunkAggregator.class) != null) { - p.remove(HttpChunkAggregator.class); - } + future.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) { + ChannelPipeline p = future.getChannel().getPipeline(); + if (p.get(HttpChunkAggregator.class) != null) { + p.remove(HttpChunkAggregator.class); + } - p.replace(HttpRequestDecoder.class, "wsdecoder", - new WebSocket13FrameDecoder(true, allowExtensions, getMaxFramePayloadLength())); - p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket13FrameEncoder(false)); + p.replace(HttpRequestDecoder.class, "wsdecoder", + new WebSocket13FrameDecoder(true, allowExtensions, getMaxFramePayloadLength())); + p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket13FrameEncoder(false)); + } + }); return future; }