use of com.netflix.zuul.message.http.HttpRequestMessage in project zuul by Netflix.
the class ClientRequestReceiver method buildZuulHttpRequest.
// Build a ZuulMessage from the netty request.
private HttpRequestMessage buildZuulHttpRequest(final HttpRequest nativeRequest, final ChannelHandlerContext clientCtx) {
PerfMark.attachTag("path", nativeRequest, HttpRequest::uri);
// Setup the context for this request.
final SessionContext context;
if (decorator != null) {
// Optionally decorate the context.
SessionContext tempContext = new SessionContext();
// Store the netty channel in SessionContext.
tempContext.set(CommonContextKeys.NETTY_SERVER_CHANNEL_HANDLER_CONTEXT, clientCtx);
context = decorator.decorate(tempContext);
// We expect the UUID is present after decoration
PerfMark.attachTag("uuid", context, SessionContext::getUUID);
} else {
context = new SessionContext();
}
// Get the client IP (ignore XFF headers at this point, as that can be app specific).
final Channel channel = clientCtx.channel();
final String clientIp = channel.attr(SourceAddressChannelHandler.ATTR_SOURCE_ADDRESS).get();
// This is the only way I found to get the port of the request with netty...
final int port = channel.attr(SourceAddressChannelHandler.ATTR_SERVER_LOCAL_PORT).get();
final String serverName = channel.attr(SourceAddressChannelHandler.ATTR_SERVER_LOCAL_ADDRESS).get();
final SocketAddress clientDestinationAddress = channel.attr(SourceAddressChannelHandler.ATTR_LOCAL_ADDR).get();
final InetSocketAddress proxyProtocolDestinationAddress = channel.attr(SourceAddressChannelHandler.ATTR_PROXY_PROTOCOL_DESTINATION_ADDRESS).get();
if (proxyProtocolDestinationAddress != null) {
context.set(CommonContextKeys.PROXY_PROTOCOL_DESTINATION_ADDRESS, proxyProtocolDestinationAddress);
}
// Store info about the SSL handshake if applicable, and choose the http scheme.
String scheme = SCHEME_HTTP;
final SslHandshakeInfo sslHandshakeInfo = channel.attr(SslHandshakeInfoHandler.ATTR_SSL_INFO).get();
if (sslHandshakeInfo != null) {
context.set(CommonContextKeys.SSL_HANDSHAKE_INFO, sslHandshakeInfo);
scheme = SCHEME_HTTPS;
}
// Decide if this is HTTP/1 or HTTP/2.
String protocol = channel.attr(PROTOCOL_NAME).get();
if (protocol == null) {
protocol = nativeRequest.protocolVersion().text();
}
// Strip off the query from the path.
String path = parsePath(nativeRequest.uri());
// Setup the req/resp message objects.
final HttpRequestMessage request = new HttpRequestMessageImpl(context, protocol, nativeRequest.method().asciiName().toString().toLowerCase(), path, copyQueryParams(nativeRequest), copyHeaders(nativeRequest), clientIp, scheme, port, serverName, clientDestinationAddress, false);
// a LastHttpContent without any prior HttpContent's.
if (HttpUtils.hasChunkedTransferEncodingHeader(request) || HttpUtils.hasNonZeroContentLengthHeader(request)) {
request.setHasBody(true);
}
// Store this original request info for future reference (ie. for metrics and access logging purposes).
request.storeInboundRequest();
// Store the netty request for use later.
context.set(CommonContextKeys.NETTY_HTTP_REQUEST, nativeRequest);
// Store zuul request on netty channel for later use.
channel.attr(ATTR_ZUUL_REQ).set(request);
if (nativeRequest instanceof DefaultFullHttpRequest) {
final ByteBuf chunk = ((DefaultFullHttpRequest) nativeRequest).content();
request.bufferBodyContents(new DefaultLastHttpContent(chunk));
}
return request;
}
use of com.netflix.zuul.message.http.HttpRequestMessage in project zuul by Netflix.
the class ZuulFilterChainHandler method channelRead.
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof HttpRequestMessage) {
zuulRequest = (HttpRequestMessage) msg;
// Replace NETTY_SERVER_CHANNEL_HANDLER_CONTEXT in SessionContext
final SessionContext zuulCtx = zuulRequest.getContext();
zuulCtx.put(NETTY_SERVER_CHANNEL_HANDLER_CONTEXT, ctx);
requestFilterChain.filter(zuulRequest);
} else if ((msg instanceof HttpContent) && (zuulRequest != null)) {
requestFilterChain.filter(zuulRequest, (HttpContent) msg);
} else {
LOG.debug("Received unrecognized message type. " + msg.getClass().getName());
ReferenceCountUtil.release(msg);
}
}
use of com.netflix.zuul.message.http.HttpRequestMessage 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.HttpRequestMessage 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.HttpRequestMessage in project zuul by Netflix.
the class ClientResponseWriter method handleComplete.
private void handleComplete(Channel channel) {
try {
if ((isHandlingRequest)) {
completeMetrics(channel, zuulResponse);
// Notify requestComplete listener if configured.
final HttpRequestMessage zuulRequest = ClientRequestReceiver.getRequestFromChannel(channel);
if ((requestCompleteHandler != null) && (zuulRequest != null)) {
requestCompleteHandler.handle(zuulRequest.getInboundRequest(), zuulResponse);
}
}
} catch (Throwable ex) {
LOG.error("Error in RequestCompleteHandler.", ex);
}
}
Aggregations