2016-05-26 17 views
2

私はApache HtppComponents(バージョン4.5.2)を使用しており、プロキシサーバー経由でHTTPSページをリクエストしようとしています。Apache HttpComponents。 CONNECTリクエストの応答を取得

EDIT:

私の主な問題は、私は、プロキシサーバと(HTTPとHTTPSの両方のための)要求されたURIの障害の障害を区別する方法を知っておく必要があるということです。私は多くのプロキシを持っていて、100%信頼できないので、プロキシが失敗した場合は、別のプロキシサーバーでリクエストを再試行する必要があります。

例えば(HTTPSの場合)、プロキシが失敗した場合、またはターゲットURLが失敗した場合の両方で、NoHttpResponseExceptionが返されます。どのように問題の根本を知ることができますか?どこから来たのですかNoHttpResponseException?ターゲットURIからのプロキシから?

私はCONNECT要求のプロキシサーバーへの読み込みを試みることができると思っていました。それが200なら、私はそれがプロキシが良いことを意味し、次にNoHttpResponseExceptionはターゲットURLから来ています。しかし、私がNoHttpResponseExceptionを直ちに(プロキシがCONNECTの200状態コードを返す前に)受け取ると、それはプロキシ自体に問題があることを意味し、別のプロキシサーバーで要求を再試行する必要があります。しかし、プロキシサーバーから返されたCONNECT要求の応答へのアクセス方法をドキュメントで見つけることができませんでした。

また、時々私はHttpHostConnectExceptionConnectTimeoutExceptionを取得しています。私はこの例外をプロキシ(HTTPとHTTPSの両方)の問題として扱っています - それは正しいですか?または、この2つの例外はターゲットURLに対しても発生する可能性がありますか?

+0

なぜ最初にCONNECT応答メッセージにアクセスしたいのですか? – oleg

+0

@oleg Oleg、私の問題の根本は、プロキシサーバーの失敗と要求されたURIの失敗を区別する方法を知る必要があることです。たとえば、どちらの場合でも 'NoHttpResponseException'を返すことができます。そこで、私はCONNECTリクエストの再取得でプロキシによって返されたいくつかのヘッダを読みたいと思います(ヘッダがいくつかあれば、それはプロキシサーバからのヘッダがない場合は、プロキシの良さと宛先URIに問題があります - プロキシへの接続中に 'NoHttpResponseException'が発生した) – MyTitle

+0

@olegプロキシサーバーの失敗を特定する方法と、要求されたURI(特に 'NoHttpResponseException 'に関連するもの)の失敗を区別する方法について他に提案がある場合は、それらを手伝ってください。ありがとう – MyTitle

答えて

2

は、かなりになるだろうされていないが、それはトリックに

HttpHost myproxy = new HttpHost("myproxy", 8080) 
CloseableHttpClient client = HttpClientBuilder.create() 
     .setProxy(myproxy) 
     .setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy() { 

      @Override 
      public boolean isAuthenticationRequested(HttpHost authhost, HttpResponse response, HttpContext context) { 

       if (myproxy.equals(authhost)) { 
        context.setAttribute("proxy.status", response.getStatusLine()); 
       } 
       return super.isAuthenticationRequested(authhost, response, context); 
      } 
     }) 
     .build(); 

HttpClientContext context = HttpClientContext.create(); 
HttpGet get = new HttpGet("https://httpbin.org/"); 
try (CloseableHttpResponse response = client.execute(get, context)) { 
    EntityUtils.consume(response.getEntity()); 
} 
StatusLine proxyStatus = context.getAttribute("proxy.status", StatusLine.class); 
System.out.println("Proxy said " + proxyStatus); 

PSを実行する必要があります。プロキシへの接続時にHttpHostConnectExceptionConnectTimeoutException例外は唯一、つまり、最初のホップ上でスローすることができます。何らかの理由でプロキシがターゲット・サーバーへの接続に失敗した場合は、CONNECTメソッドに応答して5xxの状況で応答する可能性があります。

+1

ありがとう、それは助けてください!私の質問の最後の段落( 'HttpHostConnectException'と' ConnectTimeoutException'について)に答えてください。この例外がプロキシサーバーまたは両方の場合にのみ発生するかどうかを知る必要があります。 – MyTitle

+0

このコードを試しましたが、 'HttpResponse'オブジェクトには、要求されたURIからの情報が含まれています。プロキシからの応答ではなく、' CONNECT'要求への応答です。私。それは 'response.getStatusLine()'を直接使うのと同じです。ログでは、このプロキシがこのステータス行を返したことがわかります。「HTTP/1.1 200 Connection established」、しかし 'context.getAttribute(" proxy.status "、StatusLine.class)'は 'HTTP/1.1 200 OK'を返します。 - 私は。プロキシからではなく、リモートサーバーからの応答です。それを証明するために、私はステータスラインの代わりにヘッダーを取得しようとしました - それでもプロキシからではなく、リモートサーバーからのヘッダーです。 – MyTitle

+0

ログによると、私はこのメソッドが2回呼び出されることを理解しています。 Proxyからの応答で初めて、リモートサーバからの実際の応答で2回目。したがって、 '' proxy.status ''は2番目の呼び出しで上書きされます。 – MyTitle

関連する問題