in zuul-core/src/main/java/com/netflix/zuul/filters/endpoint/ProxyEndpoint.java [862:910]
private HttpResponseMessage buildZuulHttpResponse(
HttpResponse httpResponse, StatusCategory statusCategory, Throwable ex) {
startedSendingResponseToClient = true;
// Translate the netty HttpResponse into a zuul HttpResponseMessage.
SessionContext zuulCtx = context;
int respStatus = httpResponse.status().code();
HttpResponseMessage zuulResponse = new HttpResponseMessageImpl(zuulCtx, zuulRequest, respStatus);
Headers respHeaders = zuulResponse.getHeaders();
for (Map.Entry<String, String> entry : httpResponse.headers()) {
respHeaders.add(entry.getKey(), entry.getValue());
}
// Try to decide if this response has a body or not based on the headers (as we won't yet have
// received any of the content).
// NOTE that we also later may override this if it is Chunked encoding, but we receive
// a LastHttpContent without any prior HttpContent's.
if (HttpUtils.hasChunkedTransferEncodingHeader(zuulResponse)
|| HttpUtils.hasNonZeroContentLengthHeader(zuulResponse)) {
zuulResponse.setHasBody(true);
}
// Store this original response info for future reference (ie. for metrics and access logging purposes).
zuulResponse.storeInboundResponse();
channelCtx.channel().attr(ClientRequestReceiver.ATTR_ZUUL_RESP).set(zuulResponse);
if (httpResponse instanceof DefaultFullHttpResponse) {
ByteBufUtil.touch(
httpResponse, "ProxyEndpoint converting Netty response to Zuul response, request: ", zuulRequest);
ByteBuf chunk = ((DefaultFullHttpResponse) httpResponse).content();
zuulResponse.bufferBodyContents(new DefaultLastHttpContent(chunk));
}
// Invoke any Ribbon execution listeners.
// Request was a success even if server may have responded with an error code 5XX.
if (originConn != null) {
origin.onRequestExecutionSuccess(zuulRequest, zuulResponse, originConn.getServer(), attemptNum);
}
// Collect some info about the received response.
origin.recordFinalResponse(zuulResponse);
origin.recordFinalError(zuulRequest, ex);
StatusCategoryUtils.setStatusCategory(zuulCtx, statusCategory);
zuulCtx.setError(ex);
zuulCtx.put("origin_http_status", Integer.toString(respStatus));
return transformResponse(zuulResponse);
}