Search in sources :

Example 1 with HttpRequestMessage

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;
}
Also used : DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) HttpRequest(io.netty.handler.codec.http.HttpRequest) DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) InetSocketAddress(java.net.InetSocketAddress) HttpRequestMessage(com.netflix.zuul.message.http.HttpRequestMessage) Channel(io.netty.channel.Channel) HttpRequestMessageImpl(com.netflix.zuul.message.http.HttpRequestMessageImpl) ByteBuf(io.netty.buffer.ByteBuf) SslHandshakeInfo(com.netflix.netty.common.ssl.SslHandshakeInfo) DefaultLastHttpContent(io.netty.handler.codec.http.DefaultLastHttpContent) SessionContext(com.netflix.zuul.context.SessionContext) SocketAddress(java.net.SocketAddress) InetSocketAddress(java.net.InetSocketAddress)

Example 2 with HttpRequestMessage

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);
    }
}
Also used : HttpRequestMessage(com.netflix.zuul.message.http.HttpRequestMessage) SessionContext(com.netflix.zuul.context.SessionContext) HttpContent(io.netty.handler.codec.http.HttpContent)

Example 3 with HttpRequestMessage

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));
        }
    }
}
Also used : CurrentPassport(com.netflix.zuul.passport.CurrentPassport) HttpResponseMessage(com.netflix.zuul.message.http.HttpResponseMessage) HttpRequestMessage(com.netflix.zuul.message.http.HttpRequestMessage) RequestAttempts(com.netflix.zuul.niws.RequestAttempts) SessionContext(com.netflix.zuul.context.SessionContext) StartAndEnd(com.netflix.zuul.passport.StartAndEnd)

Example 4 with HttpRequestMessage

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));
}
Also used : OutboundPassportStampingFilter(com.netflix.zuul.filters.passport.OutboundPassportStampingFilter) HttpResponseMessage(com.netflix.zuul.message.http.HttpResponseMessage) HttpRequestMessage(com.netflix.zuul.message.http.HttpRequestMessage) ZuulFilterChainHandler(com.netflix.zuul.netty.filter.ZuulFilterChainHandler) ZuulFilter(com.netflix.zuul.filters.ZuulFilter) InboundPassportStampingFilter(com.netflix.zuul.filters.passport.InboundPassportStampingFilter)

Example 5 with HttpRequestMessage

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);
    }
}
Also used : HttpRequestMessage(com.netflix.zuul.message.http.HttpRequestMessage)

Aggregations

HttpRequestMessage (com.netflix.zuul.message.http.HttpRequestMessage)16 HttpResponseMessage (com.netflix.zuul.message.http.HttpResponseMessage)8 SessionContext (com.netflix.zuul.context.SessionContext)6 DefaultFullHttpRequest (io.netty.handler.codec.http.DefaultFullHttpRequest)4 HttpContent (io.netty.handler.codec.http.HttpContent)4 HttpRequest (io.netty.handler.codec.http.HttpRequest)4 TaskCloseable (io.perfmark.TaskCloseable)4 Test (org.junit.Test)4 ProxyEndpoint (com.netflix.zuul.filters.endpoint.ProxyEndpoint)3 ByteBuf (io.netty.buffer.ByteBuf)3 EmbeddedChannel (io.netty.channel.embedded.EmbeddedChannel)3 CompleteEvent (com.netflix.netty.common.HttpLifecycleChannelHandler.CompleteEvent)2 DefaultRegistry (com.netflix.spectator.api.DefaultRegistry)2 Headers (com.netflix.zuul.message.Headers)2 HttpQueryParams (com.netflix.zuul.message.http.HttpQueryParams)2 HttpRequestMessageImpl (com.netflix.zuul.message.http.HttpRequestMessageImpl)2 PassportLoggingHandler (com.netflix.zuul.netty.insights.PassportLoggingHandler)2 CurrentPassport (com.netflix.zuul.passport.CurrentPassport)2 HttpRequestEncoder (io.netty.handler.codec.http.HttpRequestEncoder)2 HttpServerCodec (io.netty.handler.codec.http.HttpServerCodec)2