use of org.asynchttpclient.netty.OnLastHttpContentCallback in project async-http-client by AsyncHttpClient.
the class Continue100Interceptor method exitAfterHandling100.
public boolean exitAfterHandling100(final Channel channel, final NettyResponseFuture<?> future, int statusCode) {
future.setHeadersAlreadyWrittenOnContinue(true);
future.setDontWriteBodyBecauseExpectContinue(false);
// directly send the body
Channels.setAttribute(channel, new OnLastHttpContentCallback(future) {
@Override
public void call() throws IOException {
Channels.setAttribute(channel, future);
requestSender.writeRequest(future, channel);
}
});
return true;
}
use of org.asynchttpclient.netty.OnLastHttpContentCallback 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 org.asynchttpclient.netty.OnLastHttpContentCallback in project async-http-client by AsyncHttpClient.
the class AsyncHttpClientHandler method channelRead.
@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
Channel channel = ctx.channel();
Object attribute = Channels.getAttribute(channel);
try {
if (attribute instanceof OnLastHttpContentCallback) {
if (msg instanceof LastHttpContent) {
((OnLastHttpContentCallback) attribute).call();
}
} else if (attribute instanceof NettyResponseFuture) {
NettyResponseFuture<?> future = (NettyResponseFuture<?>) attribute;
future.touch();
handleRead(channel, future, msg);
} else if (attribute instanceof StreamedResponsePublisher) {
StreamedResponsePublisher publisher = (StreamedResponsePublisher) attribute;
publisher.future().touch();
if (msg instanceof HttpContent) {
ByteBuf content = ((HttpContent) msg).content();
// Republish as a HttpResponseBodyPart
if (content.isReadable()) {
HttpResponseBodyPart part = config.getResponseBodyPartFactory().newResponseBodyPart(content, false);
ctx.fireChannelRead(part);
}
if (msg instanceof LastHttpContent) {
// Remove the handler from the pipeline, this will trigger
// it to finish
ctx.pipeline().remove(publisher);
// Trigger a read, just in case the last read complete
// triggered no new read
ctx.read();
// Send the last content on to the protocol, so that it can
// conclude the cleanup
handleRead(channel, publisher.future(), msg);
}
} else {
logger.info("Received unexpected message while expecting a chunk: " + msg);
ctx.pipeline().remove(publisher);
Channels.setDiscard(channel);
}
} else if (attribute != DiscardEvent.DISCARD) {
// unhandled message
logger.debug("Orphan channel {} with attribute {} received message {}, closing", channel, attribute, msg);
Channels.silentlyCloseChannel(channel);
}
} finally {
ReferenceCountUtil.release(msg);
}
}
use of org.asynchttpclient.netty.OnLastHttpContentCallback in project async-http-client by AsyncHttpClient.
the class AsyncHttpClientHandler method channelInactive.
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
if (requestSender.isClosed())
return;
Channel channel = ctx.channel();
channelManager.removeAll(channel);
Object attribute = Channels.getAttribute(channel);
logger.debug("Channel Closed: {} with attribute {}", channel, attribute);
if (attribute instanceof StreamedResponsePublisher) {
// setting `attribute` to be the underlying future so that the retry
// logic can kick-in
attribute = ((StreamedResponsePublisher) attribute).future();
}
if (attribute instanceof OnLastHttpContentCallback) {
OnLastHttpContentCallback callback = (OnLastHttpContentCallback) attribute;
Channels.setAttribute(channel, callback.future());
callback.call();
} else if (attribute instanceof NettyResponseFuture<?>) {
NettyResponseFuture<?> future = (NettyResponseFuture<?>) attribute;
future.touch();
if (hasIOExceptionFilters && requestSender.applyIoExceptionFiltersAndReplayRequest(future, ChannelClosedException.INSTANCE, channel))
return;
handleChannelInactive(future);
requestSender.handleUnexpectedClosedChannel(channel, future);
}
}
use of org.asynchttpclient.netty.OnLastHttpContentCallback in project async-http-client by AsyncHttpClient.
the class Continue100Interceptor method exitAfterHandling100.
public boolean exitAfterHandling100(final Channel channel, final NettyResponseFuture<?> future) {
future.setHeadersAlreadyWrittenOnContinue(true);
future.setDontWriteBodyBecauseExpectContinue(false);
// directly send the body
Channels.setAttribute(channel, new OnLastHttpContentCallback(future) {
@Override
public void call() {
Channels.setAttribute(channel, future);
requestSender.writeRequest(future, channel);
}
});
return true;
}
Aggregations