Correctly release buffers on protocol errors

Motivation:

We failed to release buffers on protocolErrors which caused buffer leaks when using HTTP/2

Modifications:

Release buffer on protocol errors

Result:

No more buffer leaks
This commit is contained in:
Norman Maurer 2014-08-30 20:53:07 +02:00
parent ce8230f455
commit cc55a71b14

View File

@ -348,6 +348,7 @@ public abstract class AbstractHttp2ConnectionHandler extends ByteToMessageDecode
*/ */
public ChannelFuture writeData(final ChannelHandlerContext ctx, final int streamId, final ByteBuf data, public ChannelFuture writeData(final ChannelHandlerContext ctx, final int streamId, final ByteBuf data,
int padding, final boolean endStream, ChannelPromise promise) { int padding, final boolean endStream, ChannelPromise promise) {
boolean release = true;
try { try {
if (connection.isGoAway()) { if (connection.isGoAway()) {
throw protocolError("Sending data after connection going away."); throw protocolError("Sending data after connection going away.");
@ -358,6 +359,7 @@ public abstract class AbstractHttp2ConnectionHandler extends ByteToMessageDecode
// Hand control of the frame to the flow controller. // Hand control of the frame to the flow controller.
ChannelFuture future = outboundFlow.writeData(ctx, streamId, data, padding, endStream, promise); ChannelFuture future = outboundFlow.writeData(ctx, streamId, data, padding, endStream, promise);
release = false;
future.addListener(new ChannelFutureListener() { future.addListener(new ChannelFutureListener() {
@Override @Override
public void operationComplete(ChannelFuture future) throws Exception { public void operationComplete(ChannelFuture future) throws Exception {
@ -374,8 +376,10 @@ public abstract class AbstractHttp2ConnectionHandler extends ByteToMessageDecode
return future; return future;
} catch (Http2Exception e) { } catch (Http2Exception e) {
promise.setFailure(e); if (release) {
return promise; data.release();
}
return promise.setFailure(e);
} }
} }
@ -506,6 +510,7 @@ public abstract class AbstractHttp2ConnectionHandler extends ByteToMessageDecode
* Writes (and flushes) the given {@code PING} frame to the remote endpoint. * Writes (and flushes) the given {@code PING} frame to the remote endpoint.
*/ */
public ChannelFuture writePing(ChannelHandlerContext ctx, ByteBuf data, ChannelPromise promise) { public ChannelFuture writePing(ChannelHandlerContext ctx, ByteBuf data, ChannelPromise promise) {
boolean release = true;
try { try {
if (connection.isGoAway()) { if (connection.isGoAway()) {
throw protocolError("Sending ping after connection going away."); throw protocolError("Sending ping after connection going away.");
@ -513,9 +518,13 @@ public abstract class AbstractHttp2ConnectionHandler extends ByteToMessageDecode
// Just pass the frame through. // Just pass the frame through.
frameWriter.writePing(ctx, false, data, promise); frameWriter.writePing(ctx, false, data, promise);
release = false;
ctx.flush(); ctx.flush();
return promise; return promise;
} catch (Http2Exception e) { } catch (Http2Exception e) {
if (release) {
data.release();
}
return promise.setFailure(e); return promise.setFailure(e);
} }
} }