Is your feature request related to a problem? Please describe.

I would like to disable protocol upgrades for Eureka client and server HTTP client, because with Spring Boot 3.4.0 ...

Apache HTTP Components have changed defaults in the HttpClient relating to HTTP/1.1 TLS upgrades. Most proxy servers handle upgrades without issue, however, you may encounter issues with Envoy or Istio.

There's a workaround suggested. However, providing a custom HttpComponentsClientHttpRequestFactoryBuilder bean does not affect Eureka's client and server HTTP clients. Afaik that's because they do not consider that bean, but create their own.

Describe the solution you'd like

As a first step, I would love a recommendation for how to customize Eureka server and client HTTP clients to disable protocol upgrades. Eventually, maybe in future versions, it would be great if there was a property one could set.

Describe alternatives you've considered

I have tried to provide my own EurekaClientHttpRequestFactorySupplier which is essentially a copied of the DefaultEurekaClientHttpRequestFactorySupplier with:

@Override
public ClientHttpRequestFactory get(SSLContext sslContext, @Nullable HostnameVerifier hostnameVerifier) {
    HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
    if (sslContext != null || hostnameVerifier != null || timeoutProperties != null) {
        httpClientBuilder
                .setConnectionManager(buildConnectionManager(sslContext, hostnameVerifier, timeoutProperties));
    }
    if (timeoutProperties != null) {
        httpClientBuilder.setDefaultRequestConfig(buildRequestConfig());
    }

    CloseableHttpClient httpClient = httpClientBuilder.build();

    // disable protocol upgrades
    HttpComponentsClientHttpRequestFactory requestFactory = ClientHttpRequestFactoryBuilder
            .httpComponents()
            .withDefaultRequestConfigCustomizer((builder) -> builder.setProtocolUpgradeEnabled(false))
            .build();

    requestFactory.setHttpClient(httpClient);
    return requestFactory;
}

but calls to the Eureka server still try to upgrade the protocol

Accept: application/json, application/*+json
Accept-Encoding: gzip, x-gzip, deflate
Host: localhost:8082
Connection: keep-alive
User-Agent: Apache-HttpClient/5.4.1 (Java/22)
Upgrade: TLS/1.2
Connection: Upgrade

172.17.0.1 - - [12/Dec/2024 14:24:50] "GET /eureka/apps/ HTTP/1.1" 200 -

Comment From: mamachanko

I learned that the RequestConfig allows me to change the desired behaviour. In the case of copying DefaultEurekaClientHttpRequestFactorySupplier it means updating buildRequestConfig:

private RequestConfig buildRequestConfig() {
    return RequestConfig.custom()
            // v
            .setProtocolUpgradeEnabled(false)
            // ^
            .setConnectTimeout(Timeout.of(timeoutProperties.getConnectTimeout(), TimeUnit.MILLISECONDS))
            .setConnectionRequestTimeout(
                    Timeout.of(timeoutProperties.getConnectRequestTimeout(), TimeUnit.MILLISECONDS))
            .build();
}

That's not the smartest thing to do since its involvement is conditional on timeoutProperties. But it allows me to press on a little further.

Ideally I'd find a way to inject this setting in less invasive manner.

Comment From: OlgaMaciaszek

Thanks, @mamachanko and thank you for the workaround. Will look into creating a better way of handling this.

Comment From: OlgaMaciaszek

A PR has been created to provide a RequestConfig customization mechanism. Once merged, we'll need to document how to use it to disable protocol upgrades.