More robust pipeline manipulation while upgrading to WebSocket
- This commit allows a user to write its first web socket frame right after calling WebSocketServerHandshaker.handshake() rather than adding a listener to the future it returns. - Should fix #1933
This commit is contained in:
parent
3a01bf1064
commit
3367e51882
@ -159,33 +159,38 @@ public abstract class WebSocketServerHandshaker {
|
||||
logger.debug(String.format("%s WS Version %s server handshake", channel, version()));
|
||||
}
|
||||
FullHttpResponse response = newHandshakeResponse(req, responseHeaders);
|
||||
ChannelPipeline p = channel.pipeline();
|
||||
if (p.get(HttpObjectAggregator.class) != null) {
|
||||
p.remove(HttpObjectAggregator.class);
|
||||
}
|
||||
if (p.get(HttpContentCompressor.class) != null) {
|
||||
p.remove(HttpContentCompressor.class);
|
||||
}
|
||||
ChannelHandlerContext ctx = p.context(HttpRequestDecoder.class);
|
||||
final String encoderName;
|
||||
if (ctx == null) {
|
||||
// this means the user use a HttpServerCodec
|
||||
ctx = p.context(HttpServerCodec.class);
|
||||
if (ctx == null) {
|
||||
promise.setFailure(
|
||||
new IllegalStateException("No HttpDecoder and no HttpServerCodec in the pipeline"));
|
||||
return promise;
|
||||
}
|
||||
p.addBefore(ctx.name(), "wsdecoder", newWebsocketDecoder());
|
||||
p.addBefore(ctx.name(), "wsencoder", newWebSocketEncoder());
|
||||
encoderName = ctx.name();
|
||||
} else {
|
||||
p.replace(ctx.name(), "wsdecoder", newWebsocketDecoder());
|
||||
|
||||
encoderName = p.context(HttpResponseEncoder.class).name();
|
||||
p.addAfter(encoderName, "wsencoder", newWebSocketEncoder());
|
||||
}
|
||||
channel.writeAndFlush(response).addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
if (future.isSuccess()) {
|
||||
ChannelPipeline p = future.channel().pipeline();
|
||||
if (p.get(HttpObjectAggregator.class) != null) {
|
||||
p.remove(HttpObjectAggregator.class);
|
||||
}
|
||||
if (p.get(HttpContentCompressor.class) != null) {
|
||||
p.remove(HttpContentCompressor.class);
|
||||
}
|
||||
ChannelHandlerContext ctx = p.context(HttpRequestDecoder.class);
|
||||
if (ctx == null) {
|
||||
// this means the user use a HttpServerCodec
|
||||
ctx = p.context(HttpServerCodec.class);
|
||||
if (ctx == null) {
|
||||
promise.setFailure(
|
||||
new IllegalStateException("No HttpDecoder and no HttpServerCodec in the pipeline"));
|
||||
return;
|
||||
}
|
||||
p.addBefore(ctx.name(), "wsdecoder", newWebsocketDecoder());
|
||||
p.replace(ctx.name(), "wsencoder", newWebSocketEncoder());
|
||||
} else {
|
||||
p.replace(ctx.name(), "wsdecoder", newWebsocketDecoder());
|
||||
|
||||
p.replace(HttpResponseEncoder.class, "wsencoder", newWebSocketEncoder());
|
||||
}
|
||||
p.remove(encoderName);
|
||||
promise.setSuccess();
|
||||
} else {
|
||||
promise.setFailure(future.cause());
|
||||
|
Loading…
Reference in New Issue
Block a user