private static FullHttpResponse createRejectionResponse(
            HttpResponseStatus status,
            String plaintextMessage,
            boolean closeConnection,
            Map<String, String> rejectionHeaders) {
        ByteBuf body = Unpooled.wrappedBuffer(plaintextMessage.getBytes(StandardCharsets.UTF_8));
        int length = body.readableBytes();
        DefaultHttpHeaders headers = new DefaultHttpHeaders();
        headers.set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=utf-8");
        headers.set(HttpHeaderNames.CONTENT_LENGTH, length);
        if (closeConnection) {
            headers.set(HttpHeaderNames.CONNECTION, "close");
        }
        rejectionHeaders.forEach(headers::add);

        return new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, body, headers, EmptyHttpHeaders.INSTANCE);
    }
Switches on the rejection type to decide how to reject the request and or close the conn.

@param ctx                   the channel handler processing the request
@param rejectionType         the type of rejection
@param nfStatus              the status to use for metric reporting
@param reason                the reason for rejecting the request.  This is not sent back to the client.
@param request               the request that is being rejected.
@param injectedLatencyMillis optional parameter to delay sending a response. The reject notification is still
                             sent up the pipeline.
@param rejectedCode          the HTTP code to send back to the client.
@param rejectedBody          the HTTP body to be sent back.  It is assumed to be of type text/plain.
@param rejectionHeaders      additional HTTP headers to add to the rejection response
zuul-core/src/main/java/com/netflix/netty/common/throttle/RejectionUtils.java