Chapter 18. ヘッダの書き換え

ヘッダ情報は FML::Header クラスのオブジェクトに収納されています。 なお FML::Header は Mail::Header を継承しているので、 Mail::Header のメソッドは何でも利用可能です。

レシピ’s

1. Subject: に [elena:00100] のようなタグをつける
2. Subject: [elena:00100] の数字部分(00100)の桁数を変える
3. Subject: のタグの数字(00100)の0パディングをなくしたい。
4. 記事のヘッダの Subject: のタグを大文字にしたい
5. 記事のヘッダの Subject: のタグを小文字にしたい
6. いつでも Reply-To: を投稿用アドレスに強制する。
7. Reply-To: を送信者に設定する。
8. Reply-To: を「送信者 + ML」に設定する。
9. MLメンバーからの投稿であれば、Reply-To: を「送信者+ML」にする。
10. To: と Cc: の中にある fml8 が管理しているMLのアドレスだけを Reply-To: に設定する。
11. 不要なヘッダフィールド X-Face: を消す
12. Sender: を X-Sender: にコピーする。
13. Received: を X-Received: へ移動させる。
14. 元のメールに Reply-To: がなければ、そのままにしたい。
15. To: Cc: Reply-To: を全部そのまま素通しにする。
16. 記事の Message-ID: は元の値のまま通したい。
17. 記事に ML 独自の Message-ID: をつけたい
18. X-ML-Info: の内容を指定する。
19. レポートメールの Reply-To: を指定する。
20. 特定のヘッダだけを通したい
21. In-Reply-To: か References: を強制したい。
22. そもそも、あらゆるヘッダ書き換え処理を止めたい

1. Subject: に [elena:00100] のようなタグをつける

デフォルトではタグはつきません。 fml8 ではタグを sprintf 形式で指定することになっています。

[/var/spool/ml/elena/config.cf]

article_subject_tag = [$ml_name:%05d]

2. Subject: [elena:00100] の数字部分(00100)の桁数を変える

fml8 ではタグを sprintf 形式で指定することになっています。 たとえば7桁なら %07 などとすればよいだけです。

[/var/spool/ml/elena/config.cf]

article_subject_tag = [$ml_name:%07d]

3. Subject: のタグの数字(00100)の0パディングをなくしたい。

[/var/spool/ml/elena/config.cf]

article_subject_tag = [$ml_name:%d]

4. 記事のヘッダの Subject: のタグを大文字にしたい

article_subject_tag = [\U$ml_name\E:%05d]
(注意: この機能を使う場合には 2002/10/29 以降の snapshot を使ってください)。

5. 記事のヘッダの Subject: のタグを小文字にしたい

Unix 上では、たいてい小文字を使うので、ML名前も小文字でしょう。 だから、普通は何もしなくても小文字のはずですが、 念のため、小文字を強制したいなら、つぎのようにしてください。

article_subject_tag = [\L$ml_name\E:%05d]
(注意: この機能を使う場合には 2002/10/29 以降の snapshot を使ってください)。

6. いつでも Reply-To: を投稿用アドレスに強制する。

次の HOOK を config.cf の最後(=cutより後)に書いて下さい。

$article_header_rewrite_end_hook = q{
    my $ml = $config->{ article_post_address };
    $header->replace('Reply-To', $ml);
};
なおヘッダ書き換えルールに以下の命令を追加しても同じことが出来ます。
article_header_rewrite_rules += rewrite_reply_to_enforce_article_post_address

7. Reply-To: を送信者に設定する。

次の HOOK を config.cf の最後(=cutより後)に書いて下さい。

$article_header_rewrite_end_hook = q{
    my $cred   = $curproc->credential();
    my $sender = $cred->sender();

    $header->replace('Reply-To', $sender);
};

8. Reply-To: を「送信者 + ML」に設定する。

次の HOOK を config.cf の最後(=cutより後)に書いて下さい。

$article_header_rewrite_end_hook = q{
    my $ml     = $config->{ article_post_address };
    my $cred   = $curproc->credential();
    my $sender = $cred->sender();

    $header->replace('Reply-To', "$ml, $sender");
};

9. MLメンバーからの投稿であれば、Reply-To: を「送信者+ML」にする。

次の HOOK を config.cf の最後(=cutより後)に書いて下さい。

$article_header_rewrite_end_hook = q{
    my $ml     = $config->{ article_post_address };
    my $cred   = $curproc->credential();
    my $sender = $cred->sender();

    if ($cred->is_member($sender)) {
	$curproc->log("member");
	$header->replace('Reply-To', "$ml, $sender");
    }
};

10. To: と Cc: の中にある fml8 が管理しているMLのアドレスだけを Reply-To: に設定する。

だいぶ複雑ですが HOOK で実現できます。 次の HOOK を config.cf の最後(=cutより後)に書いて下さい。

$article_header_rewrite_end_hook = q{
    my $to   = $header->get('to');
    my $cc   = $header->get('cc');
    my $addr = "$to, $cc";

    use Mail::Address;
    my (@addrlist) = Mail::Address->parse($addr);

    my $reply_to = '';
    for my $a (@addrlist) {
        my $_addr = $a->address;
        if ($curproc->is_fml8_managed_address($_addr)) {
            $reply_to .= $reply_to ? ", $_addr" : $_addr;
        }
    }

    $header->replace('Reply-To', $reply_to) if $reply_to;
};

