ゲートウェイ経由で接続されたAPサーバ上で,HttpServletRequest.getServerName()を呼び出したときに得られる値について

これまた長ったらしくで要領を得にくい題だなぁ.噛み砕いて言うと,

  • なんらかの理由より,動的に完全なURL(プロトコルスキームやらホスト名,ポート番号に続き,コンテキストパスに至るまで)を生成したい.
  • そのために,HttpServletRequest.getServerName()とかgetServerPort()とかを使う.
  • 通常,得られるホスト名とかは,実サーバの値になる.

でも

  • 前面にWebサーバ置いたり,ロードバランサ置いたりして,実サーバじゃないとっから経由してきた場合でも都合悪くなくしたい.
         +---------+    +---------+
 (a) ==> | server1 |--->| server2 |
         +---------+    +---------+
          Webサーバ        APサーバ
                          ※ここでHttpServletRequest.getServerName()を呼ぶ

たとえば,こんな(↑)構成で,(a)経由で「http://server1/foo」とかして,server1からserver2にたどり着いたら,server2のHttpServletRequest.getServerName()は"server2"を返すんじゃなく,"server1"を返して欲しい.という話だ.


自分でも「何を今更な」話だと思う.昔似たような事したけど,インフラ担当の方々がよろしくやってくれていたので,別に困る事も無くできてた記憶があるし.ただだ,その「よろしくやってくれる方々」が居ないとなると,そうはいかない.ああ,こんな事なら,何を設定してくれてたのか聞いておけば良かったなどと,取って付けたような後悔だけしてみる.


というわけで調べたよ.そしたら意外な程あっさり解決した.まあ,そもそも解決できるはずだってのと,インフラの問題で送り側か受け側のどっちかに何か設定するんだろうという思い込みがあったので,調べるのも意外に苦労しなかった.
#思えば,初動が見当違いじゃなくてよかったよ.なはは.


結論から言うと「受け側でなんとか」するようだ.まずはTomcatの場合,こちらにもあるように,ゲートウェイ経由用の待ちポートを用意して,そのポート経由の場合は「実サーバの代わりにコレ返せ」という設定をする.

〜server.xml〜
<Connector className="org.apache.catalina.connector.http.HttpConnector" port="8081" ...
           proxyName="www.mycompany.com" proxyPort="80"/>

Tomcatで出来るんなら,他のAPサーバも出来るだろうと,OC4Jについて調べて,これを見つけた.

Tomcatは,実際に違う筐体にApache載っけて試してみたのでOK.OC4Jは,設定のやりかた見つけただけで,実際に試してみた訳ではない(多分,うまく行くでしょ).


まあ,なんつーかですね,ネットワーク屋とミドル屋とアプリ屋はいっぺん会って話をするべきだよなと,しごく当たり前で意外に出来ない事をつくづく思い知らされましたとさ.やれやれ.:-(
#だから,何でも知ってる万能選手が求められるんだろうなぁ.


(追記)WebLogicの場合は,下記URLの「表 8-2 詳細属性」にある「フロントエンドなんたら」で設定できそう.
http://www.beasys.co.jp/e-docs/wls/docs81/adminguide/web_server.html#111290


さらにWinstoneの場合.それっぽいオプションは無い.まあでも,クラスタリングできるくらいだし,なんかやりようはあるんじゃないの?知らんけど.
とりあえず,HTTPをリスンしてるHttpListenerは,Socketオブジェクトからバインド先の情報を取得してるので,まあ無理だろう.期待が残るのは,AJP13をリスンしてるAjp13Listener.こっちはAJP13の電文からサーバ名とか抜いてるんだけど,送り側でなんかできるんだっけ?
#わざわざWinstone程度で凝った事すんな,って結末でも別に良いんだけどさ.
http://www.jajakarta.org/tomcat/tomcat-jk2/ja/docs/common/AJPv13.html