强制 OkHttp3 将完整的 URI(包括路径)传递给 ProxySelector

Force OkHttp3 to pass full URI (including path) to ProxySelector

我正在开发一个需要根据 URI 路径切换代理以达到限速目的的应用程序。不同的 api 路径具有不同的调用权重。我们正在使用 ProxySelector 并通过构建器将其传递给 OkHttpClient 实例。问题是,当 OkHttpClient 调用 ProxySelector#select(URI) 时,URI 不包含路径,仅包含主机。

    @Override
    public List<Proxy> select(URI uri) {
        final String path = uri.getPath();
        final Proxy proxy = //proxy selection code based on URI path
        return List.of(proxy);
    }

例如,如果完整的 URI 为 https://example.com/some/path,则在上例中调用 uri.getPath() 时,它 returns 仅 /。看起来 OkHttpClient 在将路径传递给 ProxySelector#select(URI).

之前在内部剥离了路径

是否可以 configure/force OkHttpClient 在调用 ProxySelector 时传递完整的请求 URI(包括路径)?

如果不增强 OkHttp,这是不可能的。这里一般有两个问题。

1) OkHttp 没有使用原来的 URL,而是在 Address

中重建它
this.url = new HttpUrl.Builder()
    .scheme(sslSocketFactory != null ? "https" : "http")
    .host(uriHost)
    .port(uriPort)
    .build();

2) 即使我们没有在这里这样做,OkHttp 也遵循连接合并规则(如 Firefox、Chrome、Safari),特别是在 HTTP/2 上启用高效多路复用。所以这意味着即使原始请求使用它,对不同路径的第二个请求也会重用现有连接。

客户端负载平衡有一个未解决的问题,所以也许可以在那里解释你的要求https://github.com/square/okhttp/issues/4530

使用现有代码,最好的办法是拥有两个不同的客户端并在它们之间进行外部切换。您应该能够使用 Retrofit CallFactory 来进行此轨道切换。