[short-note] Spring Webflux: Webclient SOCKS5 Proxy setting with Auth(ID/PW)

2023. 2. 6. 23:13Dev/Java

0. Introduction

Spring Webflux 에서 Netty Webclient 로 외부 Proxy 를 사용하고자 할때 (reactor.netty.http.client) HttpClient 에 Proxy 관련 설정을 한다. 일반적인 HTTP Proxy type 은 많은 예제가 있지만 SOCKS 에 인증용 ID/PW를 해야 하는 경우에 대한 예제는 마땅한 것이 없어 보인다. 

 

이 글은 나의 삽질에 대한 기록.

 

 

 

 

1. Case

  • 기존에 사용하던 RestTemplate 은 deprecate 될 예정이라 다른 webclient 가 필요한 상황.
  • Request 마다 다르게 써야 하는 Proxy 설정 (전역 설정 사용 지양)
    • Proxy Type, Host, Port, Auth

 

 

 

2. Before - Bug

주의 : {some-message} 는 실제 코드가 아닌 의미만을 전달하기 위함
// ConnectionProvider 코드 생략

HttpClient httpClient = HttpClient.create(connectionProvider);
if ({Proxy Type == SOCKS5?}) {
    final String id = "Proxy-auth-ID";
    final String pw = "Proxy-auth-PW";
    httpClient.proxy(proxy -> proxy.type(ProxyProvider.Proxy.SOCKS5)
            .host({Proxy-Host})
            .port({Proxy-Port})
            .username(id)
            .password(u -> pw)
    );
} else {
    httpClient.proxy(proxy -> proxy.type(ProxyProvider.Proxy.HTTP)
            .host({Proxy-Host})
            .port({Proxy-Port})
    );
}

이렇게 세팅된 Httpclient 는 ReactorClientHttpConnector 에게 파라미터로 넘겨지고, 이는 다시 WebClient.builder() 의 clientConnector() 에게 넘겨저 최종적으로 build() 하게 된다.

 

BUG : 이 설정으로는 WebClient 가 동작은 되지만 proxy 가 동작하지 않는다. proxy 정보가 전혀 설정되지 않은채로 호출이 되고 있었다. (나는 proxy 서버의 접근 권한이 없어서 proxy 서버의 로그를 확인하지 못했다)

 

 

 

3. After - Fixed

// ConnectionProvider 코드 생략

HttpClient httpClient;
if ({Proxy Type == SOCKS5?}) {
    final String id = "Proxy-auth-ID";
    final String pw = "Proxy-auth-PW";
    
    // fix
    httpClient = HttpClient.create(this.connectionProvider)
            .proxy(proxy -> proxy.type(ProxyProvider.Proxy.SOCKS5)
            .host({Proxy-Host})
            .port({Proxy-Port})
            .username(id)
            .password(u -> pw)
    );
} else {

    // fix
    httpClient = HttpClient.create(this.connectionProvider)
            .proxy(proxy -> proxy.type(ProxyProvider.Proxy.HTTP)
            .host({Proxy-Host})
            .port({Proxy-Port})
    );
}

 

이제 Proxy 를 통해서 잘 작동한다. 이 원인에 대해서는 다른 포스팅에서 좀 더 시간을 들여서 분석하기로 하자.