ある規則は http://reports.example:80/ をプロキシ経由で送りますが、http://reports.example/ は直接通します。これらの URL は同じ通常の HTTP エンドポイントを表しています。不一致は通常、解析されたポートを文字どおり比較することから生じます。

URI.getPort() は URI にポートが現れないとき -1 を返します。スキームの既定値を補うことはしません。値を 80 と比較するルーティングポリシーは 2 番目の URL を取りこぼします。

String scheme = uri.getScheme();
int port = uri.getPort();
if (port == -1) {
    if ("http".equalsIgnoreCase(scheme)) port = 80;
    else if ("https".equalsIgnoreCase(scheme)) port = 443;
}

比較の両側に同じ正規化を適用します。リクエスト URI だけを直しても、ポートが省略された設定済みの宛先は一致しないままです。ホスト、実効ポート、意図したスキームを比較し、不正な、あるいはホストのない宛先は定義されたエラー経路で拒否します。

すべてのコールバックを HTTP の判断にしない

既定のセレクタは、socket スキームを使って生のソケット接続についても問い合わせられます。ホストとポートが一致するだけで、そのコールバックが URL リクエスト向けの HTTP プロキシを返してよいわけではありません。未対応のスキームは前のセレクタに委ね、その適切な動作を保ちます。

独自のセレクタを導入する前に、その前のセレクタを保持しておきます。置き換えの内部から現在の既定値を調べると、置き換えを再び呼び出すだけになりかねません。

不一致を診断するときは、スキーム、ホスト、元のポート、実効ポートを記録します。JDK 実装間で観測された 1 つの数値やコールバックの順序に依存しないでください。ポリシーは与えられた各 URI に対して正しい判断を下すべきです。

関連記事