<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.en.xsl"?>
<!-- English Revision: 421100 -->

<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->

<manualpage metafile="modules.xml.meta">
<parentdocument href="./">Developer Documentation</parentdocument>

<title>モジュールの Apache 1.3 から Apache 2.0 への移植</title>

<summary>
    <p>この文書は <code>mod_mmap_static</code> モジュールを Apache 2.0 用に移植した時に
    学んだ経験をもとに書いた、最初の手引き書です。まだまだ完全じゃないし、
    ひょっとすると間違っている部分もあるかもしれませんが、
    取っ掛りにはなるでしょう。</p>
</summary>

<section id="easy"><title>簡単な変更点</title>

    <section id="cleanup"><title>クリーンナップ ルーチン</title>
      <p>クリーンナップルーチンは <code>apr_status_t</code> 型である必要があります。
      そして、apr_status_t 型の値を返さなくてはなりません。
      クリーンナップ中のエラーを通知する必要がなければ、返り値は普通、
      <code>ARP_SUCCESS</code> です。たとえエラーを通知したとしても、
      すべてのコードがその通知をチェックしたり、
      エラーに応じた動作をするわけではないことに気をつけてください。</p>
    </section>


    <section id="init"><title>初期化ルーチン</title>

    <p>初期化ルーチンは処理全体から見てしっくりくるような意味を表すように、
    名前が変更されました。ですから、<code>mmap_init</code> から <code>mmap_post_config</code>
    のようにちょっと変更されました。
    渡される引数は大幅に変更され、次のようになりました。</p>

      <ul>
        <li><code>apr_pool_t *p</code></li>
        <li><code>apr_pool_t *plog</code></li>
        <li><code>apr_pool_t *ptemp</code></li>
        <li><code>server_rec *s</code></li>
      </ul>
    </section>

    <section id="datatypes"><title>データ型</title>
      <p>データ型のほとんどは <a
      href="http://apr.apache.org/">APR</a> に移されました。つまり、
      いくつかの名前が前述のように変更されています。
      施すべき変更点の簡単な一覧を以下に示します。</p>

      <ul>
        <li><code>pool</code> becomes <code>apr_pool_t</code></li>
        <li><code>table</code> becomes <code>apr_table_t</code></li>
      </ul>
    </section>
</section>

<section id="messy"><title>もっと厄介な変更点…</title>

    <section id="register-hooks"><title>フックの登録</title>
      <p>新しいアーキテクチャでは作成した関数を呼び出すのに
      一連のフックを使用します。このフックは、新しい関数
      <code>static void register_hooks(void)</code> を使って登録するよう、
      モジュールに書き足さなくてはなりません。
      この関数は、なにをすべきか一旦理解してしまえば、
      十分にわかりやすいものです。
      リクエストの処理のあるステージで呼び出さなくてはならない
      関数は登録する必要があります。ハンドラは登録する必要はありません。
      関数を登録できるフェーズはたくさんあります。
      それぞれのフェーズで、関数を呼び出す相対的な順番は、
      かなりの程度制御できます。</p>

    <p>以下は、<code>mod_mmap_static</code> に追加したコードです:</p>

      <example><pre>
static void register_hooks(void)
{
    static const char * const aszPre[]={ "http_core.c",NULL };
    ap_hook_post_config(mmap_post_config,NULL,NULL,HOOK_MIDDLE);
    ap_hook_translate_name(mmap_static_xlat,aszPre,NULL,HOOK_LAST);
};</pre>
      </example>

    <p>ここでは呼びだすべき二つの関数を登録しています。一つは
    <code>post_config</code> ステージ用 (ほとんどすべてのモジュール
    はこれが必要です) で、もう一つは <code>translate_name</code> フェーズ用です。
    それぞれの関数は名前は違うけれども形式は同じであることに注意してください。
    それでは、形式はどのようになっているでしょうか?</p>

      <example>
        ap_hook_<var>phase_name</var>(<var>function_name</var>,
        <var>predecessors</var>, <var>successors</var>, <var>position</var>);
      </example>

    <p>三つの位置が定義されています…</p>

      <ul>
        <li><code>HOOK_FIRST</code></li>
        <li><code>HOOK_MIDDLE</code></li>
        <li><code>HOOK_LAST</code></li>
      </ul>

    <p>位置を定義するには、上記の「位置」を指定し、
    修飾子である「先行」と「後行」で手を加えます。
   「先行」「後行」は、呼ばれるべき関数のリストです。
   「先行」は関数の実行前に呼ばれるもので、
   「後行」は実行後に呼ばれるものです。</p>

    <p><code>mod_mmap_static</code> の場合、<code>post_config</code>
    ステージでは必要ありませんが、
    <code>mmap_static_xlat</code> が core モジュールが名前の変換を実行した後に
    <strong>呼ばれなければなりません</strong>。
    そこで aszPre を使って <code>HOOK_LAST</code> の修飾子を定義しています。</p>
  </section>

    <section id="moddef"><title>モジュールの定義</title>
      <p>モジュールの定義を作成する際に注意しなければならない
      ステージの数は激減しています。古い定義は次のようになっていました。</p>

      <example><pre>
