Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable protocol upgrades for eureka client and server HTTP clients #4391

Open
mamachanko opened this issue Dec 12, 2024 · 2 comments
Open
Assignees

Comments

@mamachanko
Copy link

mamachanko commented Dec 12, 2024

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 -
@mamachanko
Copy link
Author

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.

@OlgaMaciaszek
Copy link
Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants