トップ «前の日記(2005-09-16) 最新 次の日記(2005-09-22)» 編集

おいぬま日報(不定期)

新しいおいぬま日報 | カテゴリ | 技術情報まとめWiki | 検索エンジンから来た人向け | RSS

2005年
9月
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30



2005-09-18 [長年日記]

@ [perl] Apache2 + mod_perl2.0.1 + Sledge-1.11

今週頭からずっとインストールにてこずっていたのですが、昨日朝方までかけてなんとかHello world!を出すところまでたどり着きました。

環境はDebian sarge + Apache 2.0.54です。Apacheはdebからインストールしている状態です。perlとmod_perlとlibapreqとSledgeはここで野良ビルドしてインストールします。

まずはperlのインストールから。http://cpan.org/src/README.htmlよりstableである5.8.7をダウンロードして解凍します。

$ tar xvzf stable.tar.gz
$ cd perl-5.8.7
$ sh Configure -Dusethreads -Duselargefiles \
 -Duse_ithreads -Dprefix=/usr/local -des
$ make
$ make test
# make install

これで/usr/local/配下にperlがインストールされました。もし/usr/local/binにパスが通っていない場合はパスを通しておきます。んで

$ perl -v

してバージョンを確認しましょう。

続いてはlibapreq2のインストールです。ここから最新版(今回は2.06-dev)を取得してインストールします。

$ tar xvzf libapreq2-2.06-dev.tar.gz
$ cd libapreq2-2.06-dev
$ ./configure --prefix=/usr/local --with-apache2-apxs=/usr/bin/apxs2 \
 --with-perl-opts
$ make
$ make test
(ここでエラーとなりますがとりあえず無視します)
# make install
# cp -f module/apache2/.libs/mod_apreq2.so /usr/lib/apache2/modules/

これで/usr/lib/apache2/modules配下にmod_apreq2.soがインストールされます。今度は必要なPerlモジュールをインストールします。

$ cd glue/perl
# perl -MCPAN -e 'install ExtUtils::XSBuilder::ParseSource'
(ビルドに必要なモジュールをインストール)
$ perl Makefile.PL
$ make
# make install

次はmod_perl2のインストールです。

perl.apache.orgより2.0系の最新版(今回は2.0.1)を取得して解凍します。

$ tar xvzf mod_perl-2.0-current.tar.gz
$ cd mod_perl-2.0.1

あとはMakefileを作るのですが、この時にapxs2コマンドのパスを指示します。そしてmake && make install。

$ perl Makefile.PL MP_APXS=/usr/bin/apxs2
$ make
$ make test
(ここでもいくつかテストが失敗しますが無視します)
# make install
#  cp -f src/modules/perl/mod_perl.so /usr/lib/apache2/modules/

ここでひとまず、インストールしたmod_perl2の動作確認を行ってみます。下記の内容をhttpd.confに追記してApacheを再起動します。これで拡張子が.plなファイルはmod_perl2で動作するようになります。

LoadModule perl_module /usr/lib/apache2/modules/mod_perl.so
LoadModule apreq_module /usr/lib/apache2/modules/mod_apreq2.so
<Files *.pl>
  SetHandler perl-script
  PerlHandler ModPerl::Registry
  Options +ExecCGI
  PerlSendHeader On
  Order allow,deny
  Allow from all
</Files>
# /etc/init.d/apache2 restart

そして下記の環境変数を出力するスクリプトを作成し、ドキュメントルートなどの下においてブラウザからアクセスしてみましょう。見事環境変数が出力されればmod_perl2のインストールは完了です。

#!/usr/local/bin/perl -w
use strict;
 
print "Content-type: text/plain\n\n";
foreach my $key (keys(%ENV)) {
  print "$key = $ENV{$key}\n";
}

残すところはSledgeのインストールなのですが、Sledgeが使用するDBIとDBD::mysqlを先にインストールしておきます。

# perl -MCPAN -e 'install Bundle::DBI'
# perl -MCPAN -e 'install DBD::mysql'

では最後の難関、Sledgeのインストールに移ります。ダウンロードページから最新版(今回は1.11)を取得して解凍し、付属のcpan_install.plを実行します。

$ tar xvzf Sledge-1.11.tar.gz
$ cd Sledge-1.11
# perl eg/cpan_install.pl

するとCPANモジュールのコンフィギュレーションが始まるので質問に対して適当に答えていきます(ほぼ全てデフォルトでOKでした)。その後、Sledgeに必要なモジュールのインストールが対話式で始まるので、全てデフォルト通りに答えます。これが終わるとSledgeに必要なモジュールのほぼ全てがインストールされます。いくつか、なぜかcpan_install.plでもインストールできないモジュールがあるので、残りは

$ perl Makefile.PL

とやると

Warning: prerequisite Apache::Request 0 not found.
Warning: prerequisite Class::Fields 0 not found.
Warning: prerequisite Test::Inline 0 not found.

というように足りないモジュールを教えてくれるので、これはCPANから取ってきて手動でインストールします。ただし、Apache::Requestは今回はlibapreq2を使うのでインストールする必要はありません。

あとは先ほどのようにMakefileを作成してmake && make installします。

$ perl Makefile.PL
$ make
# make install

ここで/usr/local/lib/perl5/site_perl/5.8.7配下にSledgeがインストールされるのですが、このままではmod_perl2に対応していないので動きません。というわけでこちらを参考にmod_perl2に対応させてみます。

Sledge/Pages/Compat.pm
既存のCompat.pmを下記の内容で置き換えます。
package Sledge::Pages::Compat;
# $Id: Compat.pm,v 1.1.1.1 2003/02/13 06:59:36 miyagawa Exp $
#
# Tatsuhiko Miyagawa <miyagawa@edge.co.jp>
# Livin' On The EDGE, Co., Ltd..
#
 