11. 不要なヘッダフィールド X-Face: を消す

unsafe_header_fields  += x-face

12. Sender: を X-Sender: にコピーする。

$article_header_rewrite_end_hook = q{
   my $header   = $curproc->article_message_header();
   $header->add('X-Sender', $header->get('Sender'));
};

13. Received: を X-Received: へ移動させる。

X-Received: へコピーした後で Received: を消します。

$article_header_rewrite_end_hook = q{
   my $header   = $curproc->article_message_header();
   $header->add('X-Received', $header->get('Received'));
   $header->delete('Received');
};

14. 元のメールに Reply-To: がなければ、そのままにしたい。

config.cf で

article_header_rewrite_rules    -=      rewrite_reply_to
としてください。

デフォルトでは Reply-To: のないメールのヘッダに対し「Reply-To: 投稿用 アドレス」が追加されます。これは article_header_rewrite_rules にある rewrite_reply_to 命令によります。よって、これをルールから削除してしま えば Reply-To: に対する書き換えルールが無効となるというわけです。

15. To: Cc: Reply-To: を全部そのまま素通しにする。

前レシピと同じです。

To: と Cc: は元々素通しです。そのため config.cf で

article_header_rewrite_rules    -=      rewrite_reply_to
とするだけで十分です。

16. 記事の Message-ID: は元の値のまま通したい。

素通しがデフォルトの挙動ですので、なにもする必要はありません。

17. 記事に ML 独自の Message-ID: をつけたい

[/var/spool/ml/elena/config.cf]

$article_header_rewrite_end_hook = q{
	my $header = $curproc->article_message_header();

	# Message-Id を生成 (この例は適当です)
	my $ml_name   = $config->{ ml_name };
	my $ml_domain = $config->{ ml_domain };
	my $new_id    = sprintf("%s-%d\@%s", $ml_name, $$, $ml_domain);

	# X-Message-Id にオリジナルの Message-Id をバックアップしておく
	$header->add('X-Message-Id', $header->get('Message-Id'));

	# Message-Id を入れ換える
	$header->replace('Message-Id', $new_id);
};

18. X-ML-Info: の内容を指定する。

ようするにメールヘッダの値を強制指定します。

$article_header_rewrite_end_hook = q{
        my $header = $curproc->article_message_header();
        $header->replace('X-ML-Info', "oresama id");
};

19. レポートメールの Reply-To: を指定する。

未実装です。 現在の fml8 でも、実際には

outgoing_mail_header_reply_to = アドレス
でレポートメールの Reply-To: を指定できるのですが、 これは今の実装が間違っていますね _o_

20. 特定のヘッダだけを通したい

現状の fml8 では、次のような HOOK で実現するしかありません。


    $article_header_rewrite_end_hook = q{
	my $header       = $curproc->article_message_header();
	my (@tags)       = $header->tags();

	# 通したいヘッダフィールドを定義する 	
	my (@valid_tags) = qw(to from reply-to subject date message-id);

        for my $tag (@tags) {
            my $valid = 0;
          SCAN:
            for my $v (@valid_tags) {
                if ($tag =~ /^$v$/i) {
                    $valid = 1;
                    last SCAN;
                }
            }
            unless ($valid) {
                $header->delete($tag);
            }
        }
    };

21. In-Reply-To: か References: を強制したい。

記事への返事にも関わらず In-Reply-To: も References: もないメールがあります。 一つには、スレッド関係が分からないので見づらいという問題があります。 二つには、通常そういったメールはないので普通のメールではなく SPAM などの 類ではないかという可能性です。

Subject に返事の印( Re: など)がなく、In-Reply-To: または References: ヘッダがないなら拒否する HOOK です。

    $article_post_verify_request_end_hook = q{
	my $header      = $curproc->incoming_message_header();
	my $subject     = $header->get('subject')     || '';
	my $in_reply_to = $header->get("In-Reply-To") || '';
	my $references  = $header->get("References")  || '';

	my $_subject = new Mail::Message::Subject $subject;
	if ($_subject->has_reply_tag()) {
	    unless ($in_reply_to || $references) {
		$curproc->log("reject invalid reply message");
		$curproc->stop_this_process();
		$curproc->policy_reject_this_message();
	    }
	}
    };
拒否した旨のメールを送信者へ送っています。 もしエラーメッセージを送信者に返さず単に無視するだけでいいなら policy_reject_this_message を policy_ignore_this_message にしてください。

22. そもそも、あらゆるヘッダ書き換え処理を止めたい

use_article_header_rewrite を no にして書き換え機能全体を止めて下さい。

[/var/spool/ml/elena/config.cf]

use_article_header_rewrite = no

fml 8.0 (fml-devel) project homepage is www.fml.org/software/fml8/.
fml 4.0 project homepage is www.fml.org/fml/menu.ja.html.
about one floppy bsd routers, see www.bsdrouter.org/.
other free softwares are found at www.fml.org/software/.

author's homepage is www.fml.org/home/fukachan/.
Also, visit nuinui's world :) at www.nuinui.net.

For questions about FML, e-mail <fml-bugs@fml.org>.