Use long for http2 ping payload.
Motivation: At the moment we use a ByteBuf as the payload for a http2 frame. This complicates life-time management a lot with no real gain and also may produce more objects then needed. We should just use a long as it is required to be 8 bytes anyway. Modifications: Use long for ping payloads. Result: Fixes [#7629].
This commit is contained in:
parent
40ae4fefc7
commit
501662a77f
@ -76,7 +76,7 @@ public class DecoratingHttp2FrameWriter implements Http2FrameWriter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture writePing(ChannelHandlerContext ctx, boolean ack, ByteBuf data, ChannelPromise promise) {
|
||||
public ChannelFuture writePing(ChannelHandlerContext ctx, boolean ack, long data, ChannelPromise promise) {
|
||||
return delegate.writePing(ctx, ack, data, promise);
|
||||
}
|
||||
|
||||
|
@ -424,16 +424,16 @@ public class DefaultHttp2ConnectionDecoder implements Http2ConnectionDecoder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||
public void onPingRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
||||
// Send an ack back to the remote client.
|
||||
// Need to retain the buffer here since it will be released after the write completes.
|
||||
encoder.writePing(ctx, true, data.retainedSlice(), ctx.newPromise());
|
||||
encoder.writePing(ctx, true, data, ctx.newPromise());
|
||||
|
||||
listener.onPingRead(ctx, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
||||
listener.onPingAckRead(ctx, data);
|
||||
}
|
||||
|
||||
@ -636,13 +636,13 @@ public class DefaultHttp2ConnectionDecoder implements Http2ConnectionDecoder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||
public void onPingRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
||||
verifyPrefaceReceived();
|
||||
internalFrameListener.onPingRead(ctx, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
||||
verifyPrefaceReceived();
|
||||
internalFrameListener.onPingAckRead(ctx, data);
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture writePing(ChannelHandlerContext ctx, boolean ack, ByteBuf data, ChannelPromise promise) {
|
||||
public ChannelFuture writePing(ChannelHandlerContext ctx, boolean ack, long data, ChannelPromise promise) {
|
||||
return frameWriter.writePing(ctx, ack, data, promise);
|
||||
}
|
||||
|
||||
|
@ -266,7 +266,7 @@ public class DefaultHttp2FrameReader implements Http2FrameReader, Http2FrameSize
|
||||
readPushPromiseFrame(ctx, payload, listener);
|
||||
break;
|
||||
case PING:
|
||||
readPingFrame(ctx, payload, listener);
|
||||
readPingFrame(ctx, payload.readLong(), listener);
|
||||
break;
|
||||
case GO_AWAY:
|
||||
readGoAwayFrame(ctx, payload, listener);
|
||||
@ -574,9 +574,8 @@ public class DefaultHttp2FrameReader implements Http2FrameReader, Http2FrameSize
|
||||
resetHeadersContinuationIfEnd(flags.endOfHeaders());
|
||||
}
|
||||
|
||||
private void readPingFrame(ChannelHandlerContext ctx, ByteBuf payload,
|
||||
private void readPingFrame(ChannelHandlerContext ctx, long data,
|
||||
Http2FrameListener listener) throws Http2Exception {
|
||||
ByteBuf data = payload.readSlice(payload.readableBytes());
|
||||
if (flags.ack()) {
|
||||
listener.onPingAckRead(ctx, data);
|
||||
} else {
|
||||
|
@ -332,36 +332,14 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture writePing(ChannelHandlerContext ctx, boolean ack, ByteBuf data, ChannelPromise promise) {
|
||||
final SimpleChannelPromiseAggregator promiseAggregator =
|
||||
new SimpleChannelPromiseAggregator(promise, ctx.channel(), ctx.executor());
|
||||
try {
|
||||
verifyPingPayload(data);
|
||||
public ChannelFuture writePing(ChannelHandlerContext ctx, boolean ack, long data, ChannelPromise promise) {
|
||||
Http2Flags flags = ack ? new Http2Flags().ack(true) : new Http2Flags();
|
||||
int payloadLength = data.readableBytes();
|
||||
ByteBuf buf = ctx.alloc().buffer(FRAME_HEADER_LENGTH);
|
||||
ByteBuf buf = ctx.alloc().buffer(FRAME_HEADER_LENGTH + PING_FRAME_PAYLOAD_LENGTH);
|
||||
// Assume nothing below will throw until buf is written. That way we don't have to take care of ownership
|
||||
// in the catch block.
|
||||
writeFrameHeaderInternal(buf, payloadLength, PING, flags, 0);
|
||||
ctx.write(buf, promiseAggregator.newPromise());
|
||||
} catch (Throwable t) {
|
||||
try {
|
||||
data.release();
|
||||
} finally {
|
||||
promiseAggregator.setFailure(t);
|
||||
promiseAggregator.doneAllocatingPromises();
|
||||
}
|
||||
return promiseAggregator;
|
||||
}
|
||||
|
||||
try {
|
||||
// Write the debug data.
|
||||
ctx.write(data, promiseAggregator.newPromise());
|
||||
} catch (Throwable t) {
|
||||
promiseAggregator.setFailure(t);
|
||||
}
|
||||
|
||||
return promiseAggregator.doneAllocatingPromises();
|
||||
writeFrameHeaderInternal(buf, PING_FRAME_PAYLOAD_LENGTH, PING, flags, 0);
|
||||
buf.writeLong(data);
|
||||
return ctx.write(buf, promise);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
package io.netty.handler.codec.http2;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.DefaultByteBufHolder;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import io.netty.util.internal.UnstableApi;
|
||||
|
||||
@ -25,19 +23,20 @@ import io.netty.util.internal.UnstableApi;
|
||||
* The default {@link Http2PingFrame} implementation.
|
||||
*/
|
||||
@UnstableApi
|
||||
public class DefaultHttp2PingFrame extends DefaultByteBufHolder implements Http2PingFrame {
|
||||
public class DefaultHttp2PingFrame implements Http2PingFrame {
|
||||
|
||||
private final long content;
|
||||
private final boolean ack;
|
||||
|
||||
public DefaultHttp2PingFrame(ByteBuf content) {
|
||||
public DefaultHttp2PingFrame(long content) {
|
||||
this(content, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* A user cannot send a ping ack, as this is done automatically when a ping is received.
|
||||
*/
|
||||
DefaultHttp2PingFrame(ByteBuf content, boolean ack) {
|
||||
super(mustBeEightBytes(content));
|
||||
DefaultHttp2PingFrame(long content, boolean ack) {
|
||||
this.content = content;
|
||||
this.ack = ack;
|
||||
}
|
||||
|
||||
@ -52,47 +51,8 @@ public class DefaultHttp2PingFrame extends DefaultByteBufHolder implements Http2
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttp2PingFrame copy() {
|
||||
return replace(content().copy());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttp2PingFrame duplicate() {
|
||||
return replace(content().duplicate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttp2PingFrame retainedDuplicate() {
|
||||
return replace(content().retainedDuplicate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttp2PingFrame replace(ByteBuf content) {
|
||||
return new DefaultHttp2PingFrame(content, ack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttp2PingFrame retain() {
|
||||
super.retain();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttp2PingFrame retain(int increment) {
|
||||
super.retain(increment);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttp2PingFrame touch() {
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttp2PingFrame touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
public long content() {
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -101,7 +61,7 @@ public class DefaultHttp2PingFrame extends DefaultByteBufHolder implements Http2
|
||||
return false;
|
||||
}
|
||||
Http2PingFrame other = (Http2PingFrame) o;
|
||||
return super.equals(o) && ack == other.ack();
|
||||
return ack == other.ack() && content == other.content();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -111,16 +71,8 @@ public class DefaultHttp2PingFrame extends DefaultByteBufHolder implements Http2
|
||||
return hash;
|
||||
}
|
||||
|
||||
private static ByteBuf mustBeEightBytes(ByteBuf content) {
|
||||
if (content.readableBytes() != 8) {
|
||||
throw new IllegalArgumentException("PING frames require 8 bytes of content. Was " +
|
||||
content.readableBytes() + " bytes.");
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringUtil.simpleClassName(this) + "(content=" + contentToString() + ", ack=" + ack + ')';
|
||||
return StringUtil.simpleClassName(this) + "(content=" + content + ", ack=" + ack + ')';
|
||||
}
|
||||
}
|
||||
|
@ -58,11 +58,11 @@ public class Http2EventAdapter implements Http2Connection.Listener, Http2FrameLi
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||
public void onPingRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -61,11 +61,11 @@ public class Http2FrameAdapter implements Http2FrameListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||
public void onPingRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -499,13 +499,13 @@ public class Http2FrameCodec extends Http2ConnectionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) {
|
||||
onHttp2Frame(ctx, new DefaultHttp2PingFrame(data, false).retain());
|
||||
public void onPingRead(ChannelHandlerContext ctx, long data) {
|
||||
onHttp2Frame(ctx, new DefaultHttp2PingFrame(data, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) {
|
||||
onHttp2Frame(ctx, new DefaultHttp2PingFrame(data, true).retain());
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, long data) {
|
||||
onHttp2Frame(ctx, new DefaultHttp2PingFrame(data, true));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -144,19 +144,17 @@ public interface Http2FrameListener {
|
||||
* Handles an inbound {@code PING} frame.
|
||||
*
|
||||
* @param ctx the context from the handler where the frame was read.
|
||||
* @param data the payload of the frame. If this buffer needs to be retained by the listener
|
||||
* they must make a copy.
|
||||
* @param data the payload of the frame.
|
||||
*/
|
||||
void onPingRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception;
|
||||
void onPingRead(ChannelHandlerContext ctx, long data) throws Http2Exception;
|
||||
|
||||
/**
|
||||
* Handles an inbound {@code PING} acknowledgment.
|
||||
*
|
||||
* @param ctx the context from the handler where the frame was read.
|
||||
* @param data the payload of the frame. If this buffer needs to be retained by the listener
|
||||
* they must make a copy.
|
||||
* @param data the payload of the frame.
|
||||
*/
|
||||
void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception;
|
||||
void onPingAckRead(ChannelHandlerContext ctx, long data) throws Http2Exception;
|
||||
|
||||
/**
|
||||
* Handles an inbound {@code PUSH_PROMISE} frame. Only called if {@code END_HEADERS} encountered.
|
||||
|
@ -70,12 +70,12 @@ public class Http2FrameListenerDecorator implements Http2FrameListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||
public void onPingRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
||||
listener.onPingRead(ctx, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
||||
listener.onPingAckRead(ctx, data);
|
||||
}
|
||||
|
||||
|
@ -98,14 +98,14 @@ public class Http2FrameLogger extends ChannelHandlerAdapter {
|
||||
logger.log(level, "{} {} SETTINGS: ack=false settings={}", ctx.channel(), direction.name(), settings);
|
||||
}
|
||||
|
||||
public void logPing(Direction direction, ChannelHandlerContext ctx, ByteBuf data) {
|
||||
logger.log(level, "{} {} PING: ack=false length={} bytes={}", ctx.channel(),
|
||||
direction.name(), data.readableBytes(), toString(data));
|
||||
public void logPing(Direction direction, ChannelHandlerContext ctx, long data) {
|
||||
logger.log(level, "{} {} PING: ack=false bytes={}", ctx.channel(),
|
||||
direction.name(), data);
|
||||
}
|
||||
|
||||
public void logPingAck(Direction direction, ChannelHandlerContext ctx, ByteBuf data) {
|
||||
logger.log(level, "{} {} PING: ack=true length={} bytes={}", ctx.channel(),
|
||||
direction.name(), data.readableBytes(), toString(data));
|
||||
public void logPingAck(Direction direction, ChannelHandlerContext ctx, long data) {
|
||||
logger.log(level, "{} {} PING: ack=true bytes={}", ctx.channel(),
|
||||
direction.name(), data);
|
||||
}
|
||||
|
||||
public void logPushPromise(Direction direction, ChannelHandlerContext ctx, int streamId, int promisedStreamId,
|
||||
|
@ -147,11 +147,11 @@ public interface Http2FrameWriter extends Http2DataWriter, Closeable {
|
||||
* @param ctx the context to use for writing.
|
||||
* @param ack indicates whether this is an ack of a PING frame previously received from the
|
||||
* remote endpoint.
|
||||
* @param data the payload of the frame. This will be released by this method.
|
||||
* @param data the payload of the frame.
|
||||
* @param promise the promise for the write.
|
||||
* @return the future for the write.
|
||||
*/
|
||||
ChannelFuture writePing(ChannelHandlerContext ctx, boolean ack, ByteBuf data,
|
||||
ChannelFuture writePing(ChannelHandlerContext ctx, boolean ack, long data,
|
||||
ChannelPromise promise);
|
||||
|
||||
/**
|
||||
|
@ -94,13 +94,13 @@ public class Http2InboundFrameLogger implements Http2FrameReader {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||
public void onPingRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
||||
logger.logPing(INBOUND, ctx, data);
|
||||
listener.onPingRead(ctx, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
||||
logger.logPingAck(INBOUND, ctx, data);
|
||||
listener.onPingAckRead(ctx, data);
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ public class Http2OutboundFrameLogger implements Http2FrameWriter {
|
||||
|
||||
@Override
|
||||
public ChannelFuture writePing(ChannelHandlerContext ctx, boolean ack,
|
||||
ByteBuf data, ChannelPromise promise) {
|
||||
long data, ChannelPromise promise) {
|
||||
if (ack) {
|
||||
logger.logPingAck(OUTBOUND, ctx, data);
|
||||
} else {
|
||||
|
@ -16,15 +16,13 @@
|
||||
|
||||
package io.netty.handler.codec.http2;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufHolder;
|
||||
import io.netty.util.internal.UnstableApi;
|
||||
|
||||
/**
|
||||
* HTTP/2 PING Frame.
|
||||
*/
|
||||
@UnstableApi
|
||||
public interface Http2PingFrame extends Http2Frame, ByteBufHolder {
|
||||
public interface Http2PingFrame extends Http2Frame {
|
||||
|
||||
/**
|
||||
* When {@code true}, indicates that this ping is a ping response.
|
||||
@ -34,6 +32,5 @@ public interface Http2PingFrame extends Http2Frame, ByteBufHolder {
|
||||
/**
|
||||
* Returns the eight byte opaque data.
|
||||
*/
|
||||
@Override
|
||||
ByteBuf content();
|
||||
long content();
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import static io.netty.buffer.Unpooled.EMPTY_BUFFER;
|
||||
import static io.netty.buffer.Unpooled.wrappedBuffer;
|
||||
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT;
|
||||
import static io.netty.handler.codec.http2.Http2CodecUtil.emptyPingBuf;
|
||||
import static io.netty.handler.codec.http2.Http2Error.PROTOCOL_ERROR;
|
||||
import static io.netty.handler.codec.http2.Http2Stream.State.IDLE;
|
||||
import static io.netty.handler.codec.http2.Http2Stream.State.OPEN;
|
||||
@ -714,15 +713,15 @@ public class DefaultHttp2ConnectionDecoderTest {
|
||||
|
||||
@Test
|
||||
public void pingReadWithAckShouldNotifyListener() throws Exception {
|
||||
decode().onPingAckRead(ctx, emptyPingBuf());
|
||||
verify(listener).onPingAckRead(eq(ctx), eq(emptyPingBuf()));
|
||||
decode().onPingAckRead(ctx, 0L);
|
||||
verify(listener).onPingAckRead(eq(ctx), eq(0L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pingReadShouldReplyWithAck() throws Exception {
|
||||
decode().onPingRead(ctx, emptyPingBuf());
|
||||
verify(encoder).writePing(eq(ctx), eq(true), eq(emptyPingBuf()), eq(promise));
|
||||
verify(listener, never()).onPingAckRead(eq(ctx), any(ByteBuf.class));
|
||||
decode().onPingRead(ctx, 0L);
|
||||
verify(encoder).writePing(eq(ctx), eq(true), eq(0L), eq(promise));
|
||||
verify(listener, never()).onPingAckRead(eq(ctx), any(long.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -45,7 +45,6 @@ import java.util.List;
|
||||
import static io.netty.buffer.Unpooled.EMPTY_BUFFER;
|
||||
import static io.netty.buffer.Unpooled.wrappedBuffer;
|
||||
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT;
|
||||
import static io.netty.handler.codec.http2.Http2CodecUtil.emptyPingBuf;
|
||||
import static io.netty.handler.codec.http2.Http2Error.PROTOCOL_ERROR;
|
||||
import static io.netty.handler.codec.http2.Http2Stream.State.HALF_CLOSED_REMOTE;
|
||||
import static io.netty.handler.codec.http2.Http2Stream.State.RESERVED_LOCAL;
|
||||
@ -639,15 +638,15 @@ public class DefaultHttp2ConnectionEncoderTest {
|
||||
public void pingWriteAfterGoAwayShouldSucceed() throws Exception {
|
||||
ChannelPromise promise = newPromise();
|
||||
goAwayReceived(0);
|
||||
encoder.writePing(ctx, false, emptyPingBuf(), promise);
|
||||
verify(writer).writePing(eq(ctx), eq(false), eq(emptyPingBuf()), eq(promise));
|
||||
encoder.writePing(ctx, false, 0L, promise);
|
||||
verify(writer).writePing(eq(ctx), eq(false), eq(0L), eq(promise));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pingWriteShouldSucceed() throws Exception {
|
||||
ChannelPromise promise = newPromise();
|
||||
encoder.writePing(ctx, false, emptyPingBuf(), promise);
|
||||
verify(writer).writePing(eq(ctx), eq(false), eq(emptyPingBuf()), eq(promise));
|
||||
encoder.writePing(ctx, false, 0L, promise);
|
||||
verify(writer).writePing(eq(ctx), eq(false), eq(0L), eq(promise));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -57,7 +57,6 @@ import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGH
|
||||
import static io.netty.handler.codec.http2.Http2Error.PROTOCOL_ERROR;
|
||||
import static io.netty.handler.codec.http2.Http2TestUtil.randomString;
|
||||
import static io.netty.handler.codec.http2.Http2TestUtil.runInChannel;
|
||||
import static io.netty.util.CharsetUtil.UTF_8;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
@ -871,24 +870,23 @@ public class Http2ConnectionRoundtripTest {
|
||||
@Test
|
||||
public void stressTest() throws Exception {
|
||||
final Http2Headers headers = dummyHeaders();
|
||||
final String pingMsg = "12345678";
|
||||
int length = 10;
|
||||
final ByteBuf data = randomBytes(length);
|
||||
final String dataAsHex = ByteBufUtil.hexDump(data);
|
||||
final ByteBuf pingData = Unpooled.copiedBuffer(pingMsg, UTF_8);
|
||||
final long pingData = 8;
|
||||
final int numStreams = 2000;
|
||||
|
||||
// Collect all the ping buffers as we receive them at the server.
|
||||
final String[] receivedPings = new String[numStreams];
|
||||
final long[] receivedPings = new long[numStreams];
|
||||
doAnswer(new Answer<Void>() {
|
||||
int nextIndex;
|
||||
|
||||
@Override
|
||||
public Void answer(InvocationOnMock in) throws Throwable {
|
||||
receivedPings[nextIndex++] = ((ByteBuf) in.getArguments()[1]).toString(UTF_8);
|
||||
receivedPings[nextIndex++] = (Long) in.getArguments()[1];
|
||||
return null;
|
||||
}
|
||||
}).when(serverListener).onPingRead(any(ChannelHandlerContext.class), any(ByteBuf.class));
|
||||
}).when(serverListener).onPingRead(any(ChannelHandlerContext.class), any(Long.class));
|
||||
|
||||
// Collect all the data buffers as we receive them at the server.
|
||||
final StringBuilder[] receivedData = new StringBuilder[numStreams];
|
||||
@ -921,7 +919,7 @@ public class Http2ConnectionRoundtripTest {
|
||||
// Send a bunch of data on each stream.
|
||||
http2Client.encoder().writeHeaders(ctx(), streamId, headers, 0, (short) 16,
|
||||
false, 0, false, newPromise());
|
||||
http2Client.encoder().writePing(ctx(), false, pingData.retainedSlice(),
|
||||
http2Client.encoder().writePing(ctx(), false, pingData,
|
||||
newPromise());
|
||||
http2Client.encoder().writeData(ctx(), streamId, data.retainedSlice(), 0,
|
||||
false, newPromise());
|
||||
@ -940,20 +938,19 @@ public class Http2ConnectionRoundtripTest {
|
||||
verify(serverListener, times(numStreams)).onHeadersRead(any(ChannelHandlerContext.class), anyInt(),
|
||||
eq(headers), eq(0), eq((short) 16), eq(false), eq(0), eq(true));
|
||||
verify(serverListener, times(numStreams)).onPingRead(any(ChannelHandlerContext.class),
|
||||
any(ByteBuf.class));
|
||||
any(long.class));
|
||||
verify(serverListener, never()).onDataRead(any(ChannelHandlerContext.class),
|
||||
anyInt(), any(ByteBuf.class), eq(0), eq(true));
|
||||
for (StringBuilder builder : receivedData) {
|
||||
assertEquals(dataAsHex, builder.toString());
|
||||
}
|
||||
for (String receivedPing : receivedPings) {
|
||||
assertEquals(pingMsg, receivedPing);
|
||||
for (long receivedPing : receivedPings) {
|
||||
assertEquals(pingData, receivedPing);
|
||||
}
|
||||
} finally {
|
||||
// Don't wait for server to close streams
|
||||
http2Client.gracefulShutdownTimeoutMillis(0);
|
||||
data.release();
|
||||
pingData.release();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -615,24 +615,20 @@ public class Http2FrameCodecTest {
|
||||
|
||||
@Test
|
||||
public void receivePing() throws Http2Exception {
|
||||
ByteBuf data = Unpooled.buffer(8).writeLong(12345);
|
||||
frameListener.onPingRead(http2HandlerCtx, data);
|
||||
frameListener.onPingRead(http2HandlerCtx, 12345L);
|
||||
|
||||
Http2PingFrame pingFrame = inboundHandler.readInbound();
|
||||
assertNotNull(pingFrame);
|
||||
|
||||
assertEquals(data, pingFrame.content());
|
||||
assertEquals(12345, pingFrame.content());
|
||||
assertFalse(pingFrame.ack());
|
||||
pingFrame.release();
|
||||
data.release();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendPing() {
|
||||
ByteBuf data = Unpooled.buffer(8).writeLong(12345);
|
||||
channel.writeAndFlush(new DefaultHttp2PingFrame(data));
|
||||
channel.writeAndFlush(new DefaultHttp2PingFrame(12345));
|
||||
|
||||
verify(frameWriter).writePing(eq(http2HandlerCtx), eq(false), eq(data), anyChannelPromise());
|
||||
verify(frameWriter).writePing(eq(http2HandlerCtx), eq(false), eq(12345L), anyChannelPromise());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -351,26 +351,22 @@ public class Http2FrameRoundtripTest {
|
||||
|
||||
@Test
|
||||
public void pingFrameShouldMatch() throws Exception {
|
||||
final ByteBuf data = buf("01234567".getBytes(UTF_8));
|
||||
|
||||
writer.writePing(ctx, false, data.slice(), ctx.newPromise());
|
||||
writer.writePing(ctx, false, 1234567, ctx.newPromise());
|
||||
readFrames();
|
||||
|
||||
ArgumentCaptor<ByteBuf> captor = ArgumentCaptor.forClass(ByteBuf.class);
|
||||
ArgumentCaptor<Long> captor = ArgumentCaptor.forClass(long.class);
|
||||
verify(listener).onPingRead(eq(ctx), captor.capture());
|
||||
assertEquals(data, captor.getValue());
|
||||
assertEquals(1234567, (long) captor.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pingAckFrameShouldMatch() throws Exception {
|
||||
final ByteBuf data = buf("01234567".getBytes(UTF_8));
|
||||
|
||||
writer.writePing(ctx, true, data.slice(), ctx.newPromise());
|
||||
writer.writePing(ctx, true, 1234567, ctx.newPromise());
|
||||
readFrames();
|
||||
|
||||
ArgumentCaptor<ByteBuf> captor = ArgumentCaptor.forClass(ByteBuf.class);
|
||||
ArgumentCaptor<Long> captor = ArgumentCaptor.forClass(long.class);
|
||||
verify(listener).onPingAckRead(eq(ctx), captor.capture());
|
||||
assertEquals(data, captor.getValue());
|
||||
assertEquals(1234567, (long) captor.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -175,13 +175,11 @@ public class Http2MultiplexCodecTest {
|
||||
|
||||
@Test
|
||||
public void unhandledHttp2FramesShouldBePropagated() {
|
||||
ByteBuf content = UnpooledByteBufAllocator.DEFAULT.buffer(8).writeLong(0);
|
||||
Http2PingFrame decodedFrame = new DefaultHttp2PingFrame(content);
|
||||
Http2PingFrame decodedFrame = new DefaultHttp2PingFrame(0);
|
||||
|
||||
codec.onHttp2Frame(decodedFrame);
|
||||
Http2PingFrame receivedPing = parentChannel.readInbound();
|
||||
assertSame(receivedPing, decodedFrame);
|
||||
assertTrue(receivedPing.release());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -249,13 +249,13 @@ public final class Http2TestUtil {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||
public void onPingRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
||||
listener.onPingRead(ctx, data);
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
||||
listener.onPingAckRead(ctx, data);
|
||||
latch.countDown();
|
||||
}
|
||||
@ -384,13 +384,13 @@ public final class Http2TestUtil {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||
public void onPingRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
||||
listener.onPingRead(ctx, data);
|
||||
messageLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
||||
listener.onPingAckRead(ctx, data);
|
||||
messageLatch.countDown();
|
||||
}
|
||||
|
@ -138,11 +138,11 @@ public final class HelloWorldHttp2Handler extends Http2ConnectionHandler impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) {
|
||||
public void onPingRead(ChannelHandlerContext ctx, long data) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) {
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, long data) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -138,11 +138,11 @@ public final class HelloWorldHttp2Handler extends Http2ConnectionHandler impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) {
|
||||
public void onPingRead(ChannelHandlerContext ctx, long data) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) {
|
||||
public void onPingAckRead(ChannelHandlerContext ctx, long data) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user