ActionMailer? の使い方ってどうなんでしょうね

初めに断っておきます。私は Ruby が使えません。が、動きを見て少し問題あるんじゃないのかな?って思った事を書きます。


Ruby の ActionMailer? ってのを使ってメールを送信するプログラムが身近に動いていたので実際にメールを送ってみました。
Ruby のバージョンや ActionMailer ってのにバージョンがあるのかどうか知りませんが、どのバージョンかは知りません。
そこで、驚愕の自体が!!


メールの件名に、日本語を使うと utf-8 + Q エンコードしてくれていました。これはなんか ActionMailer が勝手にやってくれるそうです。(該当箇所だけコードを見せてもらいました)
ただ、アルファベットや半角スペースや記号のみの場合はエンコードしてくれませんでした。このスペースや記号ってのが曲者で、メールのヘッダ部は、スペースや一部の記号はそのまま使うことは出来ません。

RFC 822 の 3.2. HEADER FIELD DEFINITIONS に定義されています。(改定されてたっけ?古かったらゴメンナサイ。)

field       =  field-name ":" [ field-body ] CRLF

     field-name  =  1*<any CHAR, excluding CTLs, SPACE, and ":">

     field-body  =  field-body-contents
                    [CRLF LWSP-char field-body]

     field-body-contents =
                   <the ASCII characters making up the field-body, as
                    defined in the following sections, and consisting
                    of combinations of atom, quoted-string, and
                    specials tokens, or else consisting of texts>

一部省略して

CHAR        =  <any ASCII character>                 ; (  0-177,  0.-127.)
specials    =  "(" / ")" / "<" / ">" / "@"           ; Must be in quoted-
                 /  "," / ";" / ":" / "\" / <">      ;  string, to use
                 /  "." / "[" / "]"                  ;  within a word.

atom        =  1*<any CHAR except specials, SPACE and CTLs>

一部の記号を使うには、エンコードしないとダメなんですよ。なのに ActionMailer ってのはエンコードしてくれませんでした。


これが、どういう事が起きるのかというとメールの件名に、

=?utf-8?Q?=e3=81=93=e3=82=8c=e3=81=af=e3=81=b2=e3=81=a9=e3=81=84?=

という文字列を送りたいとします。(こんな件名で送る必要があるかどうかは置いといて…)
これが、エンコードされずにそのままメールヘッダに出力されます。

Subject :=?utf-8?Q?=e3=81=93=e3=82=8c=e3=81=af=e3=81=b2=e3=81=a9=e3=81=84?=

これを、一般のメーラーで受信すると、件名は

これはひどい

となってしまいます。
「=?utf-8?Q?=e3=81=93=e3=82=8c=e3=81=af=e3=81=b2=e3=81=a9=e3=81=84?=」という件名で受信して欲しいのに、「これはひどい」という件名で受信してしまいました。
これはひどい!


2009/08/27 追記:今気付きましたが、この動きは別に悪くないですね。自前でエンコードした値を渡した際に再エンコードされるとまずいので。これはひどいとか書いてゴメンナサイ。このエントリ自体を削除しようかと思いましたが、自分への戒めのために残しておきます。よく考えてから記事書けよ!


あと、長い件名を渡した場合も RFC違反していました。RFC ではエンコードした文字列は、1行75文字迄のはずですがお構い無しでした。

RFC 2047 2. Syntax of encoded-words 一部抜粋

   An 'encoded-word' may not be more than 75 characters long, including
   'charset', 'encoding', 'encoded-text', and delimiters.  If it is
   desirable to encode more text than will fit in an 'encoded-word' of
   75 characters, multiple 'encoded-word's (separated by CRLF SPACE) may
   be used.

   While there is no limit to the length of a multiple-line header
   field, each line of a header field that contains one or more
   'encoded-word's is limited to 76 characters.

って事で ActionMailer を使う場合は、自前でエンコードして値をセットしないとダメなんじゃないのかな?(そもそも、ActionMailer の使い方が間違ってる可能性もありますが)
まあ、日本で使うには ISO-2022-JP の B エンコードが一般的みたいなので、みなさん自前でエンコードしてるんでしょうかね?


※補足:この記事は、Ruby や ActionMailer に対して悪意を持って書いているわけではありません。気分を害した方がおられたら申し訳ないです。
私が良く使う .NETでも標準のメール送信は大概酷いです。前のブログに書いた記事:System.Net.Mail.MailMessage って… | お だ のスペース