今日会社でCC/BCCでメールを送るプログラムを作った際に、上司に「CC/BCCに入れる複数メアドの区切り文字はカンマだよ」という指摘を受けました。 確かにOutlook Expressから複数メアドを貼り付けるとセミコロンだったのですぐさま修正したのですが、興味が湧いたので調べてみました。

RFCを見る

上司に、「セミコロンでも送信できましたよ」と言った際にRFCで仕様の誤りを説明頂きました。 今回調べたRFCはRFC822(現在はobsoleteな仕様のようです)とRFC2822(同ページに最新仕様のRFC5322へのリンクもあります)です。

まずRFCをさらっと読むと、確かにTO/CC/BCCなどのメールヘッダ値にはアドレスのリストが設定する事になっており、そのリストの区切り文字はセミコロンであると記述されていました。 (「2.7. #規則: リスト」「D. 構文規則のアルファベット順一覧」を参照)

MTAが変換している?

次にセミコロンでも送信できる事を確認するため、手元から送信可能なMTAにtelnetコマンドで直接送信してみました。

D:\>telnet sendmail.example.com 25
Trying 192.0.2.1...
Connected to sendmail.example.com.
Escape character is '^]'.
220 sendmail.example.com ESMTP Sendmail 8.12.11/8.12.11; Sat, 31 Jul 2010 00:46:53 +0900
EHLO sender@example.com
250-sendmail.example.com Hello localhost [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-DELIVERBY
250 HELP
MAIL FROM: sender@example.com
250 2.1.0 sender@example.com... Sender ok
RCPT TO: receipt@example.com
250 2.1.5 receipt@example.com... Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
CC: foo@example.net; bar@example.org
From: sender@example.com
Subject: mailaddr separated by semicolons

mailaddr separated by semicolons
.
250 2.0.0 12345678901234 Message accepted for delivery
QUIT
221 2.0.0 sendmail.example.com closing connection
Connection closed by foreign host.

するとメールはTO/CCとも通常通り送信されました。となるとMTA側で変換している可能性が濃厚です。 とりあえずPostfixの最新ソースをダウンロードしてさらっと見てみたのですが、こちらはC言語のためセミコロンの処理をしているのか正直分かりませんでした…。

やっぱりMSが悪い?

上司はこの動作を「過去にMS製品がRFC非準拠のセミコロンで送信するから、それを吸収するために各MTAが対応した」旨をおっしゃってました。:-) でも、こんな例があるのを思い出し、昔VBでお世話になったMSを擁護?(笑)するため、Outlook ExpressからMTAに渡しているデータを覗いて見ることにしました。 方法はCygwin版netcat(nc)コマンドを25番ポートでlistenさせ、SMTP通信を手動でやりとりします。 (レスポンスコードはtelnetでのやり取りを参考にコードのみコピペ)

D:\>nc -l -p 25 ※Windowsファイアウォールの確認メッセージが表示されます
220
HELO localhost
250
MAIL FROM: <sender@example.com>
250
RCPT TO: <receipt@example.com>
250
RCPT TO: <foo@example.net>
250
RCPT TO: <bar@example.org>
250
DATA
354
Message-ID: <0123456789ABCDEF0123456789ABCDEF@localhost>
From: "Sender" <sender@example.com>
To: <receipt@example.com>
Cc: <foo@example.net>,
        <bar@example.org>
Subject: mailaddr separated by semicolons
Date: Sat, 31 Jul 2010 00:57:29 +0900
MIME-Version: 1.0
Content-Type: text/plain;
        format=flowed;
        charset="UTF-8";
        reply-type=original
Content-Transfer-Encoding: 7bit
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 6.00.2900.5931
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5931

mailaddr separated by semicolons

.
250
QUIT
221

なんとOutlook ExpressからMTAに渡す際にセミコロンをカンマに変換しているではないですか!さすがMS(笑)。 CCに設定したメールアドレスはMTA側じゃなくてメーラ側(MUA)で展開されていることも分かります。

おわりに

以上の結果から、RFC準拠的にもプログラム中で複数のメールアドレスを記述する時にはカンマ区切りの方が無難のようです。ただ、最近のMTAやメーラーであればセミコロンでもうまく処理してくれるようです。 なぜカンマのみだった区切り文字がセミコロンも許容されるようになったかは未だ謎ですが、普段使っているメールの裏側を垣間見る事ができました。