HTTPClient 无法在 https 和 http 之间建立路由

标签 httpclient routes

我正在通过混合使用 http 和 https 链接来测试 HttpClient 4.2。

HttpClient 似乎坚持使用第一次调用的协议(protocol)。如果第一个调用是 http,那么所有后续的 https 调用都会失败,但 http 调用很好。反之亦然。

这是我使用的测试代码。

@Test
public void testNoRedirectMixed() throws ClientProtocolException, IOException {
    HttpClient httpclient = new DefaultHttpClient();
    httpclient=WebClientDevWrapper.wrapClient(httpclient);
    HttpClientParams.setRedirecting(httpclient.getParams(), false);

    {
    HttpGet httpget = new HttpGet("http://www.hotmail.com");
    HttpResponse response = httpclient.execute(httpget);
    HttpEntity entity = response.getEntity();
    assertTrue(EntityUtils.toString(entity).indexOf("com")>0);
    }

    try {
    HttpGet httpget = new HttpGet("https://www.hotmail.com");
    HttpResponse response = httpclient.execute(httpget);
    HttpEntity entity = response.getEntity();

    }catch (Exception e) {
        e.printStackTrace();
    }

    {
    HttpGet httpget = new HttpGet("http://www.baidu.com");
    HttpResponse response = httpclient.execute(httpget);
    HttpEntity entity = response.getEntity();
    assertTrue(EntityUtils.toString(entity).indexOf("com")>0);
    }
}

第二个请求(https)会失败,但是百度请求没问题。

原因:org.apache.http.HttpException:无法建立路由:planned = {s}-> https://www.hotmail.com ;当前 = {s}-> http://www.hotmail.com
在 org.apache.http.impl.client.DefaultRequestDirector.establishRoute(DefaultRequestDirector.java:842)

我还必须禁用重定向,因为 hotmail 重定向请求:http://www.hotmail.com -> https://www.hotmail.comhttps://www.hotmail.com -> https://www.live.com .在任何一种情况下都会引发类似的错误。

包装器如下所示。它用于接受所有证书。
public class WebClientDevWrapper {

    public static HttpClient wrapClient(HttpClient base) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {

                public void checkClientTrusted(X509Certificate[] xcs,
                        String string) throws CertificateException {
                }

                public void checkServerTrusted(X509Certificate[] xcs,
                        String string) throws CertificateException {
                }

                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[]{};
                }
            };
            ctx.init(null, new TrustManager[] { tm }, null);
            SSLSocketFactory ssf = new SSLSocketFactory(ctx);
                ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            ClientConnectionManager ccm = base.getConnectionManager();
            SchemeRegistry sr = ccm.getSchemeRegistry();
            sr.register(new Scheme("https", ssf, 443));
            DefaultHttpClient client= new DefaultHttpClient(ccm, base.getParams());
            return client;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }
}

最佳答案

HttpClient 应该能够对用户绝对透明地管理连接。此问题可能是由 4.2 版本 (see HTTPCLIENT-1193) 中引入的回归引起的。

在 4.2.1 版本发布之前,使用 PoolingConnectionManager 或 SingleConnectionManager 而不是默认的。

关于HTTPClient 无法在 https 和 http 之间建立路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10735586/

相关文章:

Apache HTTP 客户端只有两个连接是可能的

javascript - 快速将 POST 重定向到具有相同 URL 的 PUT

c# - 使用 Mock HttpClient 进行 Mock Refit SDK 注入(inject)以进行集成测试

Facebook 的 Qt 客户端

ruby-on-rails - 处理 "composed classes"

ruby-on-rails - 如何处理自定义 url 中的大写和小写字符?

c# - 通过更改 Razor 中的 url 获取 View

javascript - 不显示 AngularJS View

java - 从 http 客户端获取 404

go - go http.Client 的 DialContext KeepAlive 和 Transport IdleTimeout 的区别