use strict;
use mod_perl;
use constant MOD_PERL2 => (defined $ENV{MOD_PERL} && $mod_perl::VERSION > 1.99);
use constant MOD_PERL1 => (defined $ENV{MOD_PERL} && !MOD_PERL2);
 
sub import {
    my $base = MOD_PERL1 ? 'Sledge::Pages::Apache' :
               MOD_PERL2 ? 'Sledge::Pages::Apache2::MP20' :
               'Sledge::Pages::CGI';
    eval qq{require $base};
    {
        my $pkg = caller;
        no strict 'refs';
        unshift @{"$pkg\::ISA"}, $base;
    }
}
 
1;
Sledge/Pages/Apache2/MP20.pm
新規に作成します。
package Sledge::Pages::Apache2::MP20;
 
use strict;
use base qw/Sledge::Pages::Base/;
use Apache2::RequestUtil;
use Sledge::Request::Apache2::MP20;
 
sub create_request {
    my($self, $r) = @_;
    my $req = Sledge::Request::Apache2::MP20->new($r
        || Apache2::RequestUtil->request );
    return $req;
}
 
1;
Sledge/Request/Apache2/MP20
これも新規に作成します。
package Sledge::Request::Apache2::MP20;
 
use Apache2::Request;
use Apache2::Upload;
use Apache2::Const -compile => qw(:common);
 
our @ISA = qw(Apache2::Request);
 
sub new {
    my($class, $r, @args) = @_;
    my $self = bless {
        r => Apache2::Request->new($r, @args),
        _my_table => '',
    }, $class;
    my %table;
    for my $key ($self->{r}->param) {
        my @ret = $self->{r}->param($key);
        $table{$key} = scalar @ret > 1 ? [@ret] : $ret[0];
    }
    $self->{_my_table} = \%table;
    return $self;
}
 
sub param {
    my $self = shift;
    my($key, $val) = @_;
    my $table = $self->{_my_table};
    unless(defined $key) {
        return keys %{$table};
    }
    if(defined $val){
        $table->{$key} = $val;
        $self->{_my_table} = $table;
    }
    my $ret = $table->{$key};
    if(ref $ret eq 'ARRAY') {
        return wantarray ? @$ret : $ret->[0];
    } else {
        return $ret;
    }
}
 
sub send_http_header {
    my $self = shift;
    my $type = shift;
    $self->{r}->content_type($type) if($type);
}
 
sub header_in {
    my $self = shift;
    $self->{r}->headers_in->get($_[0]);
}
 
sub header_out {
    my($self, $key, @v) = @_;
    if($key eq 'Content-Length'){
        $self->{r}->set_content_length(shift @v);
    }elsif($key =~ /^(?:Set-Cookie|Location)$/){
        $self->{r}->err_headers_out->add($key => $_) for @v;
    }elsif($key ne 'Content-Type'){
        $self->{r}->content_type(shift @v);
    }else{
        $self->{r}->headers_out->add( $key => $_ ) for @v;
    }
}
 
1;

つまるところ、mod_perl2用のRequestクラスとPagesクラスを作成して、それをCompat.pmで使うようにしているわけです。

これで本当に動くのかどうかは、こちらのhelloプロジェクトのサンプルで検証してみてください。ちなみにhttpd.confの設定はここに書かれているままだと動作しないので、私は下記のようにしています。

LoadModule perl_module /usr/lib/apache2/modules/mod_perl.so
LoadModule apreq_module /usr/lib/apache2/modules/mod_apreq2.so
<Files *.cgi>
  SetHandler perl-script
  PerlHandler ModPerl::Registry
  Options +ExecCGI
  PerlSendHeader On
  Order allow,deny
  Allow from all
</Files>
 
<Directory htdocsディレクトリ>
  PerlSetEnv PERL5LIB /home/kazuhiro/public_html/sledge/hello/lib/
</Directory>

私の環境ではいちおうこれでSledge + mod_perl2が無事動いてHello worldが表示されました!

もし間違いやなどあればぜひご指摘下さい。

2005/09/20追記: kurtさんのつっこみを反映しました。

2006/08/23追記: nipotanさんのコメントを受けてSledge::Request::Apache2::MP20->paramのunless ($key) の部分を修正しました。気づくの遅くてスイマセン。

本日のツッコミ(全3件) [ツッコミを入れる]
# kurt (2005-10-09 12:37)

sledgeとmod_perl2でここに行き着きました!動きましたよ!<br>なのですが、Sledge::DispatchQueryを使うとどうやらparamの値がとれていないみたいなのです。<br>Sledge/Request/Apache2/MP20.pmのnewしているところで<br><br>$self->{_my_table} = %table;<br><br>!レファレンスを渡していないからということに気づきました。<br>(そのままコピペだったのでわからなかったです、、)<br>まだシビアに検証はしていないので業務に使えるかわからないですが、とにかく助かりました。

# kurt (2005-10-09 12:38)

追記で<br><br>$self->{_my_table} = \%table;<br><br>これでHoge::Pages::Index(Pagesのベースクラスを継承したモジュール)のdispatch_xxxで$self->r->paramしてもURLの引数を取得することができます

# おいぬめ (2005-10-09 13:10)

ご指摘ありがとうございます。<br>日記の整形時に<br> $self->{_my_table} = %table;<br>となってしまっていたようです。おっしゃるようにここはリファレンスが正解ですね。


Bookmark: あんてな | ぶっくまーく | 覚え書き | Project Amateras | ExcelPettyCashBook | FreeStyle Wiki

2002|10|11|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|11|12|
2008|01|02|03|04|05|06|07|08|10|11|12|
2009|01|
人気ブログランキング - おいぬま日報(不定期)