Architecture/MSA

Spring Cloud Gateway - HttpHeadersFilters

체리필터 2021. 1. 7. 09:11
728x90
반응형

ForwardedHeadersFilter

from의 헤더를 to 로 복사해서 보내주는 역할을 하는 것으로 보인다.

package org.springframework.cloud.gateway.filter.headers;

public class ForwardedHeadersFilter implements HttpHeadersFilter, Ordered {

	/**
	 * Forwarded header.
	 */
	public static final String FORWARDED_HEADER = "Forwarded";
    
    ...
    
    @Override
	public HttpHeaders filter(HttpHeaders input, ServerWebExchange exchange) {
		ServerHttpRequest request = exchange.getRequest();
		HttpHeaders original = input;
		HttpHeaders updated = new HttpHeaders();

		// copy all headers except Forwarded
		original.entrySet().stream().filter(
				entry -> !entry.getKey().toLowerCase().equalsIgnoreCase(FORWARDED_HEADER))
				.forEach(entry -> updated.addAll(entry.getKey(), entry.getValue()));

		List<Forwarded> forwardeds = parse(original.get(FORWARDED_HEADER));

		for (Forwarded f : forwardeds) {
			updated.add(FORWARDED_HEADER, f.toHeaderValue());
		}

		// TODO: add new forwarded
		URI uri = request.getURI();
		String host = original.getFirst(HttpHeaders.HOST);
		Forwarded forwarded = new Forwarded().put("host", host).put("proto",
				uri.getScheme());

		InetSocketAddress remoteAddress = request.getRemoteAddress();
		if (remoteAddress != null) {
			// If remoteAddress is unresolved, calling getHostAddress() would cause a
			// NullPointerException.
			String forValue = remoteAddress.isUnresolved() ? remoteAddress.getHostName()
					: remoteAddress.getAddress().getHostAddress();
			int port = remoteAddress.getPort();
			if (port >= 0) {
				forValue = forValue + ":" + port;
			}
			forwarded.put("for", forValue);
		}
		// TODO: support by?

		updated.add(FORWARDED_HEADER, forwarded.toHeaderValue());

		return updated;
	}
}

 

RemoveHopByHopHeadersFilter

특정 헤더를 삭제한다. HEADERS_REMOVED_ON_REQUEST 값에 삭제할 내용이 정의 되어 있다. 해당 값을 변경하고 싶으면 Annotation에 있는 것 처럼 spring.cloud.gateway.filter.remove-hop-by-hop.headers 에 값을 셋팅하면 된다.

package org.springframework.cloud.gateway.filter.headers;

@ConfigurationProperties("spring.cloud.gateway.filter.remove-hop-by-hop")
public class RemoveHopByHopHeadersFilter implements HttpHeadersFilter, Ordered {

	/**
	 * Headers to remove as the result of applying the filter.
	 */
	public static final Set<String> HEADERS_REMOVED_ON_REQUEST = new HashSet<>(
			Arrays.asList("connection", "keep-alive", "transfer-encoding", "te",
					"trailer", "proxy-authorization", "proxy-authenticate",
					"x-application-context", "upgrade"
			// these two are not listed in
			// https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-14#section-7.1.3
			// "proxy-connection",
			// "content-length",
			));

    ...
    
	@Override
	public HttpHeaders filter(HttpHeaders input, ServerWebExchange exchange) {
		HttpHeaders filtered = new HttpHeaders();

		input.entrySet().stream()
				.filter(entry -> !this.headers.contains(entry.getKey().toLowerCase()))
				.forEach(entry -> filtered.addAll(entry.getKey(), entry.getValue()));

		return filtered;
	}
}

hop-by-hop Header가 무엇인지 몰라 찾아 보니 다음과 같이 나온다. ( developer.mozilla.org/ko/docs/Web/HTTP/Connection_management_in_HTTP_1.x )

명심해야 할 중요한 점은 HTTP 내 커넥션 관리가 end-to-end가 아닌 hop-by-hop인 두 개의 연속된 노드 사이의 커넥션에 적용된다는 것입니다. 클라이언트와 첫 번째 프록시 사이의 커넥션 모델은 프록시와 최종 목적 서버(혹은 중간 프록시들) 간의 것과는 다를 수도 있습니다. 
Connection와 Keep-Alive와 같이 커넥션 모델을 정의하는 데 관여하는 HTTP 헤더들은 hop-by-hop 헤더이며, 중간 노드에 의해 그 값들이 변경될 수 있습니다.

 

XForwardedHeadersFilter

관련 소스는 package org.springframework.cloud.gateway.filter.headers; 안에 XForwardedHeadersFilter.java 파일이다.

X-Forwarded-* 로 시작하는 헤더를 콘트롤 할 수 있다. 각각의 헤더는 다음 정보의 boolean 값으로 만들 수 있다. (기본은 true)

  • spring.cloud.gateway.x-forwarded.for-enabled
  • spring.cloud.gateway.x-forwarded.host-enabled
  • spring.cloud.gateway.x-forwarded.port-enabled
  • spring.cloud.gateway.x-forwarded.proto-enabled
  • spring.cloud.gateway.x-forwarded.prefix-enabled

appending multiple header는 다음 정보의 boolean 값으로 만들 수 있다. (기본은 true)

  • spring.cloud.gateway.x-forwarded.for-append
  • spring.cloud.gateway.x-forwarded.host-append
  • spring.cloud.gateway.x-forwarded.port-append
  • spring.cloud.gateway.x-forwarded.proto-append
  • spring.cloud.gateway.x-forwarded.prefix-append

 

 

728x90
반응형