MIMEについて学んだことのアウトプット

はじめに

最近SMTPプロトコルとMIMEについて勉強したので、理解の整理を兼ねてアウトプットします。「メールって普通に日本語も画像も送れるけど、裏側では何が起きているんだろう?」という疑問からスタートしました。

SMTPはASCII文字しか扱えない

SMTP(Simple Mail Transfer Protocol)はメールを送信するためのプロトコルですが、もともとはASCII文字(7bit)しか安全に運べないという制約を持っていました。

つまり素のSMTPでは、

  • 日本語などの非ASCII文字
  • 画像やPDFなどのバイナリデータ

をそのまま送ることができません。これではメールとして不便すぎるので、この制約を解消するために生まれたのがMIMEです。

MIMEはメールのフォーマットを拡張する仕組み

MIME(Multipurpose Internet Mail Extensions)は、SMTPそのものを拡張するプロトコルというよりは、メールメッセージのフォーマットを拡張する規格です。SMTPは「メールを転送する仕組み」、メール本文の書式は別の規格(RFC 5322)で定義されており、MIMEはこの書式を拡張して、テキスト以外のデータ種別やエンコーディング方式を表現できるようにしています。

MIMEは主に次のようなヘッダーで構成されます。

  • Content-Type:データの種類を示す(text/plainimage/pngapplication/pdf、複数の要素を含む場合はmultipart/mixedなど)
  • Content-Transfer-Encoding:データをASCII文字だけの形にどう変換したかを示す(Base64Quoted-Printable7bitなど)
  • charset:文字コードの指定(UTF-8ISO-2022-JPなど)

変換の流れ:文字コード変換 → 転送用エンコード

日本語のテキストを送る場合、実は2段階の変換が行われています。

  1. 文字コード変換(charset):日本語の文字を、指定した文字コードのバイト列に変換する
  2. 転送用エンコード(Content-Transfer-Encoding):そのバイト列を、SMTPで安全に運べるASCII文字列の形に変換する

例えばcharset=UTF-8と指定した場合は「日本語→UTF-8のバイト列」に変換され、そのバイト列はASCIIの範囲を超える(8bit全部を使う)ため、さらにBase64Quoted-Printableで包む必要があります。

一方、charset=ISO-2022-JPの場合は少し特殊です。ISO-2022-JPは、エスケープシーケンスという特殊な合図の文字列を使うことで、日本語も含めてすべて7bit(ASCIIの範囲)のバイト列だけで表現できるように設計された文字コードです。つまりISO-2022-JPに変換した時点で、すでにSMTPの制約をクリアしています。そのため、Content-Transfer-Encodingとして追加のエンコードをせず7bit(そのまま送れる、という意味の指定)が使われることが伝統的に多いです。

まとめると:

charset文字→バイト列の変換追加の転送用エンコードは必要?
UTF-8日本語→UTF-8バイト列必要(Base64やQuoted-Printableが多い)
ISO-2022-JP日本語→ISO-2022-JPバイト列(エスケープシーケンス使用)基本不要(7bit指定で足りる)

画像やPDFの場合

画像やPDFなどのバイナリデータは、そのままだとASCII文字ではないので、Base64エンコードによってASCII文字列に変換してから本文に埋め込みます。添付ファイルが複数ある場合は、multipart/mixedという指定で「本文」と「添付」を区切り(boundaryという文字列で境界を示す)、一通のメールにまとめます。

全体の流れ

送信側:

  1. メールに日本語・画像・PDFなどが含まれる
  2. MIMEでそれぞれのデータ種別(Content-Type)を記述
  3. charsetで文字コードを指定し、必要なら転送用エンコード(Base64など)を適用
  4. SMTPで運べる形(ASCII文字列)になったメールを送信

受信側:

  1. SMTPでメールを受信
  2. MIMEヘッダー(Content-Type、Content-Transfer-Encoding、charsetなど)を確認
  3. その情報をもとに、エンコードされたデータを元の日本語・画像・PDFなどに復元
  4. 正しいデータとして閲覧できる

おまけ:MIMEはメール以外にも影響を与えている

Content-Typeヘッダーはメールだけでなく、HTTP通信でも使われています。Webサーバーがブラウザに「これはHTMLです」「これは画像です」と伝えるあの仕組みも、もとをたどればMIMEで定義された考え方です。メールのために生まれた規格が、Webの基盤の一部にもなっているというのは面白いポイントだと思いました。

まとめ

  • SMTPはASCII文字しか運べないプロトコル
  • MIMEはメールのフォーマットを拡張し、非ASCIIデータをASCIIの形に変換して運べるようにする規格
  • 変換は「文字コード変換」と「転送用エンコード」の2段階(文字コードによっては後者が省略されることもある)
  • MIMEの考え方はHTTPのContent-Typeなど、Web全体にも影響を与えている