You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java标准库SocksSocketImpl是否存在IPv6相关BUG?

Spring Boot关闭嵌入式Tomcat时发现JDK SocksSocketImpl的IPv6 URI解析问题

我在Spring Boot应用中调用TomcatWebServer#stop()关闭嵌入式Tomcat的过程中,捕获到一个被抑制的URISyntaxException。经调试定位,问题出在JDK的SocksSocketImpl类代码中(我使用的是Eclipse Temurin 17.0.8.1,测试其他Java版本后发现逻辑基本一致)。

在IPv6场景下,这段代码的处理逻辑存在问题:

  • epoint.getHostString()返回不带括号的合法IPv6地址(例如fd00:baba:babe:0:0:0:0:862)
  • 后续代码检测到这是IPv6地址,自动添加括号,变为[fd00:baba:babe:0:0:0:0:862]
  • ParseUtil.encodePath(host)将该带括号的主机名编码为%5bfd00:baba:babe:0:0:0:0:862%5d,这一步本身不会引发异常,但会导致后续URI解析无法区分主机名和端口
  • 编码后的内容与协议、端口拼接后,得到类似socket://%5bfd00:baba:babe:0:0:0:0:862%5d:55507的字符串,进一步加大了解析难度
  • 调用new URI构造方法时,会把编码后的主机名和端口合并为authority,最终导致uri.getHost() == null且uri.getPort() == -1

要让new URI正确解析IPv6主机,必须传入未编码且带有必填字面括号的IPv6地址,也就是[fd00:baba:babe:0:0:0:0:862]这种形式。

以下是简单的复现案例:

URI uri = new URI("socket://[fd00:baba:babe:0:0:0:0:862]:55507");
System.out.println(uri.getHost()); // 输出[fd00:a89f:8b41:0:0:0:0:862] - 正常解析
uri = new URI("socket://%5bfd00:baba:babe:0:0:0:0:862%5d:55507");
System.out.println(uri.getHost()); // 输出null - port为-1,所有内容合并到authority
uri = new URI("socket://fd00:baba:babe:0:0:0:0:862:55507");
System.out.println(uri.getHost()); // 输出null - port为-1,所有内容合并到authority

我原本以为host == null会导致SocksSocketImpl后续逻辑崩溃,但意外发现,唯一实际使用该URI的地方是调用DefaultProxySelector#select(URI uri),而这里有个针对国际化域名和含下划线域名的老旧临时规避方案——尽管注释明确说明该方案不适用于当前场景,但它恰好让代码没有崩溃。

想问的是:这到底是我忽略了什么明显的细节,还是这确实是JDK标准库中堆叠出来的BUG,需要向上游反馈?

内容的提问来源于stack exchange,提问作者user213769

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 17:07:45