2012-05-24 16 views
4

我正在通過點擊http和https鏈接的混合來測試HttpClient 4.2。HTTPClient無法建立https和http之間的路由

HttpClient似乎堅持從第一次調用的協議。如果第一個電話是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:無法建立路由:計劃= {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; 
     } 
    } 
} 

回答

3

HttpClient應該能夠絕對透明地管理連接給用戶。這個問題可能是由4.2版本(see HTTPCLIENT-1193)中引入的迴歸引起的。

使用PoolingConnectionManager或SingleConnectionManager代替默認版本,直到4.2.1版本發佈。

+0

謝謝@oleg。該問題很好地匹配了票據(從http到https的重定向,或者在同一個域中反向)。我嘗試使用PoolingClientConnectionManager,但它仍然拋出相同的錯誤。當它被釋放時,我會嘗試4.2.1。 –

0

您正試圖使用​​一個連接與多個不同的站點進行通信。 AFAIR您必須爲每個獨特的網站創建新的連接(==新客戶端)。

+0

謝謝,Germann。你是對的,這實際上與http或https無關。我認爲第三個調用是成功的,因爲第二個調用的失敗會以某種方式重置httpclient。當一個頁面將https請求重定向到同一個域中的http時,我最初遇到了錯誤類型。有沒有優雅的方式來檢測它,然後用一個新的連接(一個新的httpclient)連接到http請求? –