子供のころの図書館
子供のころ、実家の近くには図書館があった。歩いて数分。夏休みともなると、毎日出かけた。広いフロアに大きな本棚。飽きなかった。
本格的な情報システムというものに触れたのも、この図書館が初めてだった。30年近くまえから、貸出がコンピュータ化されていて、市内全域の図書館とオンラインでつながっていた。窓口の職員が保護フィルムの下に張られたシールの番号をOCRで読み込むと、その瞬間画面に書名が出てくる。格好良かった。
おそらくこれは先進的なシステムだったのだろうと思う。図書館好きが高じて県立図書館まで遠征にいったとき、大量のカード目録が引き出しに収まっているのを見て衝撃を受けた。まだ紙なんだ、と。子供の認識では、市よりも県の方がエライから、県のシステムはさぞや凄いんだろうという漠然とした期待感があったのだが、裏切られた。
先日久しぶりに、毎日のように通ったその図書館に寄った。フロアは狭く、本棚は小さかった。子供のころは、本がこんなにたくさんある、という無限の広がりを感じていたが、今見ると、これしかないのか、という限定感がある。
お気に入りの棚をじっくり眺めると、本の顔ぶれががらっと変わっていることがわかる。何回も何回も借りて読んだ本を探しても見つからない。収容量には限度があって、常時新しい本が入ってくるのだから、古くて貸出もされない本を処分するのは当然だろうが、さびしい。それでも時折、小学生のころに読んでいた本がまだ残っている。ページを開くと当時の記憶がよみがえってくる。
自分の根っこは両親が作ってくれたが、その根っこの上の基礎はこの図書館が作ってくれた。小学生のときの関心事といまの関心事が、まったく変わっていない。当時読んでいた本と同じような本を今も読んでいる。三つ子の魂百まで。この図書館のそばにたまたま住んでいたその偶然に感謝したい。
複数のSSL証明書をインストールする方法
HTTPS を使うとき、ウェブサーバには SSL証明書をインストールする。通常、一台のサーバにつき一つしか、SSL証明書はインストールできない。いや、できるのだが、複数のIPアドレスをサーバに割り当てるか、別のポートでHTTPリクエストを受けるかをしなくてはならない。前者は Amazon EC2 をはじめとするレンタルサーバでは使えないことが多いし、後者はビジネス要件として許されないことが多い。
一般的に使われている名前ベースのバーチャルホストでなぜ複数証明書を使えないのか。それは、どのバーチャルホストを使うかを決める情報が、クライアントから送られるHTTPリクエストヘッダ中のHostフィールドに入っているからである。つまりHTTPレイヤの情報だからだ。HTTPS で通信するときは、まずクライアントとサーバとで SSL の通信路を確立してから、HTTPのリクエストを送る。どのバーチャルホストを使うかという情報は SSL の通信確立の時点では知りようがないため、複数の SSL 証明書の中から選んで通信することができない。
これを解決する方法がいくつかあるが、どれも使い勝手がよくない。1つ目はワイルドカード証明書を使う方法。hoge.example.com と bar.example.com というような2ドメインを対象としたいようなときは、この手が使える。ただし example.com や sub.hoge.example.com などのように、階層がずれたものは対象にできない。
2つ目はSSL証明書の Subject Alternative Names を利用する方法。SSL証明書内部に、こっちのドメインもあっちのドメインも対象にするよ、という情報を Alternative Names(別名)として埋め込むことができる。すごく便利なようだが、ガラケーが未対応なので、携帯サイトを作りたいときには使えない。
3つ目は、Server Name Indication という SSL の拡張仕様を使う方法。どのバーチャルホストを使うかを、SSL のプロトコルで指定できるようにしたものだが、未対応のクライアントも多いため、まだ利用できる状況にはない。
というわけで、複数のドメインでSSLを使う場合は、複数のIPアドレス、あるいは複数のサーバ(つまり複数のIPアドレス)を用意しましょう、というのが現時点での標準的な方式になっている。あと3年はこのままだろう。
HTTPクライアントの接続元IPアドレスを知る
ウェブサーバで、クライアントの接続元IPアドレスを見て挙動を変えたいということはよくある。社内からのアクセスだけ特別扱いしたり、携帯電話キャリアのからのアクセスの時だけコンテンツを表示するなど、用途は広い。
普通、このIPアドレスは REMOTE_ADDR という変数名で取得できる。これはもともと、CGI で使われた仕様(http://tools.ietf.org/html/draft-robinson-www-interface-00)であるようだ。Apache の mod_rewrite なら %{REMOTE_ADDR} で、PHP なら $_SERVER[‘REMOTE_ADDR’] で参照できる。
ところがロードバランサやプロキシを間に挟むと、REMOTE_ADDR がロードバランサ等のアドレスになる。この場合、多くのロードバランサ等では HTTP のリクエストヘッダに X-Forwarded-For フィールドを追加する。これは HTTP の仕様ではないものの、デファクトスタンダードだ。
REMOTE_ADDR は IPレイヤの情報だが、X-Forwarded-For は HTTPレイヤの情報である。データの取得元が変わるので、値の取り方も変わる。mod_rewrite なら %{HTTP:X-Forwarded-For} だし、PHP なら $headers = apache_request_headers(); $ip = $headers[‘X-Forwarded-For’]; となる。
IPレイヤの REMOTE_ADDR とは違い、HTTPレイヤの X-Forwarded-For はクライアントによる偽装が容易なので、インターネットなどの信頼できないネットワークから直接HTTPリクエストを受ける経路も存在する場合、X-Forwarded-For のみを信じて大事な情報の表示可否を決めてはいけない。REMOTE_ADDR を併用したチェックが欠かせない。
HTTP で便利に使える X-Forwarded-For だが、HTTPS では利用できない。HTTPS では通信がエンドトゥーエンドで暗号化されるため、途中に挟まるプロキシ等が X-Forwarded-For ヘッダを挿入することができない。REMOTE_ADDR もプロキシのものになってしまって元のIPアドレスがわからないし、X-Forwarded-For も使えないので、アクセス元を判定できない。
HTTPS でアクセス元IPアドレスを知りたい場合は、ロードバランサやプロキシを通さずに HTTPS を受けるようにするか、SSLアクセラレーションあるいは SSLターミネーションと呼ばれる機能を使ってロードバランサで SSL を受け、復号化してウェブサーバに送るようにすればよい。
オブジェクト指向の終焉
オブジェクト指向って、もう流行らないな、と思う。
2000年ころは熱かった。Javaの影響だろう。それまで主流だったCに文法が似ていて、Cよりも簡単な Java が業界のデファクトスタンダード言語になりつつあった。Java は、初めての標準オブジェクト指向言語だった。プログラマなりたての人から熟練者までが使う、初めてのオブジェクト指向言語だった。もちろんC++ もあったが、プログラマ一年生がいきなりC++を使うことはない。VC++ から入る不幸なプログラマも多数いたが、オブジェクト指向云々の前に MFCフレームワークの大海に溺れた。
VC++にはフレームワークや便利なIDEがあったが、Javaには何もなかった。利用者が多い割には言語とクラスライブラリ以外に何もない、素のオブジェクト指向言語。テキストエディタに自分で Class Person { … } などと打たなくてはならない。否が応でもクラスを意識する。アプリケーション全体を視野に収めなければ、プログラムの理解ができなかった。それでオブジェクト指向が流行った。同時に、オブジェクト指向設計を表記するための UML も注目された。
しかし2001年にWebアプリケーションフレームワーク Struts がリリースされたときから、状況は変わる。Java でも、フレームワークの上に乗っかって、必要な処理を穴埋めするだけでアプリケーションが作れるようになった。決められたクラスを継承して、決められたメソッドを実装すれば済むようになった。こうなると、自分でクラスの構造や振る舞いを考える必要がなくなる。
いま流行っている iOS や Android でも、すでに巨大なフレームワークが存在して、プログラマは穴埋めするだけで済むようになっている。フレームワークが膨大すぎて溺れそうなのは MFC と大差ないが、オブジェクト指向が無くても仕事はできる。
オブジェクト指向は、フレームワークの利用者が必要とするものではなく、フレームワークの作成者に不可欠の技術、思考法だ。これを必要とする人は、それほどいない。今思えば、Java は初めてにして最後の、素のデファクトスタンダードオブジェクト指向言語だったのではないだろうか。
Windows で Apache2.2 + PHP5.3
Windows で Apache2.2 + PHP5.3 の環境を作った。たかが Apache + PHP と思ったが、サクッとはいかなかった。
現時点で簡単にインストールできるのは、http://windows.php.net/download/ の PHP 5.3 VC9 x86 Thread Safe (2011-Mar-22 13:27:32) と、http://www.apachelounge.com/download/ の httpd-2.2.19-win32-x86-ssl.zip の組み合わせ。必ず Thread Safe版を使う。Non thread safe版には、Apache のモジュール php5apache2_2.dll が同梱されていないので、Apache とはつながらない。
windows.php.net で提供されている PHP 5.3 は VC9版で、これは Visual C++ 2008 でビルドされていることを意味する。PHP 5.2 は Visual C++ 6 でビルドされた VC6版だった。
Apache 上で使う場合、VC9 なら VC9版 Apache を、VC6 なら VC6版 Apache と組み合わせる必要がある。Apache の公式サイト http://httpd.apache.org/ で配布されているバイナリは VC6版で、PHP 5.2 は動くものの、上記 PHP 5.3 は動かない。そこで http://www.apachelounge.com/download/ のバイナリを使う。このバイナリにはインストーラがない。サービスとしても登録してくれない。なので、コマンドラインから httpd -k install と打って、自分で登録する。Apache Monitor も、自分で Startup に登録する。
これでようやく入り口に立てた。