Make it configurable if the HttpClientCodec should throw an exception on close when the response and request count does not match. Default is false. See #266
This commit is contained in:
parent
d808cd0475
commit
54559a9595
@ -57,14 +57,16 @@ public class HttpClientCodec implements ChannelUpstreamHandler,
|
|||||||
private final HttpRequestEncoder encoder = new Encoder();
|
private final HttpRequestEncoder encoder = new Encoder();
|
||||||
private final HttpResponseDecoder decoder;
|
private final HttpResponseDecoder decoder;
|
||||||
private final AtomicLong requestResponseCounter = new AtomicLong(0);
|
private final AtomicLong requestResponseCounter = new AtomicLong(0);
|
||||||
|
private final boolean failOnMissingResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance with the default decoder options
|
* Creates a new instance with the default decoder options
|
||||||
* ({@code maxInitialLineLength (4096}}, {@code maxHeaderSize (8192)}, and
|
* ({@code maxInitialLineLength (4096}}, {@code maxHeaderSize (8192)}, and
|
||||||
* {@code maxChunkSize (8192)}).
|
* {@code maxChunkSize (8192)}).
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public HttpClientCodec() {
|
public HttpClientCodec() {
|
||||||
this(4096, 8192, 8192);
|
this(4096, 8192, 8192, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,7 +74,16 @@ public class HttpClientCodec implements ChannelUpstreamHandler,
|
|||||||
*/
|
*/
|
||||||
public HttpClientCodec(
|
public HttpClientCodec(
|
||||||
int maxInitialLineLength, int maxHeaderSize, int maxChunkSize) {
|
int maxInitialLineLength, int maxHeaderSize, int maxChunkSize) {
|
||||||
|
this(maxInitialLineLength, maxHeaderSize, maxChunkSize, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance with the specified decoder options.
|
||||||
|
*/
|
||||||
|
public HttpClientCodec(
|
||||||
|
int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, boolean failOnMissingResponse) {
|
||||||
decoder = new Decoder(maxInitialLineLength, maxHeaderSize, maxChunkSize);
|
decoder = new Decoder(maxInitialLineLength, maxHeaderSize, maxChunkSize);
|
||||||
|
this.failOnMissingResponse = failOnMissingResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -101,12 +112,14 @@ public class HttpClientCodec implements ChannelUpstreamHandler,
|
|||||||
|
|
||||||
Object obj = super.encode(ctx, channel, msg);
|
Object obj = super.encode(ctx, channel, msg);
|
||||||
|
|
||||||
// check if the request is chunked if so do not increment
|
if (failOnMissingResponse) {
|
||||||
if (msg instanceof HttpRequest && !((HttpRequest) msg).isChunked()) {
|
// check if the request is chunked if so do not increment
|
||||||
requestResponseCounter.incrementAndGet();
|
if (msg instanceof HttpRequest && !((HttpRequest) msg).isChunked()) {
|
||||||
} else if (msg instanceof HttpChunk && ((HttpChunk) msg).isLast()) {
|
requestResponseCounter.incrementAndGet();
|
||||||
// increment as its the last chunk
|
} else if (msg instanceof HttpChunk && ((HttpChunk) msg).isLast()) {
|
||||||
requestResponseCounter.incrementAndGet();
|
// increment as its the last chunk
|
||||||
|
requestResponseCounter.incrementAndGet();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
@ -127,7 +140,9 @@ public class HttpClientCodec implements ChannelUpstreamHandler,
|
|||||||
return buffer.readBytes(actualReadableBytes());
|
return buffer.readBytes(actualReadableBytes());
|
||||||
} else {
|
} else {
|
||||||
Object msg = super.decode(ctx, channel, buffer, state);
|
Object msg = super.decode(ctx, channel, buffer, state);
|
||||||
decrement(msg);
|
if (failOnMissingResponse) {
|
||||||
|
decrement(msg);
|
||||||
|
}
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,9 +219,11 @@ public class HttpClientCodec implements ChannelUpstreamHandler,
|
|||||||
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
|
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
|
||||||
super.channelClosed(ctx, e);
|
super.channelClosed(ctx, e);
|
||||||
|
|
||||||
long missingResponses = requestResponseCounter.get();
|
if (failOnMissingResponse) {
|
||||||
if (missingResponses > 0) {
|
long missingResponses = requestResponseCounter.get();
|
||||||
throw new PrematureChannelClosureException("Channel closed but still missing " + missingResponses + " response(s)");
|
if (missingResponses > 0) {
|
||||||
|
throw new PrematureChannelClosureException("Channel closed but still missing " + missingResponses + " response(s)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ public class HttpClientCodecTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFailsNotOnRequestResponse() {
|
public void testFailsNotOnRequestResponse() {
|
||||||
HttpClientCodec codec = new HttpClientCodec();
|
HttpClientCodec codec = new HttpClientCodec(4096, 8192, 8192, true);
|
||||||
DecoderEmbedder<ChannelBuffer> decoder = new DecoderEmbedder<ChannelBuffer>(codec);
|
DecoderEmbedder<ChannelBuffer> decoder = new DecoderEmbedder<ChannelBuffer>(codec);
|
||||||
EncoderEmbedder<ChannelBuffer> encoder = new EncoderEmbedder<ChannelBuffer>(codec);
|
EncoderEmbedder<ChannelBuffer> encoder = new EncoderEmbedder<ChannelBuffer>(codec);
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ public class HttpClientCodecTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFailsNotOnRequestResponseChunked() {
|
public void testFailsNotOnRequestResponseChunked() {
|
||||||
HttpClientCodec codec = new HttpClientCodec();
|
HttpClientCodec codec = new HttpClientCodec(4096, 8192, 8192, true);
|
||||||
DecoderEmbedder<ChannelBuffer> decoder = new DecoderEmbedder<ChannelBuffer>(codec);
|
DecoderEmbedder<ChannelBuffer> decoder = new DecoderEmbedder<ChannelBuffer>(codec);
|
||||||
EncoderEmbedder<ChannelBuffer> encoder = new EncoderEmbedder<ChannelBuffer>(codec);
|
EncoderEmbedder<ChannelBuffer> encoder = new EncoderEmbedder<ChannelBuffer>(codec);
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ public class HttpClientCodecTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFailsOnMissingResponse() {
|
public void testFailsOnMissingResponse() {
|
||||||
HttpClientCodec codec = new HttpClientCodec();
|
HttpClientCodec codec = new HttpClientCodec(4096, 8192, 8192, true);
|
||||||
EncoderEmbedder<ChannelBuffer> encoder = new EncoderEmbedder<ChannelBuffer>(codec);
|
EncoderEmbedder<ChannelBuffer> encoder = new EncoderEmbedder<ChannelBuffer>(codec);
|
||||||
|
|
||||||
encoder.offer(new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost/"));
|
encoder.offer(new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost/"));
|
||||||
@ -82,7 +82,7 @@ public class HttpClientCodecTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFailsOnIncompleteChunkedResponse() {
|
public void testFailsOnIncompleteChunkedResponse() {
|
||||||
HttpClientCodec codec = new HttpClientCodec();
|
HttpClientCodec codec = new HttpClientCodec(4096, 8192, 8192, true);
|
||||||
DecoderEmbedder<ChannelBuffer> decoder = new DecoderEmbedder<ChannelBuffer>(codec);
|
DecoderEmbedder<ChannelBuffer> decoder = new DecoderEmbedder<ChannelBuffer>(codec);
|
||||||
|
|
||||||
EncoderEmbedder<ChannelBuffer> encoder = new EncoderEmbedder<ChannelBuffer>(codec);
|
EncoderEmbedder<ChannelBuffer> encoder = new EncoderEmbedder<ChannelBuffer>(codec);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user