こんにちは、mayuki です。
いま竹芝のすき家ユーザーに大人気なWebサーバーと言えば当然IIS7ですよね。そんなIIS7でPerlアプリケーション動かしたいですよね。
ご存じかと思いますがIISはWindows Server上で動作するWebサーバーで、IIS7はWindows Server 2008(Vista)世代のWebサーバーのことです。IIS7はIIS6からアーキテクチャまるごとだいぶ変わっているのでいろいろ便利でおもしろくなっています。
最近Perlでプログラムを書いたりしていないのですがPerlで書かれたアプリケーションをそんなIIS7で動かす機会はあったのでその時得たハマリどころなどを書いてみます。
時代も時代ですのでIIS6のことは忘れましょう。あれは過去の遺物です。
IIS7でPerlのアプリケーションを動かすには次の3つの手段があります。
それぞれ利用するパターンはこんな感じですね。
それぞれの利点・欠点はこんな感じです。
今回はCGIにフォーカスして説明します。なんか長くなりそうだし…。
ということでもっとも基本的なCGIでPerl アプリケーションを動かす為の設定をしてみます。CGIの設定方法は割とWebに転がっているのでざっくりと説明します。
とりあえず簡単なCGIスクリプトを用意します。以下のような内容でindex.cgiとして保存しておきます。
use strict; use CGI; my $q = CGI->new; print $q->header(-charset => 'utf-8'); print "初春かわいい";
ではこれをどこか公開するためのフォルダに配置しましょう。今回は C:\InetPub\wwwroot がサイトのルートとして、その下の C:\InetPub\wwwroot\Perl\ に設置することにします。
ファイルを設置したらインターネット インフォメーション サービス (IIS) マネージャを起動しましょう。
起動できたら先ほどファイルを設置したディレクトリをサイトのツリーから探し出します。
そして見つかったらそのフォルダを選択して、コンテキストメニューを開きます。開いたメニューの中に「アプリケーションへの変換」というのがあるのでそれを選択します。そうするとディレクトリがアプリケーションとして設定されます。
で、アプリケーションに変換できたら、真ん中の機能ビューで「ハンドラ マッピング」というのを開きます。開くとハンドラの一覧が出てきますので、その右側のペインの「操作」から「モジュール マップの追加」を選択します。
「モジュール マップの追加」ダイアログが出てきますので以下のように値をうめます。
ちなみに各項目を簡単に説明しておくと…
というわけで設定したらOKを押して閉じましょう。OKを押すと
この ISAPI 拡張機能を有効にしますか? [はい] をクリックすると、[ISAPI および CGI の制限] の一覧の "許可済み" の項目に、拡張機能が追加されます。[ISAPI および CGI の制限] の一覧に拡張機能の項目が既に存在する場合は、"許可済み" に更新されます。
とか言われますので「はい」を押します。
では早速ブラウザで http://localhost/Perl/index.cgi にアクセスしてみましょう。無事表示されましたか?ここまでで動かなかった人は次のトラブルシュートをご覧ください。
こんな感じで普通のCGIなアプリケーションも設定すれば動くでしょう。
さて、CGIの設定をしましたが先ほどのような簡単なモノならともかくそこら辺に転がっていたりするモノを動かしてみると案外動かなかったりします。というわけでトラブルシュートです。
ハンドラの設定が間違っているときによく表示されます。例えばPerlのパスが違うなどです。
このメッセージは何らかの理由でCGIが死んだりしたときに出てきます。Apacheで動かしたときの500相当ですね。
まずはPerl.exeで直接実行してみましょう。そもそもモジュールが足りなくて死んだりする場合はすぐわかります。
動かしてみて大丈夫そうだったけどやっぱりIISで動かない…。そういうときはスクリプトの頭に
BEGIN { print "Content-Type: text/html\n\n"; }
とか書いて実行してみましょう。こうすると大体動作して、何かwarningが頭についていたりするのが見えたりするようになります。
IIS7にはFREBという失敗した要求のナントカカントカというログ機構が備わっていますが、CGIのエラーはろくに情報がないのでこのローテクで回避するのが楽です。IISでCGIを動かすときにはおぼえてて損はないと思います。
で、warningが原因で502になるというのはどういうことかというと、どうやらIISのCgiModuleはSTDERRをSTDOUTと同様にクライアントへ出力しようとしてしまい途中でエラーとなるようです。
20世紀スクリプトを動かす場合などにこまったりしますね。
例えば先ほどのコードもこんな感じにするとすぐ動かなくなります。Apacheではerror.logにはなにやらでますが一応動きます。
use strict; warn "------\n\n"; print "Content-Type: text/html; charset=utf-8\n\n"; print "初春かわいい";
で、じゃあどうするのかという話なのですが手っ取り早い方法はスクリプトの頭に
BEGIN { close(STDERR); }
とか書いてしまう方法です。これで忌まわしきWarningでエラーになることがなくなります。
本当のエラーが出たらCGIは死ぬし元々情報は残らないのでそこで調べればいいと思います。STDERRをどこかのファイルに出すなり、その辺はどうとでもやりようがありそうです。
ちなみにSTDERRに吐いてても処理しきってしまえれば動くことはあるので、知らないうちにヘッダーにwarningがでていることがあります。そういう意味でもSTDERRを何とかしておいた方が良いかもしれません。
IISのCgiModuleはIISでアプリケーションに指定したディレクトリをワーキングディレクトリとして起動します。
そのため /App/ をアプリケーションとして指定してあっても /App/Hauhau/ をアプリケーションとして指定していない場合、 /App/ をワーキングディレクトリとして /App/Hauhau/nantoka.cgi を起動するのでPerlアプリケーション内で各種読み込みのパスが期待と異なってしまうことがあります。
というわけでCGIファイルを含むディレクトリはすべてアプリケーションに変換しておくのが安全です。
というわけでちょっとクセがありますがコツをつかめばCGIは楽勝ですね。FastCGIとかARRとかについてもふれる機会があればいずれ。
みなさんもIIS7でクリスマスをエンジョイしてください。