2017-09-20 3 views
0

Apache HTTPクライアント4.3.6およびhttpcore 4.3.3(opensaml 3.3.0にバンドルされています)を使用しています。 HTTPS経由でプロキシ経由でWebページを取得しようとしていますが、毎回SocketTimeoutExceptionが発生します。 HTTP接続は正常に動作します。特定のタイムアウトは関係ありません。より高い値で失敗するのに時間がかかります。SSLを使用するとApache HttpClientがSocketTimeoutExceptionをスローする

サンプルコード:

public class TestGet { 
    private static final int TIMEOUT = 7000; 

    public static void main(String[] args) throws Exception { 
     URL url = new URL("https://www.google.com"); 
     URL proxy = new URL("https://myproxy:9090/"); 
     try { 
      String s = get(url, proxy); 
      System.out.println(s); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    private static String get(URL url, URL proxy) throws IOException, URISyntaxException { 
     CloseableHttpClient client = HttpClients.createDefault(); 
     HttpGet    request = new HttpGet(url.toURI()); 
     HttpHost   host = null; 

     if (proxy != null) { 
      host = new HttpHost(proxy.getHost(), proxy.getPort(), proxy.getProtocol()); 
     } 

     RequestConfig config = RequestConfig.custom() 
      .setProxy(host) 
      .setConnectionRequestTimeout(TIMEOUT) 
      .setConnectTimeout(TIMEOUT) 
      .setSocketTimeout(TIMEOUT) 
      .build(); 
     request.setConfig(config); 

     try { 
      CloseableHttpResponse response = client.execute(request); 
      try { 
       System.out.println(response.getStatusLine()); 
       return EntityUtils.toString(response.getEntity()); 
      } finally { 
       response.close(); 
      } 
     } finally { 
      client.close(); 
     } 
    } 
} 

プロキシに接続しようとすると例外がスローされます。スタックトレースは、これがないように設定されているソケットタイムアウトとしなければならなかったApacheの問題HTTPCLIENT-1478によく似ています

org.apache.http.conn.ConnectTimeoutException: Connect to <proxy> failed: Read timed out 
    at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:134) 
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:319) 
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:371) 
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:219) 
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195) 
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86) 
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108) 
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) 
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) 
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106) 
    at authentication.TestGet.get(TestGet.java:47) 
    at authentication.TestGet.main(TestGet.java:22) 
Caused by: java.net.SocketTimeoutException: Read timed out 
    at java.net.SocketInputStream.socketRead0(Native Method) 
    at java.net.SocketInputStream.socketRead(Unknown Source) 
    at java.net.SocketInputStream.read(Unknown Source) 
    at java.net.SocketInputStream.read(Unknown Source) 
    at sun.security.ssl.InputRecord.readFully(Unknown Source) 
    at sun.security.ssl.InputRecord.read(Unknown Source) 
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source) 
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) 
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:290) 
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:259) 
    at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:125) 
    ... 11 more 

です。このバグは4.3.4(私は4.3.6を使用しています)に修正済みとマークされていますが、いくつかのコメントは、それ以降のバージョンでは回避策がまだ必要であることを示していますが、私のために働いていません。さらに、私はSSLConnectionSocketFactory.createConnection()に入って、ソケットタイムアウトがゼロ以外の値に設定されていることを確認しました。

私は立ち往生しています。 SSLSocketImpl.startHandshake()を呼び出してトラブルシューティングを行うよりも、接続に失敗した理由が分からず、さらに深く踏み込むことができませんでした。何が間違っている可能性があり、どうすれば修正できますか?

+0

無限ソケットタイムアウトを設定するとどうなりますか?サーバ側のプロセスがSSLハンドシェイクの途中で立ち往生し、クライアントへのデータの送信を停止する可能性があります。 – oleg

答えて

0

[質問の回答者の質問]

プロキシサーバーがHTTPSをサポートしていることを確認してください。ターゲットサーバーへの接続でHTTPSが使用されていても、通常のHTTPが必要になることがあります。プロキシがHTTPSをサポートしていない場合は、クライアントのhelloメッセージに応答しません。ソケットタイムアウトが発生します。

javax.net.debugシステムプロパティをsslに設定すると、SSLネゴシエーションのデバッグログが有効になります。後続のServerHelloなしでClientHelloが表示される場合、プロキシサーバーはおそらくHTTPSをサポートしません。プロキシをhttps://からhttp://に変更して、もう一度お試しください。

2

は、代わり.setConnectionRequestTimeout(TIMEOUT)

を使用し、長い時間を待って、何が起こるか見ないでください。

詳細については、thisをお読みください。

+0

私がOPで言ったように、タイムアウトの具体的な値は関係ありません。いずれも設定されていないと、結局は接続のリセットSocketExceptionが発生します。 –

+0

Apache HttpClientのバグかもしれません。ネイティブコードを使用できますか? –

+0

こちらをご覧くださいhttps://stackoverflow.com/questions/11341928/sockettimeoutexception-after-converting-from-http-to-https-in-android-app too –

関連する問題