PSLブログ

ヨシナシゴトヲツヅリマス

Windows-IISな環境でperlis.dllを使ってCGIを動かす

Unixな環境でテストしたCMSがクライアント先のWindows-IISな環境で動かずトラブルに。

IISは普段まったく扱っておらず、素人同然なのだが、とにかく収束させないとということでいろいろ調べた。

まず、テストサーバがPerlEx30.dllで動作していたため、どうにも動作がおかしいので、PerlIS.dllに変更。プロバイダのコントロールパネルでは、PerlEx30.dllを使うか使わないかの切り替えしかできなかったため、こちらは無効に、代わりにドキュメントルートに置くweg.configに以下の記述をした(サポートに教えてもらった)。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <directoryBrowse enabled="false" />
        <defaultDocument>
            <files>
                <clear />
                <add value="Default.htm" />
                <add value="Default.html" />
                <add value="index.htm" />
                <add value="index.html" />
                <add value="index.php" />
                <add value="index.aspx" />
                <add value="Default.aspx" />
                <add value="index.py" />
                <add value="index.pl" />
            </files>
        </defaultDocument>
        <handlers>
        <add name="cgi" path="*.cgi" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="C:\Perl\bin\perlis.dll" resourceType="File" />
        </handlers>
    </system.webServer>
</configuration>

お、なにやら動くようになってきた(BEGINブロックなどに書いたデバッグ用の出力が出てくるようになったので)と思ったが、今度は、Content-typeヘッダを勝手に出力するようになった。またネットを調べたら、HTTP/1.0なりHTTP/1.1なりの応答ヘッダを一番最初に出力すると解決するということで、それも対応した。Cookieを出力する場合、それより手前で出さないとダメ、Locationヘッダを出力するときはHTTP/1.0 302 Foundを出力するようにした。

PerlIS.dllで動作しているかの確認方法

PerlIS.dllにはHTTPヘッダを自動で出力してくれる小さな親切(余計なお世話)機能があって自分で出力しようとしたHTTPヘッダがHTTPヘッダではなく本文として扱われてしまって、CGIプログラムが上手く動かなくなるという問題があります。 ステータスコードから書けばHTTPヘッダの自動出力が行われなくなるので、そのように対策方法がありますが、レジストリの設定でON/OFFを切り替えられます。My CGI scripts don't seem to run right under PerlIS. おかげでPerlIS.dllで動かす場合でも普通のCGIを同じようにスクリプトを書けます。

AN HTTP Server の ISAPI 対応状況

PerlIS の制限
  •  パイプ入出力は使えません。 標準入力からの読み込みはできるだけ read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}) を使う方がよいようです。
  •  カレントディレクトリを変える操作はできるようですが、避けた方がよいようです。(httpd が動くディレクトリが変更されます。)
  •  バッククオート, system( ), exec( ) などによる外部プログラムの実行はできません。無視されるようです。
  •  Location: を含むヘッダを返すときは、 初めに "HTTP/1.0 302 Found\n" を出力(print)してください。 そうしないと、"HTTP/1.0 200 OK\n" になってしまいます。