use of io.netty.handler.codec.PrematureChannelClosureException in project async-http-client by AsyncHttpClient.
the class AsyncHttpClientHandler method exceptionCaught.
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) {
Throwable cause = getCause(e);
if (cause instanceof PrematureChannelClosureException || cause instanceof ClosedChannelException)
return;
Channel channel = ctx.channel();
NettyResponseFuture<?> future = null;
logger.debug("Unexpected I/O exception on channel {}", channel, cause);
try {
Object attribute = Channels.getAttribute(channel);
if (attribute instanceof StreamedResponsePublisher) {
ctx.fireExceptionCaught(e);
// setting `attribute` to be the underlying future so that the
// retry logic can kick-in
attribute = ((StreamedResponsePublisher) attribute).future();
}
if (attribute instanceof NettyResponseFuture<?>) {
future = (NettyResponseFuture<?>) attribute;
future.attachChannel(null, false);
future.touch();
if (cause instanceof IOException) {
// FIXME why drop the original exception and throw a new one?
if (hasIOExceptionFilters) {
if (!requestSender.applyIoExceptionFiltersAndReplayRequest(future, ChannelClosedException.INSTANCE, channel)) {
// Close the channel so the recovering can occurs.
Channels.silentlyCloseChannel(channel);
}
return;
}
}
if (StackTraceInspector.recoverOnReadOrWriteException(cause)) {
logger.debug("Trying to recover from dead Channel: {}", channel);
future.pendingException = cause;
return;
}
} else if (attribute instanceof OnLastHttpContentCallback) {
future = OnLastHttpContentCallback.class.cast(attribute).future();
}
} catch (Throwable t) {
cause = t;
}
if (future != null)
try {
logger.debug("Was unable to recover Future: {}", future);
requestSender.abort(channel, future, cause);
handleException(future, e);
} catch (Throwable t) {
logger.error(t.getMessage(), t);
}
channelManager.closeChannel(channel);
// FIXME not really sure
// ctx.fireChannelRead(e);
Channels.silentlyCloseChannel(channel);
}
use of io.netty.handler.codec.PrematureChannelClosureException in project netty by netty.
the class HttpClientCodecTest method testFailsOnMissingResponse.
@Test
public void testFailsOnMissingResponse() {
HttpClientCodec codec = new HttpClientCodec(4096, 8192, 8192, true);
EmbeddedChannel ch = new EmbeddedChannel(codec);
assertTrue(ch.writeOutbound(new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost/")));
ByteBuf buffer = ch.readOutbound();
assertNotNull(buffer);
buffer.release();
try {
ch.finish();
fail();
} catch (CodecException e) {
assertTrue(e instanceof PrematureChannelClosureException);
}
}
use of io.netty.handler.codec.PrematureChannelClosureException in project netty by netty.
the class HttpClientCodecTest method testFailsOnIncompleteChunkedResponse.
@Test
public void testFailsOnIncompleteChunkedResponse() {
HttpClientCodec codec = new HttpClientCodec(4096, 8192, 8192, true);
EmbeddedChannel ch = new EmbeddedChannel(codec);
ch.writeOutbound(new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost/"));
ByteBuf buffer = ch.readOutbound();
assertNotNull(buffer);
buffer.release();
assertNull(ch.readInbound());
ch.writeInbound(Unpooled.copiedBuffer(INCOMPLETE_CHUNKED_RESPONSE, CharsetUtil.ISO_8859_1));
assertThat(ch.readInbound(), instanceOf(HttpResponse.class));
// Chunk 'first'
((HttpContent) ch.readInbound()).release();
// Chunk 'second'
((HttpContent) ch.readInbound()).release();
assertNull(ch.readInbound());
try {
ch.finish();
fail();
} catch (CodecException e) {
assertTrue(e instanceof PrematureChannelClosureException);
}
}
use of io.netty.handler.codec.PrematureChannelClosureException in project ratpack by ratpack.
the class RequestActionSupport method addCommonResponseHandlers.
private void addCommonResponseHandlers(ChannelPipeline p, Downstream<? super T> downstream) throws Exception {
if (channelKey.ssl && p.get(SSL_HANDLER_NAME) == null) {
// this is added once because netty is not able to properly replace this handler on
// pooled channels from request to request. Because a pool is unique to a uri,
// doing this works, as subsequent requests would be passing in the same certs.
p.addLast(SSL_HANDLER_NAME, createSslHandler());
}
p.addLast(CLIENT_CODEC_HANDLER_NAME, new HttpClientCodec(4096, 8192, requestConfig.responseMaxChunkSize, false));
p.addLast(READ_TIMEOUT_HANDLER_NAME, new ReadTimeoutHandler(requestConfig.readTimeout.toNanos(), TimeUnit.NANOSECONDS));
p.addLast(REDIRECT_HANDLER_NAME, new SimpleChannelInboundHandler<HttpObject>(false) {
boolean redirected;
HttpResponse response;
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
ctx.fireExceptionCaught(new PrematureChannelClosureException("Server " + requestConfig.uri + " closed the connection prematurely"));
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
if (msg instanceof HttpResponse) {
this.response = (HttpResponse) msg;
int maxRedirects = requestConfig.maxRedirects;
int status = response.status().code();
String locationValue = response.headers().getAsString(HttpHeaderConstants.LOCATION);
Action<? super RequestSpec> redirectConfigurer = RequestActionSupport.this.requestConfigurer;
if (isRedirect(status) && redirectCount < maxRedirects && locationValue != null) {
final Function<? super ReceivedResponse, Action<? super RequestSpec>> onRedirect = requestConfig.onRedirect;
if (onRedirect != null) {
final Action<? super RequestSpec> onRedirectResult = onRedirect.apply(toReceivedResponse(response));
if (onRedirectResult == null) {
redirectConfigurer = null;
} else {
redirectConfigurer = redirectConfigurer.append(onRedirectResult);
}
}
if (redirectConfigurer != null) {
Action<? super RequestSpec> redirectRequestConfig = s -> {
if (status == 301 || status == 302) {
s.get();
}
};
redirectRequestConfig = redirectConfigurer.append(redirectRequestConfig);
URI locationUrl;
if (ABSOLUTE_PATTERN.matcher(locationValue).matches()) {
locationUrl = new URI(locationValue);
} else {
locationUrl = new URI(channelKey.ssl ? "https" : "http", null, channelKey.host, channelKey.port, locationValue, null, null);
}
onRedirect(locationUrl, redirectCount + 1, redirectRequestConfig).connect(downstream);
redirected = true;
dispose(ctx.pipeline(), response);
}
}
}
if (!redirected) {
ctx.fireChannelRead(msg);
}
}
});
if (requestConfig.decompressResponse) {
p.addLast(DECOMPRESS_HANDLER_NAME, new HttpContentDecompressor());
}
addResponseHandlers(p, downstream);
}
Aggregations