output_filterで出力を覗き見してみようよ

いろいろなモジュールのコードを読んで切り貼りして output_filter を書いてみました。
まだ動作が微妙で、コンテンツが途中で切れたりします。
このあたりは、日本語の資料が少ないのは当然、英語の資料も少ないです(;´Д`)。


まずは、output_filter を登録

// registers_hooksで
ap_register_output_filter("mod_my", my_output_filter, NULL,
                          AP_FTYPE_RESOURCE); // 最後の引数これでよいんだろうか

コンテントハンドラなどで add する。registerだけで動くかと思いきやこれを書かないと呼ばれない。

 ap_add_output_filter("mod_my", NULL, r, r->connection);


output_filter は出力の度に呼ばれるっぽい。
つまり、Apacheはコンテンツを一度に出力するのではないってことだ。


apr_bucket_read の最後の引数は、APR_BLOCK_READ/APR_NONBLOCK_READは、READの際にスレッドがブロックされるかという意味だと思うんだが。
どちらが主流なのか分からないのが痛い。

static char* content = "";           // このあたりは
static apr_size_t total_length = 0;  // 後でどうにかしよう

static int my_output_filter(ap_filter_t* f, apr_bucket_brigade* bb)
{
    request_rec* r = f->r;
    apr_bucket* backet;
    apr_size_t length = 0;
    apr_status_t read_status;

    if (r->main)
    {
        ap_remove_output_filter(f);
        return ap_pass_brigade(f->next, bb);
    }

    FUNC_TRACE("~~~~~~~~~~~~~~ output_filter for %s ~~~~~~~~~~~~~", r->unparsed_uri);

    APR_BRIGADE_FOREACH (backet, bb)
    {
        const char *str;

        if (APR_BUCKET_IS_EOS(backet))
        {
            return ap_pass_brigade(f->next, bb);
        }

        if (APR_BUCKET_IS_FLUSH(backet))
        {
            continue;
        }

//        read_status = apr_bucket_read(backet, &str, &length, APR_NONBLOCK_READ);
        read_status = apr_bucket_read(backet, &str, &length, APR_BLOCK_READ);
        if (read_status != APR_SUCCESS)
        {
            ERROR("apr_bucket_read error [\d]", read_status);
            return read_status;
        }

        FUNC_TRACE("[%s]", str);
        FUNC_TRACE("length = %d", length);
        content = apr_pstrcat(r->pool, content, str, NULL);// 怪しい
        total_length += length;
    }

    FUNC_TRACE("total_length = %d", total_length);

    return ap_pass_brigade(f->next, bb);
}


同じURIに対してでも、コンテンツが取れるときと、中途半端で切れるときがある。
というのが課題。
Apache 2.x系に対応した、Apacheモジュールの本誰か書いてくれないかなぁ。

Apacheモジュール プログラミングガイド (Advanced Server‐side programmingシリーズ)

Apacheモジュール プログラミングガイド (Advanced Server‐side programmingシリーズ)