RestTemplate… Host Header…

Circlee7
4 min readMar 29, 2018

--

spring 의 RestTemplate 을 통해 Proxy 처럼 기능을 개발할 요건이 생겼다.

클라이언트로 부터 들어온 Request 의 모든 것들을 , 타깃 서버로 넘겨버린다.

Request의 Header, Body, queryString, Method…

그런데 타깃 서버쪽에서는 Request 로 부터 넘어온 Host 헤더를 확인하여
허용된 Host 요청인지를 확인한다.

내 생각은 Proxy 역할을 하고 있는 내 쪽에서 타깃서버로 보내는 Request의
Host 헤더를 타깃서버에 맞게 변경하지 않았으니 에러가 나겠구나 라고 생각했다.

하지만 에러는 나지 않았다.
타깃 서버쪽 request log 를 보니 , 타깃 서버에 맞게끔 host 헤더가 설정되어 들어오고 있었다.

나는.. 아무것도 안했는데…

왜 그럴까. .

RestTemplate restTemplate = new RestTemplate();

RequstFactory를 생성자 인자로 넘기지 않고 인스턴스를 생성하면
RestTemplate은 default 로 SimpleClientHttpRequestFactory 를 사용한다.

이 SimpleClientHttpRequestFactory는 java.net.UrlConnection을 구현한
sun.net.www.protocol.http.HttpURLConnection
sun.net.www.protocol.https.HttpsURLConnection
… 등을 사용한다.

HttpURLConnection 은 아래와 같이 헤더에 대한 제한을 두고 있다.

private static final boolean allowRestrictedHeaders;
private static final Set<String> restrictedHeaderSet;
private static final String[] restrictedHeaders = { /* Restricted by XMLHttpRequest2 */ //”Accept-Charset”, //”Accept-Encoding”, “Access-Control-Request-Headers”, “Access-Control-Request-Method”, “Connection”, /* close is allowed */ “Content-Length”, //”Cookie”, //”Cookie2", “Content-Transfer-Encoding”, //”Date”, //”Expect”, “Host”, “Keep-Alive”, “Origin”, // “Referer”, // “TE”, “Trailer”, “Transfer-Encoding”, “Upgrade”, //”User-Agent”, “Via” };

restricedHeaders 에 있는 헤더들은 수정할 수 없다.

Host 헤더는 request url로 부터 참조되어 셋팅된다.

하지만 아래와 같은 자바시스템 변수를 정의 하면 수정되어진다.

-Dsun.net.http.allowRestrictedHeaders=true

다른 RequestFactory도 마찬가지 일까? 라는 생각에 찾아보니.

많이들 사용하는 HttpComponentsClientHttpRequestFactory 는 다르다.

apache package로 SimpleClientHttpRequestFactory와는 다른 HttpClient http라이브러리를 사용하고 있다.

오히려 이쪽은 자유도가 높기 때문에. 위에서 말한 Proxy기능을 개발할때는 Host헤더를 정의 해줘야 제대로 동작하겠다.

--

--