2012-02-29 8 views
3

Apache HttpClientを仮想化された開発環境の外部サービスに接続するのに問題があります。 インターネット(api.twitter.comなど)にアクセスするには、ローカルURL(例:api.twitter.com.dev.mycompany.net)を呼び出す必要があります。このURLは、実際のホストにリクエストを転送します。プロキシ/ロードバランサ経由でサービスにアクセスするためのApache HttpClientの設定

問題は、私が送信したリクエストに応じて、404 Not Foundレスポンスが得られることです。

私はwgetを使用してデバッグしようとしましたが、問題は、宛先ヘッダーとホストヘッダーの両方のホスト名を使用して宛先サーバーが目的のリソースを識別しているようです。ホスト名が一致しないため、リソースを見つけることができません。

私は(失敗した)このように、クライアント上でhttp.virtualホストパラメータを設定することにより、ホストヘッダーを上書きしようとしている:

HttpClient client = new DefaultHttpClient(); 
if (envType.isWithProxy()) { 
    client.getParams().setParameter(ClientPNames.VIRTUAL_HOST, "api.twitter.com"); 
} 

技術的な詳細:

  1. クライアントが使用されていますRESTeasyのエグゼキュータとしてREST APIを呼び出します。したがって、「手動で」仮想ホストを設定すると(hereのように)、オプションではありません。

  2. すべてはHTTPS/SSL経由で行われます。違いはないと思います。編集1

:所望の効果を有していないHttpHost文字列の代わりに使用いずれか:

HttpClient client = new DefaultHttpClient(); 
if (envType.isWithProxy()) { 
    HttpHost realHost = new HttpHost("api.twitter.com", port, scheme); 
    client.getParams().setParameter(ClientPNames.VIRTUAL_HOST, realHost); 
} 

編集2:さらに調査パラメータがあることが必要であることを、明らかにしました要求オブジェクトに設定します。以下は、コードvでのHttpClientの4.2-aplha1は、仮想ホストの設定:。

HttpRequest orig = request; 
RequestWrapper origWrapper = wrapRequest(orig); 
origWrapper.setParams(params); 
HttpRoute origRoute = determineRoute(target, origWrapper, context); 

virtualHost = (HttpHost) orig.getParams().getParameter(
      ClientPNames.VIRTUAL_HOST); 

paramsをクライアントから渡されたパラメータです。しかし、 'virtualHost'の値はリクエストパラメータから読み取られます。

質問の性質を次のように変更しました。要求にVIRTUAL_HOSTプロパティを設定するにはどうすればよいですか?

答えて

3

ClientPNames.VIRTUAL_HOSTは、HTTP要求の物理ホスト名を上書きするための正しいパラメータです。クライアントオブジェクトの代わりにリクエストオブジェクトにこのパラメータを設定することをお勧めします。それが望みの効果をもたらさない場合は、ここまたはHttpClientユーザーリストにセッションの完全なワイヤ/コンテキストログ(手順についてはlogging guideを参照)を投稿してください。


フォローアップ

OK。もっと大きなスレッジハンマーを作ってみましょう。インターセプタを使用してHostヘッダーの内容を無効にすることができます。

DefaultHttpClient client = new DefaultHttpClient(); 
client.addRequestInterceptor(new HttpRequestInterceptor() { 

    public void process(
      final HttpRequest request, 
      final HttpContext context) throws HttpException, IOException { 
     request.setHeader(HTTP.TARGET_HOST, "www.whatever.com"); 
    } 
}); 

一つは、特定のホストに対して、選択的にヘッダを上書きするのに十分なインターセプタが賢いすることができます。

+0

あなたの答えは@olegありがとうと思います、あなたは正しいです。 :)残念ながら、要求オブジェクトはRESTeasyによって作られています。私は質問を更新します。 – tveon

+0

@tveon:実際には、HttpClientレベルのパラメータは常に個々の要求に伝播する必要があります。すべてのリクエストに対して 'Host'値を無差別に設定するのは概念的に間違っているようです。 – oleg

+0

はい、あなたは正しいです。 RESTでは一般的にすべてのアクションに関係するベースURIを使用していますが、アプローチが安全ではない相互作用(リダイレクトなど)があり、適切なロジックを備えたインターセプタを使用する方がおそらく良いでしょう。 – tveon

関連する問題