メールを書くときに使う文法はRFC 5322です。

勉強のきっかけになった問題

インターネット標準 RFC 5322(旧 RFC 822)に準拠した電子メールにおいて,ヘッダと本体を区別する方法はどれか。

ア. <header>と </header>で囲まれた部分をヘッダ,とで囲まれた部分を本体とする。
イ. 1個のピリオドだけから成る行の前後でヘッダと本体を分ける。
ウ. Subjectフィールドがヘッダの最後であり,それ以降を本体とする。
エ. 最初に現れる空行の前後でヘッダと本体を分ける。>>>正解
平成26年秋期問20 メールヘッダと本体を区別する方法|情報処理安全確保支援士.com

メールのざっくりした流れ図

f:id:ponsuke_tarou:20180224131345j:plain

メールを書くときにRFC 5322を使います。

RFC 5322とは、メールのフレームワークにおいてコンピュータ利用者間で送信されるテキストメッセージの文法です。

RFC 5322とは、IETF(インターネット技術の標準を定める団体)が発行するRFCという文書の一つで、電子メールのフレームワークにおいてコンピュータ利用者間で送信されるテキストメッセージの文法、インターネットメッセージフォーマット(IMF)を規定しています。
いつもメーラーによろしくやってもらっているけどちゃんと決まりがあるんです!

IETFとは、インターネット技術の標準を定める団体です。

IETFは、インターネット技術の標準化を推進する任意団体です。 コンピュータシステムを相互接続するため、 共通の技術仕様策定を議論するグループから発展したものです。
インターネット用語1分解説~IETFとは~ - JPNIC

RFCとは、インターネットの標準を定めた文書です。

e-words.jp

(旧 RFC 822)って書いてあるのは、いろいろ改訂してきたからなんです。

f:id:ponsuke_tarou:20180224162332j:plain

ヘッダ情報は、「フィールド名:フィールド本文CRLF」で構成されます。

メールの情報は、フィールドを定義して書かれています。

ヘッダフィールドは、フィールド名の次にコロン(":")、次にフィールドの本文、最後に CRLF で終了する行である。フィールド名は(コロンを除く)印刷可能な US-ASCII 文字で構成されなければならない。フィールド本文は CR と LF とを除く任意の US-ASCII 文字のほかに、空白・水平タブの各文字で構成されてよい。<省略>
必須のヘッダフィールドは発信日付フィールドと発信元アドレスフィールドだけである。それ以外のすべてのヘッダフィールドは文法的にはオプションである。
RFC5322(Internet Message Format)

発信日付フィールドには、メール配送システムへの投入準備ができたことをメッセージ作成者が示した日付と時刻を書きます。

Date: Sat, 24 Feb 2018 12:59:20 +0900

発信元フィールドには、メッセージの送信元のメールボックスを書きます。

fromとsenderとオプションのreply-toがあります。

From: "はてなブログ " < noreply+blog-anniversary_mail@hatena.ne.jp>
宛先アドレスフィールドには、メッセージの受信者を書きます。
  • 「To:」フィールド : メッセージの主要な受信者
  • 「Cc:」フィールド : メッセージの内容はその人たちに向けられたものではないかもしれないが、それを受け取るべき人のアドレス
  • Bcc:」フィールド : メッセージの受信者を表すが、他の受信者に公開されないアドレス
To: hoge@hoge.com

識別フィールドは、必須じゃないんだけど「書くべき」とされています。

「Message-ID:」フィールドには、ユニークなメッセージ識別子を書きます。

これを書くことで、特定のメッセージの特定のバージョンを表しユニーク性はそれを生成したホストによって保証されます。
メッセージ識別子は機械的に読み取られることを目的としており、その後に修正されたメッセージはそれぞれ新しいメッセージ識別子を持つことになります。

Message-Id: <20180224035920.A26A21B80B9@smtp01.hatena.ne.jp>
「In-Reply-To:」フィールドには、返信元メッセージの「Message-ID:」フィールドの内容を書きます。
「References:」フィールドには、の内容は、返信元メッセージの識別フィールドを書きます。

情報フィールドには、メッセージに関して人が読むことのできる情報を書くけど必須ではありません。

「Subject:」には、メッセージの見出しを表す短い文字列、件名を書きます。
  • 返信では、「Re:」の後に元のメッセージの "Subject:" フィールドの内容を続けてもいいです。必須ではありません。
  • 他の文字列や二つ以上の "Re: " が使用されるのは望ましくないため、文字列 "Re: " をひとつだけ使うのが好ましいそうです。

そういえば、社会人なり立ての十数年前にメーラの件名では見切れるぐらい「Re:」が連続しているメールをちょいちょい見かけて「わかりずらいよ」と思ったことがありました。

