Spring Cloud Gateway代理WebSocket因大小写敏感Header连接失败如何解决
Spring Cloud Gateway 代理WebSocket请求头大小写问题解决方案
问题根因为Spring Cloud Gateway底层Netty默认将HTTP请求头转为小写,不符合第三方WebSocket服务对Upgrade、Connection头名称的大小写严格校验要求,可通过以下步骤修复:
步骤1:修改application.yml配置
在原有配置的spring.cloud.gateway.httpclient节点下新增头大小写敏感与校验关闭配置,修改后对应配置段如下:
spring: cloud: gateway: httpclient: pool: max-idle-time: 10s # 新增以下配置 headers: case-sensitive: true validate-headers: false
步骤2:添加自定义请求头重写过滤器
新增全局过滤器,识别WebSocket握手请求后替换小写头为大写标准格式:
import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; @Component public class WebSocketHeaderCaseFixFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); // 仅处理WebSocket握手请求 if (!"websocket".equalsIgnoreCase(request.getHeaders().getUpgrade())) { return chain.filter(exchange); } ServerHttpRequest modifiedRequest = request.mutate() .headers(httpHeaders -> { // 移除原有小写头 httpHeaders.remove("upgrade"); httpHeaders.remove("connection"); }) // 新增大写格式要求的头 .header("Upgrade", "websocket") .header("Connection", "Upgrade") .build(); return chain.filter(exchange.mutate().request(modifiedRequest).build()); } @Override public int getOrder() { // 优先级高于内置WebSocket转发过滤器 return -1; } }
可选兼容配置(低版本SCG适用)
如果上述配置不生效,可新增HttpClient自定义配置Bean强制开启大小写敏感:
import org.springframework.cloud.gateway.config.HttpClientCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import reactor.netty.http.client.HttpClient; @Configuration public class HttpClientCustomConfig { @Bean public HttpClientCustomizer headerCaseCustomizer() { return httpClient -> httpClient .headers(headers -> headers.caseSensitive(true)) .validateHeaders(false); } }
配置完成后重启服务即可正常握手连接第三方WebSocket服务。
内容的提问来源于stack exchange,提问作者Jerry
相关产品推荐
相关产品推荐

