Delphi2009でApache2.2(Windows)用のモジュールを作成する方法。Delphi7ぐらいのときは標準でApache2モジュール選べたのになぁ。
使用しているDelphiは2009pro。
Delphi2009になってからも、Apacheのヘッダファイル群をポートしてラップしたクラスが残っています(2009でも問題なく動作する)。
Apache2のインストール
まずはApache2のインストール。使用したApach2のバージョンは2.2.11です。
このあたりからダウンロードしてきましょう。
http://www.apache.jp/misc/download.html
Windows用のインストーラが手に入ったら早速インストール。
設定は適当に。Server Nameはlocalhostでいいと思います。80番ポートが使えない場合は別途調べてインストールどうぞ。
後で必要になるので、Customインストールで "Build Headers and Libraries" もインストールしておきます。
インストールに成功したら、 http://localhost/ にブラウザでアクセスしてApacheが動いているか見てみましょう。
作成するモジュールはApacheのDLLを呼び出すので、Apacheのインストールディレクトリを環境変数のPATHに追加しておきます。
DelphiでWebサーバーアプリケーションを作る
Apacheのインストールができたら、Delphiでアプリケーションを作りましょう。
CGI実行形式で開発を行います。
アクションを一つ作ってHTMLのレスポンスを返すイベントを実装しました。
procedure THelloApp.HelloAppIndexAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin Response.Content := '<html><head>' + '<meta http-equiv="content-type" content="text/html; charset=Shift_JIS">' + '<title>Apache2モジュール</title></head><body>' + '<h1>こんにちはApache</h1>' + '</body></html>'; end;
プロジェクトのソースを開いて、Apache用に書き換えます。
library Apache2Hello; // program -> library {$APPTYPE CONSOLE} uses WebBroker, //CGIApp, ApacheTwoApp, // apache 1.xの場合はApacheApp uHelloApp in 'uHelloApp.pas' {HelloApp: TWebModule}; {$R *.res} {$E so} // 拡張子を.soに // Apacheから呼ばれるハンドルをエクスポート exports apache_module name 'Apache2Hello_module'; begin Application.Initialize; Application.CreateForm(THelloApp, HelloApp); Application.Run; end.
さてこれでApache2用のモジュールがビルドされます。Apache2Hello.soファイルができました。
Apacheにモジュールを設定する
Apache2のconfを少し書きます。"C:\Program Files\Apache Software Foundation\Apache2.2\httpd.conf"
LoadModule Apache2Hello_module "C:\sokano\Projects\Delphi\_sample\apache2mod\Apache2Hello.so" <Location /> # ファイル名を小文字にしたもの+"-handler"をSetHandlerで指定 SetHandler apache2hello-handler </Location>
Apacheを再起動して確認しようとしたところ、モジュールが見つかりませんとエラーがでました。
DelphiのApacheモジュールはApacheの "libapr.dll" と "libhttpd.dll" を参照しています。
Apacheのbinディレクトリには、 "libhttpd.dll" はありましたが、"libapr.dll"はなかったので"libapr-1.dll"をこの名前でコピーしておきます。
これで動作するか、と思いきやまたエラーがでました。
httpd: Syntax error on line 484 of F:/Program Files/Apache Software Foundation/Apache2.2/conf/httpd.conf: API module structure 'Apache2Hello_module' in file F:/sokano/Projects/Delphi/_sample/apache2mod/Apache2Hello.so is garbled - expected signature 41503232 but saw 41503230 - perhaps this is not an Apache module DSO, or was compiled for a different Apache version?
Apacheのバージョンが合いませんということのようです。
Apacheのバージョンを合わせる
DelphiのHTTPD2.pasはApache2.0.42用に書かれています。なのでこれを使用するApacheのバージョンに合わせる必要があります。
230行目のこのあたりが原因。2.0.42になっている。
{$HPPEMIT '#include <http_config.h>'} (* * @file http_config.h * @brief Apache Configuration *) const MODULE_MAGIC_COOKIE = $041503230; (* "AP20" *) {$EXTERNALSYM MODULE_MAGIC_COOKIE} MODULE_MAGIC_NUMBER_MAJOR = 20020903; { Apache 2.0.42 } {$EXTERNALSYM MODULE_MAGIC_NUMBER_MAJOR} MODULE_MAGIC_NUMBER_MINOR = 0; (* 0...n *) {$EXTERNALSYM MODULE_MAGIC_NUMBER_MINOR} MODULE_MAGIC_NUMBER = MODULE_MAGIC_NUMBER_MAJOR; (* backward compat *) {$EXTERNALSYM MODULE_MAGIC_NUMBER}
MODULE_MAGIC_COOKIEとMODULE_MAGIC_NUMBER_MAJOR、MODULE_MAGIC_NUMBER_MINORを書き換えます。
Apacheのincludeディレクトリからgrepでこの値を探します。
"ap_mmn.h" に同じ値がありました。
#define MODULE_MAGIC_COOKIE 0x41503232UL /* "AP22" */ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20051115 #endif #define MODULE_MAGIC_NUMBER_MINOR 21 /* 0...n */
Delphiのsource\internetディレクトリから "HTTP2.pas" と "ApacheTwoApp.pas" をプロジェクトディレクトリにコピーしてきます。
HTTP2.pasの該当箇所を書き換えます。
{$HPPEMIT '#include <http_config.h>'} (* * @file http_config.h * @brief Apache Configuration *) const MODULE_MAGIC_COOKIE = $041503232; (* "AP20" *) {$EXTERNALSYM MODULE_MAGIC_COOKIE} MODULE_MAGIC_NUMBER_MAJOR = 20051115; { Apache 2.0.42 } {$EXTERNALSYM MODULE_MAGIC_NUMBER_MAJOR} MODULE_MAGIC_NUMBER_MINOR = 21; (* 0...n *) {$EXTERNALSYM MODULE_MAGIC_NUMBER_MINOR} MODULE_MAGIC_NUMBER = MODULE_MAGIC_NUMBER_MAJOR; (* backward compat *) {$EXTERNALSYM MODULE_MAGIC_NUMBER}
書き換えたら、プログラムの再構築を行います。
Apacheを再起動して、http://localhost/ にアクセスすると「こんにちはApache」と表示されました。
めでたしめでたし。