Subject: はてなブログ/ponsuke_tarou(id: ponsuke_tarou)
  さま、ponsuke_tarou’s blogを開設して1年が経ちました
「Comments:」フィールドには、メッセージボディに関する任意の追加コメントを書きます。
「Keywords:」フィールドには、受信者にとって役に立つかもしれない重要な単語や語句のカンマ区切りリストを書きます。

再送フィールドには、メッセージの特定の再送に関連する情報を書きます。

再投入のたびに個別の再送フィールドの集合が追加されるべきである(SHOULD)。メッセージの特定の再送に関連するすべての再送フィールドはひとまとめにして置かれるべきである(SHOULD)。再送フィールドの新しい集合はメッセージの先頭に追加される。したがって、もっとも新しい再送フィールドがメッセージの前方に現れる。再送フィールドが追加されるとき、そのメッセージの他のフィールドは変更されない。<省略>
再送フィールドは、そのメッセージがユーザーによって配送システムに再投入されたことを識別するために使用される。再送フィールドを使用する目的は、最終受信者に対してそのメッセージが元の送信者から(元のフィールドはすべて同じままで)直接送られたかのように見せることである。
RFC5322(Internet Message Format)

返信の時に欲しいフィールド 対応する再送フィールド 内容
MUST Resent-Date: メッセージの再送信者がその再送メッセージを発信した日付と時刻
MUST Resent-From: メッセージを再送した人またはシステムのメールボックス
「Resent-From:」と同じ場合、使用されないべき(SHOULD NOT)。 Resent-Sender: 一人または複数の人に代わってメッセージを再送した個人
SHOULD Resent-Message-ID: 再送メッセージのためのユニークな識別子

※. 他にもフィールドはあります。

トレースフィールドは、情報提供用です。

Received: by 10.100.164.108 with SMTP id h99csp1614716pje;
        Fri, 23 Feb 2018 19:59:21 -0800 (PST)
Return-Path: <noreply+blog-anniversary_mail@hatena.ne.jp>
Received: from smtp01.hatena.ne.jp (gw.hatena.ne.jp. [59.106.108.66])
        by mx.google.com with ESMTP id a21sixxxxxxxpgw.xxx2018.02.23.19.59.20
        for <hoge@hoge.com>;
        Fri, 23 Feb 2018 19:59:21 -0800 (PST)

f:id:ponsuke_tarou:20180224162501j:plain

はてなブログからもらったメールを土台に見てみます。

Delivered-To: hoge@hoge.com
Received: 一番上の Received が受信側メールサーバ
X-Google-Smtp-Source: 「X-」始まりで、Gmailがつけている
X-Received: by 「X-」で始まる項目は、メール送信者やサーバ側で任意に設定できる
ARC-Seal: i=1; a=rsa-sha256; t=..................................
ARC-Message-Signature: i=1; a=rsa............................
ARC-Authentication-Results:..........................................
Return-Path: <noreply+blog-anniversary_mail@hatena.ne.jp>送信先のメールアドレスに届けられない場合、サーバが自動的に送信者へ通知するための宛先
Received: 経由したサーバのIPアドレスやドメイン名、送信元のIPアドレスやドメイン名などで、経由したサーバの数だけ Received が記録される
Received-SPF: SPF認証情報とドメイン送信元サーバーを照合した結果
Authentication-Results: 送信ドメイン認証の結果。RFC 5451にて標準化
Received: from ヘッダ一番下の Received が送信元
From: "はてなブログ " < noreply+blog-anniversary_mail@hatena.ne.jp>
To: mana.ukigaya.opentone@gmail.com
Subject: はてなブログ/ponsuke_tarou(id: ponsuke_tarou)
  さま、ponsuke_tarou’s blogを開設して1年が経ちました
Date: Sat, 24 Feb 2018 12:59:20 +0900
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="メールを情報を区切る文字"
Message-Id: <20180224035920.A26A21B80B9@smtp01.hatena.ne.jp>

--メールを情報を区切る文字
Date: Sat, 24 Feb 2018 12:59:20 +0900
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: base64

メッセージ本文の部分
メッセージのボディは単純な US-ASCII 文字からなる行である。ボディに課される制限は以下の二つだけである:
CR と LF とは CRLF としてのみ現れなければならず(MUST)、ボディ内にそれらが独立して現れてはならない(MUST NOT)。
ボディ内の各行は CRLF を除いて 998 文字までに制限されなければならならず(MUST)、78 文字までに制限されるべきである(SHOULD)。
[http://srgia.com/docs/rfc5322j.html#p2.3:title]

--メールを情報を区切る文字
Content-Type: MIME-Type; name="添付ファイルの名前"
Content-Disposition: attachment; filename="添付ファイルの名前"
Content-Transfer-Encoding: base64

添付ファイルを文字にしたもの

--メールを情報を区切る文字--