public Duration computeReadTimeout(HttpRequestMessage request, int attemptNum) {
        IClientConfig clientConfig = getRequestClientConfig(request);
        Long originTimeout = getOriginReadTimeout();
        Long requestTimeout = getRequestReadTimeout(clientConfig);

        long computedTimeout;
        if (originTimeout == null && requestTimeout == null) {
            computedTimeout = MAX_OUTBOUND_READ_TIMEOUT_MS.get();
        } else if (originTimeout == null || requestTimeout == null) {
            computedTimeout = originTimeout == null ? requestTimeout : originTimeout;
        } else {
            // return the stricter (i.e. lower) of the two timeouts
            computedTimeout = Math.min(originTimeout, requestTimeout);
        }

        // enforce max timeout upperbound
        return Duration.ofMillis(Math.min(computedTimeout, MAX_OUTBOUND_READ_TIMEOUT_MS.get()));
    }
Derives the read timeout from the configuration.  This implementation prefers the longer of either the origin
timeout or the request timeout.
<p>
This method can also be used to validate timeout and deadline boundaries and throw exceptions as needed. If
extending this method to do validation, you should extend {@link com.netflix.zuul.exception.OutboundException}
and set the appropriate {@link com.netflix.zuul.exception.ErrorType}.

@param request    the request.
@param attemptNum the attempt number, starting at 1.
zuul-core/src/main/java/com/netflix/zuul/netty/timeouts/OriginTimeoutManager.java