Runtime View¶
Request-Response Roundtrip¶
Any incoming TCP connection is wrapped into a Netty channel (io.netty.channel.Channel) and incoming bytes are handled by a chain of ChannelInboundHandlers. For connections resulting in bytes written back to the channel, the write attempts accordingly are passed along a chain of ChannelOutboundHandlers. To gain a deeper understanding about Netty’s asynchronous non-blocking I/O model, please refer to the documentation at https://netty.io/.
Inbound TCP streams that contain HTTP requests, are effectively handled by Zuul, where they are passed along chains of inbound filters and outbound filters. Between both chains, the final request is actually processed, usually by performing a proxy request against an upstream/origin server. This processing is performed by an endpoint filter.
Proxy requests are performed using Netty again on the HTTP and network layers.

Server Request Processing¶
This section describes, how incoming HTTP requests are processed by handlers of the underlying Zuul and Netty frameworks and handlers added by OX. It describes the various io.netty.channel.ChannelHandler implementations that perform actual work during this process. The term Channel denotes a low-level socket connection between client and server. A ChannelHandler reacts to events that happen on such channels. The most relevant events are:
inbound data is available for reading
outbound data was written
a user-defined event was fired
Channel handlers are implemented as chains, where each handler optionally performs its work based on an event and then calls the next handler in the chain to perform its own work. To preserve state between different handlers, multiple invocations of the same handler or different events of the same handler, a ChannelContext instance is passed along with the actual event object.
Server Channel Handlers¶
The following chain of inbound and outbound channel handlers is processed for each incoming HTTP request. The yellow boxes denote plain Netty handlers while the red ones denote Zuul handlers.

