use of com.netflix.zuul.message.http.HttpResponseMessage in project zuul by Netflix.
the class PassportLoggingHandler method logPassport.
private void logPassport(Channel channel) {
// Collect attributes.
CurrentPassport passport = CurrentPassport.fromChannel(channel);
HttpRequestMessage request = ClientRequestReceiver.getRequestFromChannel(channel);
HttpResponseMessage response = ClientRequestReceiver.getResponseFromChannel(channel);
SessionContext ctx = request == null ? null : request.getContext();
String topLevelRequestId = getRequestId(channel, ctx);
// Do some debug logging of the Passport.
if (LOG.isDebugEnabled()) {
LOG.debug("State after complete. " + ", current-server-conns = " + ConnCounter.from(channel).getCurrentActiveConns() + ", current-http-reqs = " + HttpMetricsChannelHandler.getInflightRequestCountFromChannel(channel) + ", status = " + (response == null ? getRequestId(channel, ctx) : response.getStatus()) + ", nfstatus = " + String.valueOf(StatusCategoryUtils.getStatusCategory(ctx)) + ", toplevelid = " + topLevelRequestId + ", req = " + request.getInfoForLogging() + ", passport = " + String.valueOf(passport));
}
// Some logging of session states if certain criteria match:
if (LOG.isInfoEnabled()) {
if (passport.wasProxyAttempt()) {
if (passport.findStateBackwards(PassportState.OUT_RESP_LAST_CONTENT_SENDING) == null) {
incompleteProxySessionCounter.increment();
LOG.info("Incorrect final state! toplevelid = " + topLevelRequestId + ", " + ChannelUtils.channelInfoForLogging(channel));
}
}
if (!passport.wasProxyAttempt()) {
if (ctx != null && !isHealthcheckRequest(request)) {
// Why did we fail to attempt to proxy this request?
RequestAttempts attempts = RequestAttempts.getFromSessionContext(ctx);
LOG.debug("State after complete. " + ", context-error = " + String.valueOf(ctx.getError()) + ", current-http-reqs = " + HttpMetricsChannelHandler.getInflightRequestCountFromChannel(channel) + ", toplevelid = " + topLevelRequestId + ", req = " + request.getInfoForLogging() + ", attempts = " + String.valueOf(attempts) + ", passport = " + String.valueOf(passport));
}
}
StartAndEnd inReqToOutResp = passport.findFirstStartAndLastEndStates(PassportState.IN_REQ_HEADERS_RECEIVED, PassportState.OUT_REQ_LAST_CONTENT_SENT);
if (passport.calculateTimeBetween(inReqToOutResp) > WARN_REQ_PROCESSING_TIME_NS.get()) {
LOG.info("Request processing took longer than threshold! toplevelid = " + topLevelRequestId + ", " + ChannelUtils.channelInfoForLogging(channel));
}
StartAndEnd inRespToOutResp = passport.findLastStartAndFirstEndStates(PassportState.IN_RESP_HEADERS_RECEIVED, PassportState.OUT_RESP_LAST_CONTENT_SENT);
if (passport.calculateTimeBetween(inRespToOutResp) > WARN_RESP_PROCESSING_TIME_NS.get()) {
LOG.info("Response processing took longer than threshold! toplevelid = " + topLevelRequestId + ", " + ChannelUtils.channelInfoForLogging(channel));
}
}
}
use of com.netflix.zuul.message.http.HttpResponseMessage in project zuul by Netflix.
the class BaseZuulChannelInitializer method addZuulFilterChainHandler.
protected void addZuulFilterChainHandler(final ChannelPipeline pipeline) {
final ZuulFilter<HttpResponseMessage, HttpResponseMessage>[] responseFilters = getFilters(new OutboundPassportStampingFilter(FILTERS_OUTBOUND_START), new OutboundPassportStampingFilter(FILTERS_OUTBOUND_END));
// response filter chain
final ZuulFilterChainRunner<HttpResponseMessage> responseFilterChain = getFilterChainRunner(responseFilters, filterUsageNotifier);
// endpoint | response filter chain
final FilterRunner<HttpRequestMessage, HttpResponseMessage> endPoint = getEndpointRunner(responseFilterChain, filterUsageNotifier, filterLoader);
final ZuulFilter<HttpRequestMessage, HttpRequestMessage>[] requestFilters = getFilters(new InboundPassportStampingFilter(FILTERS_INBOUND_START), new InboundPassportStampingFilter(FILTERS_INBOUND_END));
// request filter chain | end point | response filter chain
final ZuulFilterChainRunner<HttpRequestMessage> requestFilterChain = getFilterChainRunner(requestFilters, filterUsageNotifier, endPoint);
pipeline.addLast(new ZuulFilterChainHandler(requestFilterChain, responseFilterChain));
}
use of com.netflix.zuul.message.http.HttpResponseMessage in project zuul by Netflix.
the class ClientResponseWriter method channelRead.
@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
final Channel channel = ctx.channel();
if (msg instanceof HttpResponseMessage) {
final HttpResponseMessage resp = (HttpResponseMessage) msg;
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();
// This will trigger CompleteEvent if one is needed
ctx.close();
return;
}
startedSendingResponseToClient = true;
zuulResponse = resp;
if ("close".equalsIgnoreCase(zuulResponse.getHeaders().getFirst("Connection"))) {
closeConnection = true;
}
channel.attr(ATTR_ZUUL_RESP).set(zuulResponse);
if (channel.isActive()) {
// Track if this is happening.
if (!ClientRequestReceiver.isLastContentReceivedForChannel(channel)) {
StatusCategory status = StatusCategoryUtils.getStatusCategory(ClientRequestReceiver.getRequestFromChannel(channel));
if (ZuulStatusCategory.FAILURE_CLIENT_TIMEOUT.equals(status)) {
// If the request timed-out while being read, then there won't have been any LastContent, but thats ok because the connection will have to be discarded anyway.
} else {
responseBeforeReceivedLastContentCounter.increment();
LOG.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 {
channel.close();
}
} else if (msg instanceof HttpContent) {
final HttpContent chunk = (HttpContent) msg;
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);
}
}
use of com.netflix.zuul.message.http.HttpResponseMessage in project zuul by Netflix.
the class ZuulEndPointRunner method filter.
@Override
public void filter(final HttpRequestMessage zuulReq) {
if (zuulReq.getContext().isCancelled()) {
PerfMark.event(getClass().getName(), "filterCancelled");
zuulReq.disposeBufferedBody();
logger.debug("Request was cancelled, UUID {}", zuulReq.getContext().getUUID());
return;
}
final String endpointName = getEndPointName(zuulReq.getContext());
try (TaskCloseable ignored = PerfMark.traceTask(this, s -> s.getClass().getSimpleName() + ".filter")) {
Preconditions.checkNotNull(zuulReq, "input message");
addPerfMarkTags(zuulReq);
final ZuulFilter<HttpRequestMessage, HttpResponseMessage> endpoint = getEndpoint(endpointName, zuulReq);
logger.debug("Got endpoint {}, UUID {}", endpoint.filterName(), zuulReq.getContext().getUUID());
setEndpoint(zuulReq, endpoint);
final HttpResponseMessage zuulResp = filter(endpoint, zuulReq);
if ((zuulResp != null) && (!(endpoint instanceof ProxyEndpoint))) {
// EdgeProxyEndpoint calls invokeNextStage internally
logger.debug("Endpoint calling invokeNextStage, UUID {}", zuulReq.getContext().getUUID());
invokeNextStage(zuulResp);
}
} catch (Exception ex) {
handleException(zuulReq, endpointName, ex);
}
}
use of com.netflix.zuul.message.http.HttpResponseMessage in project zuul by Netflix.
the class HttpUtilsTest method getBodySizeIfKnown_returnsResponseBodySize.
@Test
public void getBodySizeIfKnown_returnsResponseBodySize() {
SessionContext context = new SessionContext();
Headers headers = new Headers();
HttpQueryParams queryParams = new HttpQueryParams();
HttpRequestMessage request = new HttpRequestMessageImpl(context, "http", "GET", "/path", queryParams, headers, "127.0.0.1", "scheme", 6666, "server-name");
request.storeInboundRequest();
HttpResponseMessage response = new HttpResponseMessageImpl(context, request, 200);
response.setBodyAsText("Hello world");
assertThat(HttpUtils.getBodySizeIfKnown(response)).isEqualTo(Integer.valueOf(11));
}
Aggregations