java.lang.IllegalArgumentException: wsHandshakeRequest.unknownScheme

文章讲述了在SpringBoot项目中使用WebSocket时,从Nginx转发到SpringGateway再转发至服务过程中遇到的IllegaArgumentException,原因在于X-Forwarded-Proto头导致的非法Scheme。解决方法包括检查并调整Nginx配置,升级Tomcat版本以及理解Forwarded头的作用。

记一次springboot项目websocket 从nginx转发到springgateway转发具体服务中产生的问题

1.错误日志

错误日志如下:

nested exception is java.lang.IllegalArgumentException: wsHandshakeRequest.unknownScheme] with root cause
java.lang.IllegalArgumentException: wsHandshakeRequest.unknownScheme

atorg.apache.tomcat.websocket.server.WsHandshakeRequest.buildRequestUri(WsHandshakeRequest.java:164) ~[tomcat-embed-websocket-9.0.38.jar!/:9.0.38]
 

2.问题解决:

1. 首先在代码中打印你的Scheme

HttpServletRequest request2 = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String scheme = request2.getScheme();

如果是打印出来可能是 http,http 或者 http,http, 如果是这样的话直接去看nginx上的日志是否含有

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-proto $scheme;

如果有的话去掉就可以了,在打印Scheme就会是正常的 http 。其实去掉X-Forwarded-proto这个配置就可以 这个是在nginx上解决的。如果在网关解决需要对forwarded做一些处理,暂时没有好的办法。

2.如果不行升级org.apache.tomcat.embed版本到9.0.38

以下是版本对比

3.问题排查思路:

其中走了不少的错路,就按照最后也是最顺利的方式来吧。

1.错误提示scheme是非法字符,那么打印出scheme是  http,http 
2.根据错误日志进源码tomcat-embed-websocket查看WsHandshakeRequest逻辑:

明显是因为scheme不符合规范导致的错误提示。

3.根据打印请求头里里面的具体参数发现wsHandshakeRequest.的Scheme是根据

x-forwarded-proto 来的

4.排查项目中配置发现nginx在转发中添加了

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-proto $scheme;

这就导致在请求头中的Forwarded相关值增添了,去掉这两个配置就成功了,websocket连接成功。

5.其中也查阅了tomcat的版本,发现9.0.38以后对协议判断做了优化

4.相关资料讲解

X-Forwarded-Proto (XFP) ,用来确定客户端与代理服务器或者负载均衡服务器之间的连接所采用的传输协议(HTTP 或 HTTPS)。在服务器的访问日志中记录的是负载均衡服务器与服务器之间的连接所使用的传输协议,而非客户端与负载均衡服务器之间所使用的协议。为了确定客户端与负载均衡服务器之间所使用的协议, X-Forwarded-Proto 就派上了用场。 记录协议。

X-Forwarded-For (XFF) 在客户端访问服务器的过程中如果需要经过HTTP代理或者负载均衡服务器 。简单来说记录服务经过的ip地址。


对Forwarded的解释

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值