某条规则将 http://reports.example:80/ 经由代理发送,却让 http://reports.example/ 直连。这两个 URL 描述的是同一个普通 HTTP 端点。不一致通常来自对解析出的端口做字面比较。

当 URI 中没有出现端口时,URI.getPort() 返回 -1。它不会按方案补上默认值。把该值与 80 比较的路由策略会漏掉第二个 URL。

String scheme = uri.getScheme();
int port = uri.getPort();
if (port == -1) {
    if ("http".equalsIgnoreCase(scheme)) port = 80;
    else if ("https".equalsIgnoreCase(scheme)) port = 443;
}

在比较的两侧应用同样的规范化。只修正请求 URI,配置的目标若省略端口仍然无法匹配。比较主机、有效端口和预期方案;通过明确的错误路径拒绝格式错误或没有主机的目标。

不要把每次回调都变成 HTTP 决策

默认选择器也可能因原始套接字连接而被咨询,使用 socket 方案。仅主机与端口匹配不应让该回调返回一个用于 URL 请求的 HTTP 代理。把不支持的方案交给先前的选择器,保留其恰当行为。

在安装自定义选择器之前,先捕获那个先前的选择器。从替代者内部查找当前默认值,可能只是再次调用替代者。

诊断不一致时,记录方案、主机、原始端口和有效端口。不要依赖跨 JDK 实现观察到的一个数字或回调顺序。策略应当对每个给定的 URI 做出正确判断。

相关文章