LoginSignup
3
0

More than 5 years have passed since last update.

Message-IDをDBに保存する際の考察

Posted at

この記事について

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となるため、定義上必要となる。

RFC5322

メッセージ識別子(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を守らないメールは存外多い :innocent:

[参考]
http://stackoverflow.com/questions/30079128/maximum-internet-email-message-id-length

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0