この記事について
emailのMessage-IDをDBに保存する際に、どのような設計が良いのかを調べたので、それに関する考察を記録として残す。
結論
結論から言うとMessage-IDの最大長は995である。
カラムの設定はVARCHAR(995)とすればRFCに基づいたMessage-IDは問題なく格納できる。
おおまかにrailsのマイグレーションコードにおけるadd_column
は下記のようになる
add_column :table, :message_id, :string, limit: 995
以下理由
Message-IDとは
メールを一意に特定できる識別子のこと
995になる理由
メールにおける一行の最大長は998である。
Message-IDを一行の長さに押し込めようとすると
Message-IDを囲む **<** と **>及び半角スペース' '**の3文字を取り除く。
すると、 998 - 3 = 995 となる。
この3文字、<** **> ' ' がなぜ必要なのかについて解説する、
<>について
まず<>についてだが
これはRFCに規定があり、Message-IDの定義上含まれるものである。
これらで囲まれているものがMessage-IDとなるため、定義上必要となる。
メッセージ識別子(msg-id)の文法は、アングルブラケット("<" と ">")に括られた addr-spec の限定バージョンである。
半角スペースについて
半角スペースは:とメッセージボディの間に挿入できるものから来ている。
ここによれば、コロン(:)とヘッダボディの間には空白を挿入可能である。
この空白に対して畳み込みを行うことで、空白が最初にくる行が発生する。
foldingについて
foldingとは、ヘッダとボディ部分が合わせて998文字を超える時に行われる処理である。
半角スペースの直後にCRLF、改行を挿入することで、複数行を使用してヘッダ情報を記述できる。
Message-IDをメールの1行の長さ制限ギリギリまで長くしようとすると、foldingによる改行が必要になる。
995文字
メッセージボディを前述の998文字制限に対応させるためには、コロンとボディの間に空白を挿入し、そこでfoldingを行う必要がある。
よって、畳み込みを行ったボディ部分の一行にはMessage-ID以外に半角スペース
と <
>
の3文字が入る。
よって 998 - 3 = 995
となる。
このようにMessage-IDの最大長は995文字と言える。
蛇足
上記の話は受信するメールがRFCを守ってくれているという前提に立っている。
RFCを守らないメールを受信する際はその限りではない。
そして残念なことにRFCを守らないメールは存外多い
[参考]
http://stackoverflow.com/questions/30079128/maximum-internet-email-message-id-length