module MODULE_VAR_EXPORT <var>module_name</var>_module =
{
    STANDARD_MODULE_STUFF,
    /* initializer */
    /* dir config creater */
    /* dir merger --- default is to override */
    /* server config */
    /* merge server config */
    /* command handlers */
    /* handlers */
    /* filename translation */
    /* check_user_id */
    /* check auth */
    /* check access */
    /* type_checker */
    /* fixups */
    /* logger */
    /* header parser */
    /* child_init */
    /* child_exit */
    /* post read-request */
};</pre>
      </example>

    <p>新しい構造体はとってもシンプルです…</p>
      <example><pre>
module MODULE_VAR_EXPORT <var>module_name</var>_module =
{
    STANDARD20_MODULE_STUFF,
    /* create per-directory config structures */
    /* merge per-directory config structures  */
    /* create per-server config structures    */
    /* merge per-server config structures     */
    /* command handlers */
    /* handlers */
    /* register hooks */
};</pre>
      </example>

    <p>このうちのいくつかは古いものから新しいものに直接読み替えられるもので、
    いくつかはそうではありません。どうすればいいのかを要約してみます。</p>

    <p>直接読み替えられるステージ:</p>

    <dl>
      <dt><code>/* ディレクトリ設定作成関数 */</code></dt>
      <dd><code>/* ディレクトリ毎設定構造体作成 */</code></dd>

      <dt><code>/* サーバ設定作成関数 */</code></dt>
      <dd><code>/* サーバ毎設定構造体作成 */</code></dd>

      <dt><code>/* ディレクトリ設定マージ関数 */</code></dt>
      <dd><code>/* ディレクトリ毎設定構造体マージ */</code></dd>

      <dt><code>/* サーバ設定マージ関数 */</code></dt>
      <dd><code>/* サーバ毎設定構造体作成マージ */</code></dd>

      <dt><code>/* コマンド・テーブル */</code></dt>
      <dd><code>/* コマンド apr_table_t */</code></dd>

      <dt><code>/* ハンドラ */</code></dt>
      <dd><code>/* ハンドラ */</code></dd>
    </dl>

    <p>古い関数の残りのものはフックとして登録されるべきです。
    現時点で次のようなフック・ステージが定義されています…</p>

    <dl>
      <dt><code>ap_hook_post_config</code></dt>
      <dd>(以前の <code>_init</code> ルーチンが登録されるべき場所です)</dd>

      <dt><code>ap_hook_http_method</code></dt>
      <dd>(リクエストから HTTP メソッドを取得します (互換用))</dd>

      <dt><code>ap_hook_open_logs</code></dt>
      <dd>(特定のログのオープン)</dd>

      <dt><code>ap_hook_auth_checker</code></dt>
      <dd>(リソースが権限を必要とするかどうかの確認)</dd>

      <dt><code>ap_hook_access_checker</code></dt>
      <dd>(モジュール固有の制約の確認)</dd>

      <dt><code>ap_hook_check_user_id</code></dt>
      <dd>(ユーザ ID とパスワードの確認)</dd>

      <dt><code>ap_hook_default_port</code></dt>
      <dd>(サーバのデフォルト・ポートの取得)</dd>

      <dt><code>ap_hook_pre_connection</code></dt>
      <dd>(処理の直前に必要なことを実行。ただし accept 直後に呼ばれる)</dd>

      <dt><code>ap_hook_process_connection</code></dt>
      <dd>(プロトコルの処理)</dd>

      <dt><code>ap_hook_child_init</code></dt>
      <dd>(子プロセス起動直後)</dd>

      <dt><code>ap_hook_create_request</code></dt>
      <dd>(??)</dd>

      <dt><code>ap_hook_fixups</code></dt>
      <dd>(応答内容の生成を変更するラスト・チャンス)</dd>

      <dt><code>ap_hook_handler</code></dt>
      <dd>(応答内容の生成)</dd>

      <dt><code>ap_hook_header_parser</code></dt>
      <dd>(モジュールにヘッダの照会をさせる。ほとんどのモジュールでは使われません。post_read_request を使います)</dd>

      <dt><code>ap_hook_insert_filter</code></dt>
      <dd>(フィルタ・チェインにフィルタを挿入)</dd>

      <dt><code>ap_hook_log_transaction</code></dt>
      <dd>(リクエストについての情報を記録する)</dd>

      <dt><code>ap_hook_optional_fn_retrieve</code></dt>
      <dd>(オプションとして登録された関数の取得)</dd>

      <dt><code>ap_hook_post_read_request</code></dt>
      <dd>(リクエストを読みこんだ後、他のフェーズの前に呼ばれる)</dd>

      <dt><code>ap_hook_quick_handler</code></dt>
      <dd>リクエストの処理が始まる前に呼ばれる。キャッシュモジュールが
      使用している</dd>

      <dt><code>ap_hook_translate_name</code></dt>
      <dd>(URI をファイル名に変換する)</dd>

      <dt><code>ap_hook_type_checker</code></dt>
      <dd>(文書型の決定と設定。あるいはその片方)</dd>
    </dl>
  </section>
</section>
</manualpage>
