4

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.

enter image description here

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.

Md. Hasan Basri
  • 159
  • 1
  • 15
  • 1
    Possible duplicate of [How can I support an HTTP Proxy using Spring 5 WebClient?](https://stackoverflow.com/questions/46979982/how-can-i-support-an-http-proxy-using-spring-5-webclient) – isank-a Oct 09 '19 at 07:36
  • @Isank Thanks you, today I modified the content a bit and tried to clarify my question a bit detail way mentioning some references. – Md. Hasan Basri Oct 10 '19 at 02:37
  • The quick answer is no. https://github.com/reactor/reactor-netty/issues/159 – Violeta Georgieva Oct 11 '19 at 10:12

1 Answers1

0

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();
SharifS
  • 80
  • 2
  • 10