private Publisher<LiveHttpResponse> sendRequest(LiveHttpRequest request, List<RemoteHost> previousOrigins, int attempt) { if (attempt >= MAX_RETRY_ATTEMPTS) { return Flux.error(new NoAvailableHostsException(this.id)); } Optional<RemoteHost> remoteHost = selectOrigin(request); if (remoteHost.isPresent()) { RemoteHost host = remoteHost.get(); List<RemoteHost> newPreviousOrigins = newArrayList(previousOrigins); newPreviousOrigins.add(remoteHost.get()); return ResponseEventListener.from(host.hostClient().handle(request, HttpInterceptorContext.create()) .map(response -> addStickySessionIdentifier(response, host.origin()))) .whenResponseError(cause -> logError(request, cause)) .whenCancelled(() -> originStatsFactory.originStats(host.origin()).requestCancelled()) .apply() .doOnNext(this::recordErrorStatusMetrics) .map(response -> removeUnexpectedResponseBody(request, response)) .map(this::removeRedundantContentLengthHeader) .onErrorResume(cause -> { RetryPolicyContext retryContext = new RetryPolicyContext(this.id, attempt + 1, cause, request, previousOrigins); return retry(request, retryContext, newPreviousOrigins, attempt + 1, cause); }) .map(response -> addOriginId(host.id(), response)); } else { RetryPolicyContext retryContext = new RetryPolicyContext(this.id, attempt + 1, null, request, previousOrigins); return retry(request, retryContext, previousOrigins, attempt + 1, new NoAvailableHostsException(this.id)); } }