package ankurm.sc;

import java.net.InetSocketAddress;

import org.springframework.cloud.gateway.filter.headers.ForwardedHeadersFilter;
import org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter;
import org.springframework.http.HttpHeaders;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.web.server.MockServerWebExchange;

/**
 * Spring Cloud Gateway: what do the forwarded-header filters emit when the caller is NOT a trusted proxy and
 * has sent its own Forwarded / X-Forwarded-For headers? Run on 5.0.3 (GA) and 5.1.0-M1 (Paddington milestone).
 */
public class ForwardedDemo {

	static MockServerWebExchange exchange(String remote) {
		MockServerHttpRequest request = MockServerHttpRequest.get("http://gateway.example/orders")
			.remoteAddress(new InetSocketAddress(remote, 40000))
			.header("Forwarded", "for=198.51.100.7;proto=https")
			.header("X-Forwarded-For", "198.51.100.7")
			.header("X-Forwarded-Proto", "https")
			.build();
		return MockServerWebExchange.from(request);
	}

	static void print(String label, HttpHeaders h) {
		System.out.println(label);
		System.out.println("  Forwarded        = " + h.get("Forwarded"));
		System.out.println("  X-Forwarded-For  = " + h.get("X-Forwarded-For"));
		System.out.println("  X-Forwarded-Proto= " + h.get("X-Forwarded-Proto"));
	}

	public static void main(String[] args) {
		// Only 10.0.0.0/8 is trusted. The caller is 203.0.113.9, so its forwarded headers must not be believed.
		String trusted = "10\\..*";
		ForwardedHeadersFilter forwarded = new ForwardedHeadersFilter(trusted);
		XForwardedHeadersFilter xForwarded = new XForwardedHeadersFilter(trusted);

		MockServerWebExchange untrusted = exchange("203.0.113.9");
		print("== untrusted caller 203.0.113.9: Forwarded filter", forwarded.filter(untrusted.getRequest().getHeaders(), untrusted));
		MockServerWebExchange untrusted2 = exchange("203.0.113.9");
		print("== untrusted caller 203.0.113.9: X-Forwarded filter", xForwarded.filter(untrusted2.getRequest().getHeaders(), untrusted2));
		MockServerWebExchange ok = exchange("10.1.2.3");
		print("== trusted caller 10.1.2.3: Forwarded filter", forwarded.filter(ok.getRequest().getHeaders(), ok));
	}
}
