まずメールそれ自体です。
メールは基本的にはテキストファイルであり、ヘッダ (header)
と
ボディに分かれています。ヘッダの書式は規格がありかなり厳密に
決められていますが、ボディにはありません。たとえば以下が生の
メールの例です。
Return-Path: <ruby-list-admin@ruby-lang.org> Received: from helium.ruby-lang.org (localhost [127.0.0.1]) by helium.ruby-lang.org (Postfix) with ESMTP id 4EEF9165; Wed, 12 Dec 2001 07:05:58 +0900 (JST) Received: from doraemon.edit.ne.jp (doraemon.edit.ne.jp [210.141.234.1]) by helium.ruby-lang.org (Postfix) with ESMTP id 7AFAB126 for <ruby-list@ruby-lang.org>; Wed, 12 Dec 2001 07:05:57 +0900 (JST) Date: Wed, 12 Dec 2001 07:05:58 +0900 Posted: Wed, 12 Dec 2001 07:14:16 +0900 From: Minero Aoki <aamine@mx.edit.ne.jp> Reply-To: ruby-list@ruby-lang.org Subject: [ruby-list:32880] Re: RAA update To: ruby-list@ruby-lang.org (ruby mailing list) Message-Id: <20011212071416N.aamine@mx.edit.ne.jp> In-Reply-To: <20011210141226.DTUM11600.femail11.im.home.ne.jp@witch> References: <20011210141226.DTUM11600.femail11.im.home.ne.jp@witch> Mime-Version: 1.0 Content-Type: Text/Plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit Precedence: bulk Lines: 79 X-UIDL: b8b1b7f1d28ee02af1df6f8612b5b8c4 あおきです。ここからボディです。 : (以下略)
ヘッダとボディは空行で区切られます。ヘッダではだいたい一行が
ひとつのヘッダに相当しますが、空白で始まる行は上の行の続きです。
たとえばこのメールの Received:
は二つとも 3 行でひとつのヘッダ行を
構成しています。各ヘッダには最初にヘッダ名があり、コロン(:)を
置いてそのあとが「ヘッダフィールド」(ヘッダの内容)です。
ヘッダにはそれぞれ役割があります。たとえば To:
ヘッダには
メールの宛先を書きます。From:
にはメールの送り元を書きます。
Subject:
はいわゆる題名です。Date:
はメールを送信した日時、
Received:
が配送記録などなど。詳しくはあとで説明します。
細かく追求すれば送信にもいろいろな方法があるのですが、普通に
生きていく限り関係しなくてはいけないのは SMTP (Simple Mail Transfer Protocol)
だけです。これは、とあるホストから別のホストにメールを転送する
ためのプロトコル (約束事の集合) です。とにかくこれを使えば
メールを転送できます。SMTP
ではメールの中身には基本的に関与
しません。少なくとも、メールの中身を変えてしまうような働き
かけは行いません。
またメールには本来「受信」というものはありませんでした。
基本的にメールシステムは常時接続が基本で、メールを送ったら
即座に送り先まで (SMTP
で) 配送されることになっていたからです。
いまで言えば携帯メールみたいなものです。
ところがそのうち常時接続でないところが出てきて、解決方法を
考えはじめました。そこで出てきた解決法のひとつが最近使ってる
「受信」なわけです。これには普通は POP3 (Post Office Protocol version 3)
というプロトコルを使います。
POP3
では、配送されたメールを POP
サーバに保存しておき、それを
(PPP
でつないだパソコンとかから) リクエストされたら渡し、その
あと消します。つまり本当は「送信待機」とでも言うほうがより正確
でしょう。
他の解決法としては IMAP (Internet Messsage Access Protocol) と
いうプロトコルが代表格です。POP
はメールの送信を介助するだけですが、
IMAP では普通のメールクライアントの機能の一部までがサーバに取り
こまれたような感じになります。たとえば IMAP サーバ上でメールの
検索をしたり、メールボックスの分類ができたりします。携帯メール
なんかは実は IMAP に類似の構造です。携帯は CPU パワーがないので、
サーバ上でメールを加工して携帯に渡しているのです。
届いたメールを最終的に保存しておくところがメールボックスです。
きっとどこかで聞いたことがあるであろう INBOX
とか「受信箱」とか
「郵便受け」がそれです。
メールボックスは、メーラ次第でいくらでも変えることができてしまう
ので相当にたくさん種類があります。超有名なのだけでも UNIX mbox
(さらにマイナーバージョンがいくつかある)、MH、Maildir
なんてのが
あります。
なんにしてもメールボックスはメールをとっておければいいのです。 形式については深く追求しないことにしましょう。
メールは現在あるなかではほとんど最古参の古いシステムですから、 特有の問題が死ぬほどあります。以下いくつか挙げましょう。まず 送受信から。
To:
と SMTP
の To (RCPT TO) は無関係From:
と SMTP
の From (MAIL FROM)
も無関係メール自体について。
メールボックスについて。
そんなわけで、TMail
が数千行あるのにはそれなりの理由が
あるのです。多少ロードが遅くても目をつぶってください。
メールヘッダに格納されている情報について少し詳しく解説します。 もっと詳しく内容や書式について知りたい人は RFC2822 などを見るとよいでしょう。
To:
宛先。複数アドレスを格納。
From:
送り主。複数アドレスを格納。
(ただし通常ひとつで複数のときは Sender:
をつけなければいけない)
Subject:
主題。メールに書いた内容を一言で凝縮したもの。 「題名」とはちょっと違う。
Date:
メールを送った日時。受け取った時間でも書いた時間でもない。
Message-Id:
全世界においてメールと一対一に対応する (させなければならない)
文字列。メールを作成したホストの FQDN (
正式ホスト名) と時刻、
プロセス/スレッド ID
、ランダム文字列などを使って作るのだが、
PPP
接続なパソコンだったりすると FQDN
がないので困る。そういう
ときは、危険なのを承知でプロバイダのメールサーバの FQDN
に適当な
文字列をくっつけて使うしかないと思う。
ちなみに sendmail (
一番有名な SMTP
サーバ) は勝手にメッセージ ID
をつけてくれるので、それを期待するのもよいかもしれない。が、
qmail
なんかはつけてくれないし、規格に正確に従うならばメーラが
付けるのが正しい。
In-Reply-To:
このメール、が返信した対象のメール、のメッセージ ID
。
この情報を使って返信関係をツリーにするとよく見る
「スレッド表示」になる。
References:
このメールが返信したメール、が返信したメール、が返信したメール……
と再帰的にたどって集めたメールのメッセージ ID
の集合。
In-Reply-To
と同じように、メールスレッドを作るのに使える。
基本的には関係あるメールの ID
は全部入れるが、さすがに
多すぎるときは古いものから省略してよい。たとえば 12 個とか。
Reply-To:
メールに返信するときに使うアドレス。このヘッダがある場合は
絶対に From:
にメールを返してはいけない。
Received:
配送経路情報。メールシステムのデバッグや SPAM
の発送元の
特定とかに使える。こともある。簡単に偽造できるから信用
しすぎてはならない。
X-*:
X-
が頭についているヘッダは規格で決められたのではない。
つまり解釈は自由。有名なとこでは X-Mailer (
メーラ名)とか。
Mime-Version:
Content-* ヘッダをつけるなら必ずつけなければいけない。
いまのところ常に "1.0"
。
MIME とは Multipurpose Internet Mail Extentions
の略だが
いまは同じ技術がメールに関係なくいろんなところに使われている。
メールの中身がなんであるか示す。なんであるか、とは、
たとえば「プレーンテキストである」とか「JPEG
である」とか。
俗に言うところの「MIME タイプ」。Content Type の種類に関しては
次のセクションで詳述。
メールの位置付け。というとわけわかんない。ありていに 言うと、マルチパートメールのときにパートが他のパートと どういう関係にあるかを示すもの。たとえば HTML とそこに 入ってる絵とか、そういうこと。やりかたは……やってほしく ないから、言わない。どうしてもやりたければ自分で調べて。
前述したように SMTP
は 8 ビット透過でないので、8 ビットめが
立ってるときはなにかエンコードして送る。そういうときに
このヘッダに Base64
とか書いたりする。
有名な Content Type には以下のようなものがある。
text/plain
text/html
image/gif
image/png
image/jpeg
application/octet-stream
multipart/mixed
(次のセクションを参照)
ま、だいたいわかるでしょ。また text
には charset
という
パラメータがつきもので、文字コードのエンコーディングを
指示する。もちろん charset
とエンコーディングは別物であるのだが
いったん規格で決まってしまった以上はそう簡単に変えられないのだ。
我々に関係ある charset
値は次のもんくらい。
us-ascii
iso-2022-jp
iso-2022-jp-2
(iso-2022-jp
を韓国語とかにも対応させて拡張したもの)euc-jp
shift_jis
utf-8
普通の日本語使いならば iso-2022-jp (JIS)
を使っておけばよい。というか
そうすべき。(もちろんちゃんと NKF.nkf('-j',str)
でボディを変換すること)
Content-Type: multipart/* のとき、メールはマルチパートメール というのになっている。一言で言うと、メールボディの中にまたメールが 入っているのである。俗に言う「添付ファイル」はこれを使って テキストのメールと画像のメールをひとつのメールに含めているわけだ。 つまり添付とは言っても形式上ではテキストと画像は並列に並んでいる。
ひとつのメールを複数のメールに分割して送ることができる。 このとき Content-Type: message/partial。作りかたは RFC2046 を参照。
メールがでかくなりすぎると途中のファイアウォールとかが 勝手にこれを使ってぶったぎることがあるのでときたま見かける。 しかし相手が分割メールを再生できることが保証されるならばいいが、 そうでないならそういう勝手なことをしてはいけない。送り元に エラーを返すべきである。
メールの本体は別のところに置いてあるもの。たとえば URL を 示したりする。Content-Type: message/external-body。作りかたは RFC2046 を参照。
どこで使ってんだろうと思っていたが、IETF
のアナウンス ML で
使っていた。インターネットドラフトとかが出ると、ヘッダだけが
メールに書いてあって external-body
で本体を指し示している。
なかなか賢い。ていうか IETF
が使わなかったら詐欺か。
(IETF
はインターネットで使う規格をまとめてる団体です)