Spring Cloud Gateway をエッジ サーバーとして使用しています。これが流れです
リクエストに「x-foo」という名前のヘッダーがある場合は、ヘッダー値を見つけて、別のサーバーから文字列を取得し、実際にリクエストをプロキシする代わりに、その文字列を応答として送信します。
Filter DSL のコードは次のとおりです。
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("foo-filter", r -> r.header('x-foo').and().header("x-intercepted").negate()
.filters(f -> f.filter(fooFilter))
.uri("http://localhost:8081")) // 8081 is self port, there are other proxy related configurations too
.build();
}
Foo フィルターのコード
@Component
@Slf4j
public class FooFilter implements GatewayFilter {
@Autowired
private ReactiveRedisOperations<String, String> redisOps;
@Value("${header-name}")
private String headerName;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
var foo = request.getHeaders().getFirst(headerName);
return redisOps.opsForHash()
.get("foo:" + foo, "response")
.doOnSuccess(s -> {
log.info("data on success");
log.info(s.toString()); // I am getting proper response here
if (s != null) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.OK);
response.getHeaders().set("x-intercepted", "true");
byte[] bytes = s.toString().getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory().wrap(bytes);
response.writeWith(Mono.just(buffer));
response.setComplete();
}
})
.then(chain.filter(exchange));
}
}
問題は、応答に適切な 200 コードが返され、挿入されたヘッダーが応答に存在するが、応答でデータが利用できないことです。