- IdleStateHandler
Schedules tasks to periodically check whether a configured idle time value was exceeded, resulting in an event.
Inbound: Tracks time of last complete message read event on the channel.
Outbound: Tracks time of last channel write event.
Triggered Events:
io.netty.handler.timeout.IdleStateEvent
Handled Events: –
- CloseOnIdleStateHandler
Closes idle channels.
Inbound: –
Outbound: –
Triggered Events: –
Handled Events:
io.netty.handler.timeout.IdleStateEvent
- PassportStateServerHandler
Passport maintenance to track channel lifecycles. See https://github.com/Netflix/zuul/wiki/Core-Features#request-passport.
Inbound: Tracked states:
SERVER_CH_ACTIVESERVER_CH_INACTIVESERVER_CH_EXCEPTION
Outbound: Tracked states:
SERVER_CH_CLOSESERVER_CH_DISCONNECTSERVER_CH_EXCEPTION
Triggered Events: –
Handled Events:
io.netty.handler.timeout.IdleStateEvent: Tracked asSERVER_CH_IDLE_TIMEOUT
- SourceAddressChannelHandler
Stores actual IP address and port of client and server sides of the channel within the channel context.
Inbound: –
Outbound: –
Triggered Events: –
Handled Events: –
- ServerChannelMetrics
Collects monitoring metrics on the channel level:
server.connections.currentserver.connections.connectserver.connections.errorsserver.connections.closeserver.connections.idle.timeoutserver.connections.throttled
Inbound: –
Outbound: –
Triggered Events: –
Handled Events:
MaxInboundConnectionsHandler.CONNECTION_THROTTLED_EVENTio.netty.handler.timeout.IdleStateEvent
- PerEventLoopMetricsChannelHandler
Collects monitoring metrics on the event loop level:
server.eventloop.http.requests.currentserver.eventloop.connections.current
Inbound: –
Outbound: –
Triggered Events: –
Handled Events:
HttpLifecycleChannelHandler.StartEvent: increment current HTTP requestsHttpLifecycleChannelHandler.CompleteEvent: decrement current HTTP requests
- ElbProxyProtocolChannelHandler
Decodes PROXY protocol and if applicable stores the contained client and server IP addresses and ports within the channel context. This effectively overrides the values stored by
SourceAddressChannelHandler.Inbound: Check for PROXY protocol and process its metadata.
Outbound: –
Triggered Events: –
Handled Events: –
- MaxInboundConnectionsHandler
Closes any incoming new connections if current count is above a configured threshold. For throttled connections, this is stored within the passport.
Inbound: –
Outbound: –
Triggered Events:
MaxInboundConnectionsHandler.CONNECTION_THROTTLED_EVENT
Handled Events: –
- SslHandler
Performs TLS handshake on incoming connections and ensures according wrapping of input/output byte buffers. See JavaDoc of
io.netty.handler.ssl.SslHandlerfor details.Inbound: –
Outbound: –
Triggered Events:
SslHandshakeCompletionEvent
Handled Events: –
- SslHandshakeInfoHandler
Stores info about the client and server’s SSL certificates in the context, after a successful handshake.
Inbound: –
Outbound: –
Triggered Events: –
Handled Events:
SslHandshakeCompletionEvent
- HttpServerCodec
De-/encodes the in-/outbound byte streams to/from HTTP domain objects.
Inbound: Decode byte stream into
io.netty.handler.codec.http.HttpRequest.Outbound: Encode
io.netty.handler.codec.http.HttpResponseinto byte stream.Triggered Events: –
Handled Events: –
- Http1ConnectionCloseHandler
Manages HTTP keep-alive lifecycle of inbound connections.
Inbound: –
Outbound: Adds
Connection: closeresponse header if channel is supposed to be closed after the current request was handled. In addition it actively closes the channel after the last packet has been sent.Triggered Events: –
Handled Events: –
- PassportStateHttpServerHandler
Passport maintenance to track HTTP request lifecycle events. See https://github.com/Netflix/zuul/wiki/Core-Features#request-passport.
Inbound: Tracked states:
IN_REQ_HEADERS_RECEIVEDIN_REQ_CONTENT_RECEIVEDIN_REQ_LAST_CONTENT_RECEIVED
Outbound: Tracked states:
OUT_RESP_HEADERS_SENDINGOUT_RESP_HEADERS_SENTOUT_RESP_HEADERS_ERROR_SENDINGOUT_RESP_CONTENT_SENDINGOUT_RESP_CONTENT_SENTOUT_RESP_CONTENT_ERROR_SENDINGOUT_RESP_LAST_CONTENT_SENDINGOUT_RESP_LAST_CONTENT_SENTOUT_RESP_LAST_CONTENT_ERROR_SENDING
Triggered Events: –
Handled Events:
HttpLifecycleChannelHandler.CompleteEvent: Reset channel passport
- HttpRequestReadTimeoutHandler
Fires timeout event if configured read timeout is exceeded while waiting for data of an incoming HTTP message. The handler does NOT close a timed out connection!
Sets
IN_REQ_READ_TIMEOUTstate in passport for timed out requests. Also incrementsserver.http.request.read.timeoutmonitoring counter.Inbound: Tracks time since last chunk of data was read.
Outbound: –
Triggered Events:
HttpRequestReadTimeoutEvent
Handled Events: –
- HttpServerLifecycleChannelHandler
Triggers HTTP request lifecycle events for the Zuul layer.
Inbound: Fires event as soon as an incoming HTTP request along with all headers is available.
Outbound: Fires event as soon as an HTTP response was fully sent.
Triggered Events:
com.netflix.netty.common.HttpLifecycleChannelHandler.StartEventcom.netflix.netty.common.HttpLifecycleChannelHandler.CompleteEvent
Handled Events: –
- HttpBodySizeRecordingChannelHandler
Records body sizes of HTTP requests and responses and stores them as attributes within the channel context.
Inbound: Records request body size.
Outbound: Records response body size.
Triggered Events: –
Handled Events:
HttpLifecycleChannelHandler.CompleteEvent: Resets channel context
- HttpMetricsChannelHandler
Collects monitoring metrics on the HTTP request level:
server.http.requests.currentserver.http.requests.pipelining.dropped
Inbound: –
Outbound: –
Triggered Events: –
Handled Events:
HttpServerLifecycleChannelHandler.StartEventHttpServerLifecycleChannelHandler.CompleteEventEventHttpServerLifecycleChannelHandler.RejectedPipeliningEvent
- AccessLogChannelHandler
Performs HTTP access logging for handled requests.
Inbound: Tracks start time (as soon as request headers are parsed) and request body size and stores it in channel context.
Outbound: Tracks response body size and stores it in channel context.
Triggered Events: –
Handled Events:
HttpServerLifecycleChannelHandler.CompleteEvent: Combines tracked data with other channel attributes and writes access log entry.
- StripUntrustedProxyHeadersHandler
Based on configuration removes
X-Forwarded-*headers from incoming requests.Inbound: Strips headers.
Outbound: –
Triggered Events: –
Handled Events: –
- LoggingHandler
Netty debug handler that logs any channel event according to a configured log level threshold.
Inbound: –
Outbound: –
Triggered Events: –
Handled Events: –
- ClientRequestReceiver
Converts Netty HTTP request object into a Zuul domain object and passes it further down the channel pipeline.
Inbound: As soon as an
io.netty.handler.codec.http.HttpRequestinstance is available, it is converted into acom.netflix.zuul.message.http.HttpRequestMessageinstance.Outbound: Tracks I/O errors during response writing
Triggered Events: –
Handled Events:
HttpServerLifecycleChannelHandler.CompleteEventEvent
- PassportLoggingHandler
Logs the passport (https://github.com/Netflix/zuul/wiki/Core-Features#request-passport) for completed requests. Typically this results in
DEBUGlogs. But if request or response processing took longer than a configured time, this is logged onINFOlevel.Inbound: –
Outbound: –
Triggered Events: –
Handled Events:
HttpLifecycleChannelHandler.CompleteEvent
- ZuulFilterChainHandler
This is the actual bridge between Netty events and the Zuul proxy engine.
Inbound:
com.netflix.zuul.message.http.HttpRequestMessageare taken and handed over to the Zuul request filter chain.Outbound: –
Triggered Events: –
Handled Events:
HttpLifecycleChannelHandler.CompleteEvent: Reports processing completion to proxy endpoint.HttpRequestReadTimeoutEvent: Responds with HTTP 408io.netty.handler.timeout.IdleStateEvent: Responds with HTTP 504RequestCancelledEvent: Track cancelled statusHttpLifecycleChannelHandler.RejectedPipeliningEvent: Responds with HTTP 400
- ClientResponseWriter
Reacts to Zuul HTTP responses passed along the channel pipeline and converts them into Netty domain objects.
Inbound: If the Zuul proxy engine is done with a request and has a response ready in the form of
com.netflix.zuul.message.http.HttpResponseMessage, it is actually passed along the Netty channel pipeline as a read event. This handler converts those instances intoio.netty.handler.codec.http.HttpResponseinstances. It then effectively interrupts the read handler chain for this request and instead initiates the write handler chain by writing the Netty HTTP response object onto it.Outbound: –
Triggered Events: –
Handled Events:
HttpServerLifecycleChannelHandler.StartEventHttpServerLifecycleChannelHandler.CompleteEventEvent: If the channel is to be closed because of aConnection: closeresponse header, this handler does so. Otherwise it restarts the read handler chain on this channel to process the next request.
- ServerStatusHeaderHandler
Does nothing currently.
- Http1ConnectionExpiryHandler
Tracks the number of requests per channel so that it can be marked as closed and be effectively closed by
Http1ConnectionCloseHandlerandClientResponseWriter.Inbound: –
Outbound: Marks channel to be closed if max. number of requests per channel was reached.
Triggered Events: –
Handled Events: –
HTTP Request Handling¶
Any HTTP request that successfully passed the inbound channel handlers is finally available as a com.netflix.zuul.message.http.HttpRequestMessage object. This object is passed on to the Zuul request filter chain, where it is handled. Handling means, the request is either forwarded (“proxied”) to an origin server or handled by an endpoint filter directly. In any case it leads to the creation of an com.netflix.zuul.message.http.HttpResponseMessage object, which is then passed forward to the server channel outbound handlers.

App Suite Proxy Engine¶
TODO
Client Request Processing¶
This section describes, how HTTP requests are
transformed and forwarded to an origin server and its response then transformed and written to the client or
handled by App Suite Proxy directly, resulting in a generated HTTP response