<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>はらぺこ日誌 &#187; Apache</title>
	<atom:link href="https://blog.harapeko.jp/tag/apache/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.harapeko.jp</link>
	<description>株式会社はらぺこ 公式ブログ</description>
	<lastBuildDate>Mon, 30 Oct 2017 14:32:56 +0000</lastBuildDate>
	<language>ja</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.9.2</generator>
	<item>
		<title>Apache 周りの設定と、WebDAV 設定</title>
		<link>https://blog.harapeko.jp/2010/11/05/apache-webdav-setting/</link>
		<comments>https://blog.harapeko.jp/2010/11/05/apache-webdav-setting/#comments</comments>
		<pubDate>Fri, 05 Nov 2010 06:10:31 +0000</pubDate>
		<dc:creator><![CDATA[村山 俊之]]></dc:creator>
				<category><![CDATA[技術メモ]]></category>
		<category><![CDATA[活動記録]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[WebDAV]]></category>
		<category><![CDATA[サーバー管理]]></category>

		<guid isPermaLink="false">http://blog.harapeko.jp/?p=144</guid>
		<description><![CDATA[会社サーバー絡みで最近行った設定に関するメモです。 サーバー全体の動作が重くなるのをどうにかする さくらの V [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>会社サーバー絡みで最近行った設定に関するメモです。<br />
<span id="more-144"></span></p>
<h3>サーバー全体の動作が重くなるのをどうにかする</h3>
<p>さくらの VPS を利用するようになってから、サーバー全体の動作が重いのが気になっていました。結論から言うと、 Apache がメモリーを食いつぶし、スワップを引き起こしまくっていたからでした。</p>
<p>Trac のページやこのブログ、会社のトップページでさえ、表示するのにやたらと時間がかかるので、 ssh で接続して状況を見ようとすると、その ssh での応答も非常に時間がかかるという状態。まさかこれが単体の専用サーバーと VPS の差だとは到底思えなかったので、 ps -AF するなり top するなりして軽く状況を見てみると、メモリーどころかスワップ領域もほぼフル回転で httpd が食いつぶしていた。こりゃああかんと言うことで、ネットで調べつつ設定を修正…。</p>
<h4>起動するプロセスの数を減らす</h4>
<p>とりあえず応急処置と言うことで、一度に起動するプロセスの数を減らすことを考えてみた。以下のサイトが参考になりました。</p>
<ul>
<li><a href="http://labs.unoh.net/2008/03/apache_mpm.html">ウノウラボ Unoh Labs: Apache MPM の基礎をしっかりと理解しよう！</a></li>
</ul>
<p>まず <a href="http://httpd.apache.org/docs/2.2/mpm.html" title="マルチプロセッシングモジュール (MPM) - Apache HTTP サーバ">MPM</a> に何を選択しているのかを知る必要があります。 CentOS を採用しているさくらの VPS では prefork MPM が選択されていました。</p>
<pre>
$ cat /etc/sysconfig/httpd
# Configuration file for the httpd service.

#
# The default processing model (MPM) is the process-based
# 'prefork' model.  A thread-based model, 'worker', is also
# available, but does not work with some modules (such as PHP).
# The service must be stopped before changing this variable.
#
#HTTPD=/usr/sbin/httpd.worker

(以下略)
</pre>
<p>その場合、 httpd.conf ファイルにて修正すべきは、以下の部分と言うことになります。</p>
<pre>
&lt;IfModule prefork.c&gt;
StartServers       8
MinSpareServers    5
MaxSpareServers   20
ServerLimit      256
MaxClients       256
MaxRequestsPerChild  4000
&lt;IfModule&gt;
</pre>
<p>基本的に社員2名の会社で社内サービスがメイン、会社サイトもこのブログもそれほど頻繁にアクセスされているわけでもないのに、プロセス 256個同時起動はまずあり得ないでしょう。プロセス 1つで 70MB ぐらい消費してしまうのに、メモリー 512MB、スワップ領域 2GB でプロセスをそんなに確保できるわけがありません。</p>
<p>また、待機するプロセス数の最大 20も大きすぎます。一度作られた待機プロセスは Apache を再起動でもしない限りは残ったままになってしまうらしく、メモリー使用量を抑えたいのであれば、この数を減らしてやる必要があります。</p>
<p>というわけで、変更後の内容は以下の通りです。</p>
<pre>
&lt;IfModule prefork.c&gt;
StartServers       8
MinSpareServers    5
MaxSpareServers   10
ServerLimit       15
MaxClients        15
MaxRequestsPerChild  4000
&lt;/IfModule&gt;
</pre>
<p>とりあえずこの設定で数日間動かしてみたところ、それでもまだメモリーは景気よく食いつぶされているものの、重たくて使い物にならないような状況には至らなくなりました。</p>
<h4>使わなさそうなモジュールをざっくり外す</h4>
<p>1つ1つのプロセスが消費するメモリー容量がそもそも大きいので、シェイプアップも図ってみることにしました。デフォルトでロードするよう設定されているモジュール類でも、必ずしも全て必要なわけではなく、使わないモジュールを外すことでメモリー使用量を抑えることができるという<a href="http://memo.majide.com/index.php?%A1%DAApache%A1%DB%A5%E2%A5%B8%A5%E5%A1%BC%A5%EB%A4%CE%BA%EF%BD%FC%A4%CB%A4%E8%A4%EA%A5%E1%A5%E2%A5%EA%A4%F2%C0%E1%CC%F3%A4%B9%A4%EB" title="【Apache】モジュールの削除によりメモリを節約する - (・∀・)イイ!!Memo">情報</a>を見つけたので、<a href="http://httpd.apache.org/docs/2.2/mod/" title="モジュール一覧 - Apache HTTP サーバ">Apache のドキュメント</a>とにらめっこしながら、今は使っていないし近い将来使う予定もなさそうなモジュールを威勢よく外してみました。</p>
<pre>
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule auth_digest_module modules/mod_auth_digest.so
LoadModule authn_file_module modules/mod_authn_file.so
#LoadModule authn_alias_module modules/mod_authn_alias.so
#LoadModule authn_anon_module modules/mod_authn_anon.so
#LoadModule authn_dbm_module modules/mod_authn_dbm.so
LoadModule authn_default_module modules/mod_authn_default.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_owner_module modules/mod_authz_owner.so
#LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
#LoadModule authz_dbm_module modules/mod_authz_dbm.so
LoadModule authz_default_module modules/mod_authz_default.so
#LoadModule ldap_module modules/mod_ldap.so
#LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
#LoadModule include_module modules/mod_include.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule logio_module modules/mod_logio.so
LoadModule env_module modules/mod_env.so
#LoadModule ext_filter_module modules/mod_ext_filter.so
LoadModule mime_magic_module modules/mod_mime_magic.so
LoadModule expires_module modules/mod_expires.so
#LoadModule deflate_module modules/mod_deflate.so
LoadModule headers_module modules/mod_headers.so
#LoadModule usertrack_module modules/mod_usertrack.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule mime_module modules/mod_mime.so
LoadModule dav_module modules/mod_dav.so
#LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
#LoadModule info_module modules/mod_info.so
LoadModule dav_fs_module modules/mod_dav_fs.so
LoadModule vhost_alias_module modules/mod_vhost_alias.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule dir_module modules/mod_dir.so
#LoadModule actions_module modules/mod_actions.so
#LoadModule speling_module modules/mod_speling.so
#LoadModule userdir_module modules/mod_userdir.so
LoadModule alias_module modules/mod_alias.so
LoadModule rewrite_module modules/mod_rewrite.so
#LoadModule proxy_module modules/mod_proxy.so
#LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
#LoadModule proxy_http_module modules/mod_proxy_http.so
#LoadModule proxy_connect_module modules/mod_proxy_connect.so
#LoadModule cache_module modules/mod_cache.so
#LoadModule suexec_module modules/mod_suexec.so
#LoadModule disk_cache_module modules/mod_disk_cache.so
#LoadModule file_cache_module modules/mod_file_cache.so
#LoadModule mem_cache_module modules/mod_mem_cache.so
LoadModule cgi_module modules/mod_cgi.so
#LoadModule version_module modules/mod_version.so
</pre>
<p>厳密にはこれに加えて、さらに <code>conf.d/proxy_ajp.conf</code> や <code>conf.d/welcome.conf</code> の中身をコメントアウトしてみたりもしています。結果として、メモリー使用量はプロセス当たり 70MB ぐらいだったのが 50MB ぐらいまでスリムアップしました。</p>
<h3>WebDAV 設定</h3>
<p>社内で一時的なファイルのやりとりをするのに使用する共有フォルダ的なものが欲しかったので、WebDAV を設定して Web フォルダとして使用することにしました。要件としては以下の通りです。</p>
<ul>
<li>クライアントは Windows および Mac OS X (あとたまに Ubuntu)。</li>
<li>社外には公開しない。
<ul>
<li>認証が必要。匿名アクセスは不許可。</li>
<li>SSL による通信の保護が必要。</li>
</ul>
</li>
</ul>
<p>まず、SSL を使用するため、 developer.harapeko.jp サブドメインを使用することにしました。 WebDAV の為のディレクトリは、 developer.harapeko.jp サブドメイン用に用意しているディレクトリ下に作成することにします。</p>
<pre>
$ mkdir -p /var/www/vhosts/developer/dav/davroot
</pre>
<p><code>dav</code> ディレクトリ、<code>dav/davroot</code> ディレクトリの両方に、 apache ユーザーが書き込みを行う権限が必要です。</p>
<p>次に、ダイジェスト認証用の認証ファイルを <code>dav</code>ディレクトリ下に作成します。 realm を <code>DAV</code> とする場合、</p>
<pre>
$ htdigest -c /var/www/vhosts/developer/dav/.htdigest DAV murachi
</pre>
<p>とかやって、パスワードを設定します。 2人目以降は <code>-c</code> オプションは不要です。</p>
<p>そして、<code>conf.d/ssl.conf</code> (SSL が適用されているヴァーチャルホストに対して設定を行うので、<code>conf/httpd.conf</code> ではないという点に注意) の <code>&lt;VirtualHost&gt;</code> セクション内に、以下の設定を書き加えました。</p>
<pre>
&lt;ifmodule mod_dav.c&gt;
    DavLockDB /var/www/vhosts/developer/dav/DavLock

    Alias /dav /var/www/vhosts/developer/dav/davroot
    &lt;Location /dav&gt;
        Order Allow,Deny
        Allow from all
        Options +Indexes
        Dav On

        AuthType Digest
        AuthName DAV
        AuthUserFile /var/www/vhosts/developer/dav/.htdigest
        &lt;LimitExcept OPTIONS&gt;
            Require valid-user
        &lt;/LimitExcept&gt;
    &lt;/Location&gt;
    &lt;Location /&gt;
        Header add MS-Author-Via &quot;DAV&quot;
    &lt;/Location&gt;
&lt;/ifmodule&gt;
</pre>
<p>あとは Apache を再起動すれば ok です。</p>
<p>設定ファイルについて軽く解説すると、まず、最後の</p>
<pre>
    &lt;Location /&gt;
        Header add MS-Author-Via &quot;DAV&quot;
    &lt;/Location&gt;
</pre>
<p>の部分は、Windows から Web フォルダとしてアクセスする場合に必ず必要になります。この記述がないと、Windows クライアントは <code>/_vti_inf.html</code> ファイルが見つからないなどという意味不明なエラーを吐いてこけてしまいます。この設定のロケーションは <code>/</code> でなければなりません。</p>
<p>それから、</p>
<pre>
        &lt;LimitExcept OPTIONS&gt;
            Require valid-user
        &lt;/LimitExcept&gt;
</pre>
<p>の部分は、本来であれば</p>
<pre>
        Require valid-user
</pre>
<p>のみであるべきなのですが、Digest 認証を用いる場合には、上記のように書かないと、やはり Windows の Web フォルダとして利用することができません。これはどうやら Windows の (IE の?) バグのようで、 OPTIONS メソッドでアクセスする際にのみ、 Digest 認証が理解できないからなのだそうです。</p>
<p>この辺の、 Windows の Web フォルダ機能に絡んだ設定方法については、以下のサイトが参考になりました。</p>
<ul>
<li><a href="http://kamoland.com/wiki/wiki.cgi?WebDAV%A5%B5%A1%BC%A5%D0%A4%CE%B9%BD%C3%DB">WebDAVサーバの構築 &#8211; KamoLand</a></li>
<li><a href="http://d.hatena.ne.jp/rero/20050524/p2">Web フォルダで WebDAV &#8211; reroの日記</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://blog.harapeko.jp/2010/11/05/apache-webdav-setting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>会社サーバーをさくらの VPS に移転しました。</title>
		<link>https://blog.harapeko.jp/2010/10/15/move-to-sakura-vps/</link>
		<comments>https://blog.harapeko.jp/2010/10/15/move-to-sakura-vps/#comments</comments>
		<pubDate>Fri, 15 Oct 2010 07:54:44 +0000</pubDate>
		<dc:creator><![CDATA[村山 俊之]]></dc:creator>
				<category><![CDATA[技術メモ]]></category>
		<category><![CDATA[活動記録]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[Postfix]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[Trac]]></category>
		<category><![CDATA[サーバー管理]]></category>
		<category><![CDATA[ドメイン]]></category>

		<guid isPermaLink="false">http://blog.harapeko.jp/?p=140</guid>
		<description><![CDATA[会社サーバーとして、これまでファーストサーバさんのデルタ1 というサービスを利用させて頂いていたのですが、のっ [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>会社サーバーとして、これまで<a href="http://www.fsv.jp/">ファーストサーバ</a>さんの<a href="http://www.senyu.jp/dt/">デルタ1</a> というサービスを利用させて頂いていたのですが、のっぴきならない事由 (ごくごく経済的な事情 T-T) により、<a href="http://www.sakura.ad.jp/">さくらインターネット</a>さんの<a href="http://vps.sakura.ad.jp/">さくらのVPS</a> というサービスに乗り換えることにしました。そして、その移転作業が完了致しましたので、ご報告申し上げます。</p>
<p>と、いっても、現状何かサービスを展開しているわけでも無し、本ブログもこれまで通りそのまま閲覧できますので、「だから何?」とか言われちゃうと困ってしまうわけですが…。</p>
<p>今回の移転作業に於きましては、<strong>すべての作業内容を逐次メモに取り、その内容を公開しております</strong>。弊社のように、既に他社の専用サーバや VPS を用いてサーバーを構築しているものの、とっても安価でよさげなさくらの VPS に移行したいなぁなどとお考えの方々に、少しでも参考になれば幸いです。</p>
<ul>
<li><a href="http://developer.harapeko.jp/trac/original/ideanote/wiki/HowTo/SakuraVpsSetup">さくらの VPS セットアップメモ</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://blog.harapeko.jp/2010/10/15/move-to-sakura-vps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>とりあえず svn の設定だけ。</title>
		<link>https://blog.harapeko.jp/2009/06/25/svn-setting/</link>
		<comments>https://blog.harapeko.jp/2009/06/25/svn-setting/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 00:17:56 +0000</pubDate>
		<dc:creator><![CDATA[村山 俊之]]></dc:creator>
				<category><![CDATA[技術メモ]]></category>
		<category><![CDATA[活動記録]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[otoco]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[サーバー管理]]></category>

		<guid isPermaLink="false">http://blog.harapeko.jp/?p=44</guid>
		<description><![CDATA[初っぱなから 40分オーバーです (汗。2時間だけ作業するってのは難しいな。 とりあえず svn だけ設定しま [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>初っぱなから 40分オーバーです (汗。2時間だけ作業するってのは難しいな。</p>
<p>とりあえず <a href="http://svn.harapeko.jp/otoco/">svn だけ設定</a>しました (←まだ匿名アカウントを用意していないので私以外はアクセスできませんが…)。Subversion/WebDAV は初めて設定するのでちょっと手こずりました。</p>
<p>設定の際に参考にさせて頂いたサイトを以下に記します (敬称略)。多謝!!</p>
<ul>
<li><a href="http://www.sera.desuyo.net/WebDAV/selinux.html">Fedora Core 3 で WebDAV/Subversion を使おう</a>
<p>基本的な内容は概ねここに書かれていました。SELinux は使っていないのですが…。</p>
</li>
<li><a href="http://saikyoline.jp/wiki/index.php?%A5%E1%A5%E2%2FWebDAV%A4%C7Subversion">メモ/WebDAVでSubversion &#8211; SaikyoLine.jp</a>
<p>Apache 側での設定がもう少し詳しく触れられています。ユーザー毎の制御についても書かれています。</p>
</li>
<li><a href="http://wiki.livedoor.jp/syo1976/d/AuthzSVNAccessFile">AuthzSVNAccessFile &#8211; 気の向くままに･･･ &#8211; livedoor Wiki（ウィキ）</a>
<p>ユーザー毎の制御を行う AuthzSVNAccessFile の設定方法について解説されています。</p>
</li>
<li><a href="http://g-chan.dip.jp/square/archives/2008/02/subversionwebdav.html">G-chan Square &#8211; subversionとWebDAVと</a>
<p>Subversion/WebDAV でアクセス時に 403 Forbidden エラーが出て失敗してしまう場合は、こちらをチェックしましょう。私もこれでハマりました (^_^;A 。</p>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://blog.harapeko.jp/2009/06/25/svn-setting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mod_perl であほプログラムを作ってみた。</title>
		<link>https://blog.harapeko.jp/2008/12/29/mod-perl-aho/</link>
		<comments>https://blog.harapeko.jp/2008/12/29/mod-perl-aho/#comments</comments>
		<pubDate>Mon, 29 Dec 2008 12:41:34 +0000</pubDate>
		<dc:creator><![CDATA[村山 俊之]]></dc:creator>
				<category><![CDATA[技術メモ]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[mod_perl]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://blog.harapeko.jp/?p=21</guid>
		<description><![CDATA[はじめに 自社開発で作ろうとしていた物が実は mod_perl に対応した Web アプリなのですが、そういえ [&#8230;]]]></description>
				<content:encoded><![CDATA[<h3>はじめに</h3>
<p>自社開発で作ろうとしていた物が実は mod_perl に対応した Web アプリなのですが、そういえば mod_perl ってまともに弄ったこと無かったなぁとか思ったので、風邪も引いて頭も回らないことだし少し脱線するかとばかりに遊んでみました。</p>
<p>世間一般においてはちっともはやらない mod_perl 。かろうじて拾う話題もせいぜい Apache::Registry を用いた既存 CGI の高速化とかその程度の話で、本格的に Perl で Apache モジュールを作ろうみたいな話になると本を買うか英語で情報を探すしかなかったりするのが現状のようです (あるいはおいらの探し方が悪いのかも知れませんが…)。参考にしたのは mod_perl の公式サイトにあるドキュメントでした。</p>
<ul>
<li><a href="http://perl.apache.org/docs/2.0/index.html">mod_perl: mod_perl 2.0 Documentation</a></li>
</ul>
<p>これ全体をぼえ～っと眺めてみても何から手をつければいいのかよくわからないのですが、<a href="http://perl.apache.org/docs/2.0/user/config/config.html#Examples" title="mod_perl: mod_perl 2.0 Server Configuration#Examples">この辺</a>を見てみるとサンプルを見つけることができたので、これを参考に作ってみることにします。</p>
<p><span id="more-21"></span></p>
<h3>動かす場所 (URI) を決める</h3>
<p>とりあえず弊社の環境では test という名のサブドメインを設け、 <code>http://test.harapeko.jp/aho</code> にアクセスするとプログラムが実行できるということにしてみました。もちろん、サブドメインを設けるには、named (BIND) の設定追加と、 Apache 側の設定が必要です。</p>
<p>サブドメインとか面倒な人は、この辺は読み飛ばしちゃってください。BIND の設定については、ここでは省きます。</p>
<p>Apache 側の設定ですが、あとでここに mod_perl に関する設定も書き加えるので、 <code>mod_perl.c</code> モジュールが見える場所に記述するようにしてください (<code>mod_perl.c</code> を <code>LoadModule</code> している特別な設定ファイルがあるのであれば、その中に記述します)。</p>
<pre>
&lt;IfModule mod_perl.c&gt;

&lt;VirtualHost *:80&gt;
  ServerName test.harapeko.jp
  DocumentRoot /var/www/vhosts/test/htdocs
  ErrorLog logs/test-error_log
  CustomLog logs/test-access_log common
&lt;/VirtualHost&gt;

&lt;/IfModule&gt;
</pre>
<h3>mod_perl モジュールとしてあほプログラムを書く</h3>
<p>mod_perl モジュールとしてロードできるのは、<code>@INC</code> のパスが通ったディレクトリに置いてあるモジュールファイルだけです。つまり、通常は Cpan などから正規にインストールしたモジュールだけです。</p>
<p>ただ、 mod_perl の実行中は Apache の設定で <code>ServerRoot</code> に設定されているディレクトリにも <code>@INC</code> のパスが通るようなので、テスト目的でちょっとしたプログラムを書きたいだけならば、この配下にファイルを置いていけばいいでしょう。弊社の環境では <code>/etc/httpd</code> が <code>ServerRoot</code> に設定されているので、例えばモジュールのパッケージ名を <code>MpTest::AhoAho</code> にするのであれば、モジュールファイルは <code>/etc/httpd/MpTest/AhoAho.pm</code> とします。</p>
<p>以下、そのサンプルコードです。</p>
<pre>
package MpTest::AhoAho;

use strict;
use utf8;

use Encode;
use Apache2::RequestRec ();
use Apache2::RequestIO ();
use Apache2::Const -compile =&gt; qw( :common :http );

my $urlEncode;

sub handler {
	my $r = shift;
	$r-&gt;content_type( 'text/html; charset=UTF-8' );
	if ( $r-&gt;method eq 'GET' )
	{
		$r-&gt;print( encode( 'UTF-8', &lt;&lt;ENDLINE ) );
&lt;html&gt;&lt;head&gt;&lt;title&gt;あほあほ!!&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;あほあほ!!&lt;/h1&gt;
&lt;form method=&quot;POST&quot; action=&quot;${ \ $r-&gt;uri }&quot;&gt;
&lt;p&gt;どう思いますか? &amp;gt;&lt;input type=&quot;text&quot; name=&quot;hoge&quot; size=&quot;50&quot;&gt;
&lt;input type=&quot;submit&quot; value=&quot;送信&quot;&gt;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
ENDLINE
	}
	elsif ( $r-&gt;method eq 'POST' )
	{
		my $length = $r-&gt;headers_in-&gt;{ 'Content-Length' };
		if ( $length &gt; 1024 ){
			$r-&gt;status( Apache2::Const::HTTP_BAD_REQUEST );
			$r-&gt;print( encode( 'UTF-8', &lt;&lt;ENDLINE ) );
&lt;html&gt;&lt;head&gt;&lt;title&gt;話が長すぎじゃばっかも～～～ん!!!&lt;/title&gt;
&lt;body&gt;
&lt;h1&gt;話が長すぎじゃばっかも～～～ん!!!&lt;/h1&gt;
&lt;p&gt;1KB 以内に納めて来い!!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&quot;${ \ $r-&gt;uri }&quot;&gt;もう一回?&lt;/a&gt;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
ENDLINE
			return Apache2::Const::OK;
		}
		my $buf;
		$r-&gt;read( $buf, $length ) == $length	or die '???';
		my $request = $urlEncode-&gt;( $buf );
		my $comment = &quot;$request-&gt;{ hoge } としか言えない貴様はやっぱりあほだ!!!&quot;;
		$r-&gt;print( encode( 'UTF-8', &lt;&lt;ENDLINE ) );
&lt;html&gt;&lt;head&gt;&lt;title&gt;あほあほあほ!!!&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;$comment&lt;/h1&gt;

&lt;p&gt;
ENDLINE
		for ( 1 .. 1000 )
		{
			$r-&gt;print( encode( 'UTF-8', &quot;$comment &quot; ) );
		}
		$r-&gt;print( encode( 'UTF-8', &lt;&lt;ENDLINE ) );
&lt;/p&gt;

&lt;hr&gt;
&lt;p&gt;&lt;a href=&quot;${ \ $r-&gt;uri }&quot;&gt;もう一回?&lt;/a&gt;&lt;/p&gt;

&lt;/body&gt;
&lt;/html&gt;
ENDLINE
	}
	return Apache2::Const::OK;
}

$urlEncode = sub {
	my $url = shift;
	my %map;
	for my $pair ( split /&amp;/, $url )
	{
		my ( $name, $val ) = split /=/, $pair;
		$name =~ tr/+/ /;
		$name =~ s/%([\da-f][\da-f])/pack 'H2', $1/ieg;
		$name = decode( 'UTF-8', $name );
		$val =~ tr/+/ /;
		$val =~ s/%([\da-f][\da-f])/pack 'H2', $1/ieg;
		$val = decode( 'UTF-8', $val );
		$map{ $name } = $val;
	}
	return \%map;
};

1;
__END__
</pre>
<h3>URI アクセスに応じてモジュールが動くように設定する</h3>
<p>プログラムができたら、それを URI に関連づけます。先の手順でサブドメインの追加を行っていれば、その <code>&lt;VertualHost&gt;</code> ディレクティブの中に、以下のように設定を追加します。</p>
<pre>
&lt;VirtualHost *:80&gt;
  ServerName test.harapeko.jp
  DocumentRoot /var/www/vhosts/test/htdocs
  ErrorLog logs/test-error_log
  CustomLog logs/test-access_log common

  # 追加 --ここから
  PerlModule APR::Table  # 要らないかも。後述
  PerlModule MpTest::AhoAho
  &lt;Location /aho&gt;
    SetHandler modperl
    PerlResponseHandler MpTest::AhoAho
  &lt;/Location&gt;
  # 追加 --ここまで
&lt;/VirtualHost&gt;
</pre>
<p>これで設定完了です。 <code>apache2ctl configtest</code> (または <code>/etc/init.d/httpd configtest</code> 等) で設定ファイルの文法を確認したら、 <code>apache2ctl restart</code> (または <code>/etc/init.d/httpd restart</code> 等) で再起動しましょう。</p>
<h3>実際に動いている物サンプル</h3>
<p><a href="http://test.harapeko.jp/aho" title="あほあほ!!">実際に動いているサンプルです</a>。もうなんて言うか<strong>激しくごめんなさい</strong>。 orz</p>
<h3>解説</h3>
<p>それでは解説です。まず、 Apache 側の設定ファイル中でキモになる記述は以下の部分です。</p>
<pre>
  PerlModule MpTest::AhoAho
  &lt;Location /aho&gt;
    SetHandler modperl
    PerlResponseHandler MpTest::AhoAho
  &lt;/Location&gt;
</pre>
<p><code>PerlModule</code> はモジュールをロードする宣言で、この行は実は無くても動きます。が、書いておくと Apache の起動時にロードしてコンパイルまで済ませておいてくれるので、多分早くなるんだと思います (多分ってなんだよ＞ヲレ)。</p>
<p><code>PerlResponseHandler</code> は、Apache がクライアントにレスポンスを返す際に呼び出すハンドラモジュールを指定する宣言です。つまり、大雑把に言うと、ここで指定したモジュールの <code>handler</code> メソッドが、 URI アクセス時に呼び出されます。上記のサンプルではこの宣言は <code>&lt;Location /aho&gt;</code> ディレクティブ内に記述されているので、「<code>/aho</code> の URI にアクセスしてきた場合は、応答時に <code>MpTest::AhoAho-&gt;handler</code> を実行する」という意味になります。</p>
<p><code>SetHandler</code> は <code>PerlResponseHandler</code> などのハンドラを指定する宣言を書く場所では必ず書いておく必要のある宣言です。引数は <code>modperl</code> と <code>perl-script</code> の 2種類があって、後者はレガシーなスクリプトとの互換性を重視するためか、プログラム中でそのまま使える <code>print</code> 関数や <code>%ENV</code> などにアクセスできるようになります。今回は敢えてそれができない <code>modperl</code> の方を選んでみました。</p>
<p>次にプログラムですが、内容的には <code>GET</code> アクセス時は質問ページを、 <code>POST</code> アクセス時は罵倒ページを表示するというただそれだけの物です。但し POST したデータが長すぎる (1KB を超える) 場合には自前でエラーを表示するようにしています (ちゃんと <code>400 Bad Request</code> を返しているので、IE で試すと IE 謹製のエラー画面が表示されるはずです)。</p>
<p><code>use Apache2::*</code> シリーズはいずれもほぼ必須と考えていいと思います。<code>Apache2::RequestRec</code> と <code>Apache2::RequestIO</code> は、ハンドラ内で最初に受け取るリクエストオブジェクトの各メソッドにアクセスできるようにするためのモジュールで、前者はステータス値や HTTP ヘッダー、環境変数などへのアクセス用、後者はコンテンツの入出力用です。例えば <code>$r-&gt;method</code> や <code>$r-&gt;uri</code>、 <code>$r-&gt;headers_in</code> などを参照したり、<code>$r-&gt;content_type</code> で出力用の <code>Content-type:</code> ヘッダーを設定したりするには <code>Apache2::RequestRec</code> が、 <code>$r-&gt;print</code> でコンテンツを出力したり、 <code>$r-&gt;read</code> で POST を入力したりするには <code>Apache2::RequestIO</code> がそれぞれ必要になります。</p>
<p><code>Apache2::Const</code> モジュールは各種定数の定義です。引数リストで使用する定数を宣言できますが、その最初に <code>'-compile'</code> と入れておくと、定数名をグローバル名前空間に展開しません (その場合は、 <code>Apache2::Const::<em>HOGE_FUGA</em></code> としてアクセスします)。</p>
<p>Apache はこのモジュールの <code>handler</code> 関数を呼び出し、最初の引数にリクエストオブジェクトを渡します。そして、自前の処理を実行しつつ、リクエストオブジェクトの各メソッドを適切に呼んであげてから、 <code>Apache2::Const::OK</code> を返してあげればいい、という流れです。あとは、<a href="http://perl.apache.org/docs/2.0/api/index.html" title="mod_perl: mod_perl 2.0 API">API のリファレンス</a>とにらめっこしつつ読みこなしていただければ、やっていることは大体解ると思います。</p>
<h3><code>$r-&gt;headers_in</code> メソッド呼び出しでエラーが発生する場合</h3>
<p>ところで、 Apache 側の設定で、以下の行について説明していませんでしたが、</p>
<pre>
  PerlModule APR::Table  # 要らないかも。後述
</pre>
<p>この宣言は、 <code>$r-&gt;headers_in</code> メソッドにアクセスした際、以下のようなエラーが発生してしまうのを回避するためのものです。自宅で宅内サーバーにしているマシン@debian では発生しなかったのですが、会社サーバー@centos では発生するので、念のため付記しておきます。</p>
<pre>
[Mon Dec 29 18:47:51 2008] [error] [client 218.219.204.253] Can't locate object
method "FETCH" via package "APR::Table" at /etc/httpd/MpTest/AhoAho.pm line 32.\
n, referer: http://test.harapeko.jp/aho
</pre>
<p>この解決法については、以下のサイトを参考にしました。</p>
<ul>
<li><a href="http://mail-archives.apache.org/mod_mbox/perl-modperl/200409.mbox/%3CPine.LNX.4.44.0409211243080.6717-100000@cartman.nederhost.net%3E">Re: [mp2] APR::Table FETCH method not found (reported when using $r-&gt;headers_in-&gt;{Cookie}</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://blog.harapeko.jp/2008/12/29/mod-perl-aho/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
