0

I'm trying to configure an HTTP proxy (without CONNECT tunnelling support) for my Spring WebFlux WebClients (based on Netty HttpClient) but without success (403 HTTP status code).

As explained in the documentation:

Netty’s HTTP proxy support always uses CONNECT method in order to establish a tunnel to the specified proxy regardless of the scheme that is used http or https. (More information: Netty enforce HTTP proxy to support HTTP CONNECT method). Some proxies might not support CONNECT method when the scheme is http or might need to be configured in order to support this way of communication. Sometimes this might be the reason for not being able to connect to the proxy. Consider checking the proxy documentation whether it supports or needs an additional configuration in order to support CONNECT method.

I'm using Spring Boot WebFlux 3.5.4 and this is my configuration:

import io.netty.resolver.DefaultAddressResolverGroup;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import reactor.netty.http.client.HttpClient;
import reactor.netty.transport.ProxyProvider;

@Data
@Configuration
@ConfigurationProperties(prefix = "proxy")
public class ProxyConfiguration {
    private boolean enabled = false;
    private HttpProxy http = new HttpProxy();

    @Data
    public static class HttpProxy {
        private String host = "localhost";
        private Integer port = 8080;
        private String noProxy = "localhost|127.0.0.1";

        private HttpProxyAuthentication authentication = new HttpProxyAuthentication();

        @Data
        public static class HttpProxyAuthentication {
            private boolean enabled = false;
            private String username;
            private String password;
        }
    }

    @Bean
    @Primary
    public HttpClient httpClient() {
        HttpClient httpClient = HttpClient.create().resolver(DefaultAddressResolverGroup.INSTANCE).followRedirect(true);

        if (this.isEnabled()) {
            httpClient = httpClient.proxy(proxy -> {
                ProxyProvider.Builder builder = proxy.type(ProxyProvider.Proxy.HTTP)
                        .host(this.getHttp().getHost())
                        .port(this.getHttp().getPort())
                        .nonProxyHosts(this.getHttp().getNoProxy());

                // Add authentication if enabled
                if (this.getHttp().getAuthentication().isEnabled() &&
                        this.getHttp().getAuthentication().getUsername() != null &&
                        this.getHttp().getAuthentication().getPassword() != null) {
                    builder.username(this.getHttp().getAuthentication().getUsername())
                            .password(ignored -> this.getHttp().getAuthentication().getPassword());
                }
            });
        } else {
            httpClient = httpClient.proxyWithSystemProperties();
        }

        return httpClient;
    }
}

@Bean
public WebClient eebClient(HttpClient httpClient) {
    return WebClient.builder()
            .baseUrl(BASE_URL)
            .clientConnector(new ReactorClientHttpConnector(httpClient))
            .build();
}

What options do I have to bypass this Netty HttpClient limitation and use HTTP proxy without CONNECT tunnelling support? Switching from Netty to Jetty HttpClient or other alternatives is also OK, as long as they are supported by the Spring WebClient interface.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.