'Is it possible to avoid calling CONNECT modifying HTTP proxy configuration while using WebClient?
During the migration of spring-web to spring-reactive-web, we blocked by the implementation of HTTP proxy at the WebClient builder method.
We already tried below code snippet earlier, which is referenced at How can I support an HTTP Proxy using Spring 5 WebClient?.
WebClient.Builder currentWebClient = WebClient.builder();
if (StringUtils.isNotBlank(customRequest.getConnectionMap().get(GatewayConstants.PROXY_HOST))) {
HttpClient httpClient = HttpClient.create()
.tcpConfiguration(tcpClient ->
tcpClient.proxy(proxy -> proxy.type(ProxyProvider.Proxy.HTTP).host(customRequest.getConnectionMap().get(GatewayConstants.PROXY_HOST)).port(Integer.valueOf(customRequest.getConnectionMap().get(GatewayConstants.PROXY_PORT)))));
ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
currentWebClient = currentWebClient.clientConnector(connector);
}
For the mentioned piece of code required to have TLS enabled proxy support. It try to establish a connection using HTTP-Connect method and for our case we are getting status: 403 Forbidden, as we don't have https support for now. To disable HTTPS features from httpClient I even tried noSSL() but it won't work for me,
HttpClient httpClient = HttpClient.create()
.tcpConfiguration(tcpClient ->
tcpClient
.noSSL()
...
No matter I try enabling or disabling the SSL part from HTTP client, The network activity timeline looks the same, I mean for all the cases it invokes HTTP CONNECT method when I use a proxy.
Below code looking good and help us calling API's nice but didn't find any standard way of associate HTTP_PROXY (Without HTTP CONNECT method call) configuration with it.
WebClient.Builder currentWebClient = WebClient.builder();
Mono<CustomHttpResponse> response = WebClient.builder().build()
.method(HttpMethod.GET)
.uri(url)
.exchange()
.flatMap(r -> r.bodyToMono(String.class).flatMap(b -> {
customHttpResponse.setBodyMap(convertToMap(customRequest, b));
return Mono.just(customHttpResponse);
}))
.timeout(Duration.ofMillis(10000))
.doOnRequest(r -> logger.info("BACKEND_CALL start"))
.doOnError(r -> logger.info("BACKEND_CALL ERROR"));
Here we're looking for a standard way of implementing HTTP call mechanism for
GET, POST, PUT and DELETE HTTP methods using WebClient considering domain-specific SOCKET_TIMEOUT, CONNECTION_TIMEOUT, HTTP_PROXY (Without HTTP CONNECT method call), Number of RETRY for some back-end call.
For the dependency part, the effective version for our WebClient coming from,
Gradle: org.springframework:spring-web:5.1.7.RELEASE
Please feel free to comment below if you have any further query relevant to it.
Solution 1:[1]
It seems this is still an open issue in netty.
I faced the same issue recently and found an workaround which is using jetty-reactive-httpclient as WebClient's client connector.
To use jetty-reactive-httpclient, this dependency is needed:
'org.eclipse.jetty:jetty-reactive-httpclient:1.1.11'
Then use org.eclipse.jetty.client.HttpClient instead of reactor.netty.http.client.HttpClient like below:
HttpClient httpClient = new HttpClient();
ProxyConfiguration proxyConfig = httpClient.getProxyConfiguration();
HttpProxy proxy = new HttpProxy(${proxy.host}, ${proxy.port});
proxyConfig.getProxies().add(proxy);
JettyClientHttpConnector jettyClientHttpConnector = new JettyClientHttpConnector(httpClient);
WebClient client = WebClient.builder().clientConnector(jettyClientHttpConnector).build();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | SharifS |

