in zuul-core/src/main/java/com/netflix/zuul/netty/server/ClientResponseWriter.java [91:153]
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
Channel channel = ctx.channel();
if (msg instanceof HttpResponseMessage resp) {
if (skipProcessing(resp)) {
return;
}
if (!isHandlingRequest || startedSendingResponseToClient) {
/* This can happen if we are already in the process of streaming response back to client OR NOT within active
request/response cycle and something like IDLE or Request Read timeout occurs. In that case we have no way
to recover other than closing the socket and cleaning up resources used by BOTH responses.
*/
resp.disposeBufferedBody();
if (zuulResponse != null) {
zuulResponse.disposeBufferedBody();
}
ctx.close(); // This will trigger CompleteEvent if one is needed
return;
}
startedSendingResponseToClient = true;
zuulResponse = resp;
if ("close".equalsIgnoreCase(zuulResponse.getHeaders().getFirst("Connection"))) {
closeConnection = true;
}
channel.attr(ClientRequestReceiver.ATTR_ZUUL_RESP).set(zuulResponse);
if (channel.isActive()) {
// Track if this is happening.
if (!ClientRequestReceiver.isLastContentReceivedForChannel(channel)
&& !shouldAllowPreemptiveResponse(channel)) {
responseBeforeReceivedLastContentCounter.increment();
logger.warn(
"Writing response to client channel before have received the LastContent of request! {},"
+ " {}",
zuulResponse.getInboundRequest().getInfoForLogging(),
ChannelUtils.channelInfoForLogging(channel));
}
// Write out and flush the response to the client channel.
channel.write(buildHttpResponse(zuulResponse));
writeBufferedBodyContent(zuulResponse, channel);
channel.flush();
} else {
resp.disposeBufferedBody();
channel.close();
}
} else if (msg instanceof HttpContent chunk) {
if (channel.isActive()) {
channel.writeAndFlush(chunk);
} else {
chunk.release();
channel.close();
}
} else {
// should never happen
ReferenceCountUtil.release(msg);
throw new ZuulException("Received invalid message from origin", true);
}
}