public static void sendRejectionResponse(
            ChannelHandlerContext ctx,
            StatusCategory nfStatus,
            String reason,
            HttpRequest request,
            @Nullable Integer injectedLatencyMillis,
            HttpResponseStatus rejectedCode,
            String rejectedBody,
            Map<String, String> rejectionHeaders) {
        boolean shouldClose = closeConnectionAfterReject(ctx.channel());
        // Write out a rejection response message.
        FullHttpResponse response = createRejectionResponse(rejectedCode, rejectedBody, shouldClose, rejectionHeaders);

        if (injectedLatencyMillis != null && injectedLatencyMillis > 0) {
            // Delay writing the response for configured time.
            ctx.executor()
                    .schedule(
                            () -> {
                                CurrentPassport.fromChannel(ctx.channel()).add(PassportState.IN_REQ_REJECTED);
                                ctx.writeAndFlush(response);
                            },
                            injectedLatencyMillis,
                            TimeUnit.MILLISECONDS);
        } else {
            // Write the response immediately.
            CurrentPassport.fromChannel(ctx.channel()).add(PassportState.IN_REQ_REJECTED);
            ctx.writeAndFlush(response);
        }

        // Notify other handlers that we've rejected this request.
        notifyHandlers(ctx, nfStatus, rejectedCode, reason, request);
    }
Sends a rejection response back to the client, and fires a {@link RequestRejectedEvent} back up the pipeline.

@param ctx                   the channel handler processing the request
@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