Fix IllegalReferenceCountException caused by HttpClientCodec.upgradeFrom()
Motivation: On a successful protocol upgrade in HTTP, HttpClientUpgradeHandler calls HttpClientCodec.upgradeFrom(), which removed both the HTTP encoder and decoder from the pipeline immediately. However, because the decoder is in the middle of the decode loop, removing it from the pipeline immediately will cause the cumulation buffer to be released prematurely. This often leads to an IllegalReferenceCountException or missing first response after the upgrade response. Modifications: - Remove the decoder *after* the decode loop is done Result: Fixes #4504
This commit is contained in:
parent
ef3a9b0acd
commit
9dd68d0c3e
@ -19,7 +19,9 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerAppender;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.handler.codec.PrematureChannelClosureException;
|
||||
import io.netty.util.internal.OneTimeTask;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.List;
|
||||
@ -92,8 +94,15 @@ public final class HttpClientCodec extends ChannelHandlerAppender implements Htt
|
||||
*/
|
||||
@Override
|
||||
public void upgradeFrom(ChannelHandlerContext ctx) {
|
||||
ctx.pipeline().remove(Decoder.class);
|
||||
ctx.pipeline().remove(Encoder.class);
|
||||
final ChannelPipeline p = ctx.pipeline();
|
||||
// Remove the decoder later so that the decoder can enter the 'UPGRADED' state and forward the remaining data.
|
||||
ctx.executor().execute(new OneTimeTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
p.remove(decoder());
|
||||
}
|
||||
});
|
||||
p.remove(encoder());
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user