前回は、Cyrus IMAPを使った実際のIMAPサーバの構築について解説しました。今回は、再びクライアント側の話に戻り、実際のプロトコルのやり取りについて解説していきます。
IMAP4では、受信したメッセージはIMAP4サーバに保存されます。メーラは接続時にIMAP4サーバから各種情報(フォルダ一覧、メッセージのヘッダ情報、メッセージのボディなど)を取得しますが、毎回これらの情報すべてを取得していては、通信時間=待ち時間が長くなり、使い勝手が悪くなってしまいます。そこで、メーラはローカルのハードディスクに前回の情報をキャッシュしておき、前回の通信から変更のあった部分=差分だけを取得することで通信量を削減します。また、オフライン時に行った削除/移動/コピーなどの処理をサーバ側に反映させる処理も行います。この差分情報の取得とオフライン処理の反映をまとめて同期処理と呼びます。IMAP4プロトコルは多様なコマンド/オプションを持っているので、同期処理の実装はメーラによってさまざまな実現方法が試されています。同期処理をいかにうまく行うかが、プログラマーの腕の見せどころになるわけです。
それでは、実際に、メーラではどのようにIMAPサーバと通信しているのかをのぞいてみましょう。IMAP4をサポートしたメーラはいくつかありますが、今回は次の4つを取り上げることにします(いずれもWindows用のメーラです)。
メーラ | 開発元 | 最新版(4/5現在) |
---|---|---|
Becky! Internet Mail V2 | リムアーツ | 2.00.11 |
Datula | オンシステムズ | 1.51.09 |
Outlook Express V6 ※1 | マイクロソフト | 6.00.2600.0000 |
Winbiff V2 | オレンジソフト | 2.34PL1 |
※1 Outlook Express V6はInternet Explorer 6に含まれている |
これらのメーラでは、メールサーバとのログを記録することができます。操作方法はそれぞれ以下のとおりです。
Becky! | 「ツール」→「プロトコルログを取る」 |
---|---|
Datula | 「表示」→「Protocol Log...」 |
Outlook Express | 「オプション」→「メンテナンス」→トラブルシューティングの「IMAP」 |
Winbiff | 「ファイル」→「イベントビュアを表示」 |
Outlook Express以外は画面で確認することができますが、Outlook Expressだけは「imap4.log」という名前でログファイルが生成されますので、通信終了後にテキストエディタなどを用いてログファイルを参照してください(ログファイルの格納先フォルダは環境によって変わりますので、エクスプローラの検索機能で探してください)。
なお、以下に示すログでは、分かりやすくするために、レスポンスの多くは省略しています。また、この結果は、あくまでも検証に用いたIMAPサーバにおいての結果であり、別のIMAPサーバでは動作が異なる可能性があることをご了承ください。
Becky! | 0009 CAPABILITY 0010 LOGIN ******** ******** 0011 NAMESPACE 0011 OK Completed |
---|---|
Datula | a001 CAPABILITY a002 AUTHENTICATE LOGIN a003 STATUS "INBOX" (RECENT UNSEEN MESSAGES) a004 NAMESPACE |
Outlook Express | CAPABILITY LOGIN command sent |
Winbiff | A1 CAPABILITY A2 LOGIN ******** A3 NAMESPACE |
IMAPサーバとの接続は、CAPABILITYコマンドによりサーバの機能確認を行った後、ログインする、というのが基本の動作となります。メーラ間の違いはそれほどなく、2点だけです。
Becky! | 0006 LIST "" * |
---|---|
Datula | a019 LIST "" "" a020 LSUB "" "%" a021 LSUB "Shared Folders/User/" "%" a022 LIST "" "%" a023 LIST "Shared Folders/User/" "%" |
Outlook Express | 0002 LIST "" "*" 0003 LSUB "" "*" 0004 LIST "" "INBOX*" 0005 LSUB "" "INBOX*" |
Winbiff | A20 LIST "" "*" A24 LIST "" "Shared Folders/User/*" |
IMAP4では、おのおののメールボックスに購読(subscribe)/未購読(unsubscribe)設定を行うことができます。LSUBコマンドは、購読メールボックスの一覧を取得するコマンドです。DatulaとOutlook Expressは、このLSUBコマンドを用いて、購読メールボックスの一覧を取得し、表示するようにしています。
Datulaは、メールボックス一覧表示でツリーをオープンしたときに、その直下の階層のメールボックス一覧を取得しています。取得するメールボックス数を減らすことができるので、通信時間の短縮に効果があると考えられます。
DatulaとWinbiffは、NAMESPACEによる名前空間を認識していて、共有メールボックス一覧を取得しています。
メールボックス一覧の取得については、Datulaが一番多くの工夫がなされていると思います。DatulaがNNTP(News)クライアントでもあるのも一因でしょう。
Becky! | 0010 SELECT "INBOX" 0011 UID SEARCH ALL 1. 0012 UID SEARCH UNSEEN 0013 UID SEARCH ANSWERED 0014 UID SEARCH DELETED 0015 FETCH 5069:5099 (UID FLAGS RFC822.SIZE RFC822.HEADER) |
---|---|
Datula | a003 SELECT "@IT" a004 FETCH 1:59 (FLAGS UID) 2. a005 FETCH 1:59 (RFC822.SIZE BODY.PEEK[HEADER.FIELDS.NOT (Received)]) |
Outlook Express | SELECT "INBOX" 0003 UID FETCH 213555:* (BODY.PEEK[HEADER.FIELDS (References X-Ref X-Priority X-MSMail-Priority X-MSOESRec Newsgroups)] ENVELOPE RFC822.SIZE UID FLAGS INTERNALDATE) 0004 UID FETCH 1:213554 (UID FLAGS) |
Winbiff | A558 SELECT "inbox" A559 UID SEARCH UNDELETED A560 UID SEARCH FLAGGED UNDELETED A561 UID SEARCH UNSEEN UNDELETED A562 UID SEARCH RECENT UNDELETED A563 UID SEARCH ANSWERED UNDELETED A564 UID FETCH 213819:213822 (UID INTERNALDATE RFC822.SIZE BODY. PEEK[HEADER.FIELDS.NOT ("Received")]) |
●メール一覧の取得
メールの一覧を取得するときには、キャッシュにないメールを探す必要があります。この方法には、大きく分けて2種類あります。1つは、Becky!とWinbiffで使われているSEARCHコマンドを用いた方式(1)。もう1つは、DatulaとOutlook Expressで使われているFETCHコマンドによる方式(2)です。
Becky!のログで流れを見てみましょう。1.により、メールボックスに含まれるすべてのメールのUIDを検索(取得)しています。UIDとは各メールに割り振られたユニークな番号です。このUIDをキーにして、キャッシュに含まれていないメールを検出することができます。この例では、UID=5069〜5099のヘッダ情報をタグ0015のFETCHコマンドで取得しています。0012から0014までのSEARCHコマンドは、各メールのフラグを取得しています。フラグには未読(UNSEEN)/返信済み(ANSWERED)/削除(DELETED)などがあります。IMAP4では、サーバにメールがあるので、ほかのクライアントによりフラグが書き換えられていることもあります。その同期を取るためにフラグを取得し、キャッシュに反映させるわけです。
UIDとフラグを取得してキャッシュと同期を取るという方法論自体は、方式(1)と変わりありません。しかし、UIDとFLAGを取得するのにFETCHコマンドを用いているのが、違う部分です。Datulaのログでは、2.がそれに当たります。Outlook Expressでは、この方式に少し工夫を加えていますが、基本的には同一の方式です。
方式(1)の、SEARCHコマンドを用いる利点は、レスポンスのデータ量が少ないことにあります。SEARCHコマンドのレスポンスは、
A01 UID SEARCH 1:9 ALL * SEARCH 92285 92286 92287 92295 92296 92297 92298 92301 92302 A01 OK Completed
のように1つのタグなしレスポンスにUIDが羅列されますが、FETCHコマンドでは、
A02 FETCH 1:9 UID * 1 FETCH (UID 92285) * 2 FETCH (UID 92286) * 3 FETCH (UID 92287) * 4 FETCH (UID 92295) * 5 FETCH (UID 92296) * 6 FETCH (UID 92297) * 7 FETCH (UID 92298) * 8 FETCH (UID 92301) * 9 FETCH (UID 92302) A02 OK Completed
のように複数のタグなしレスポンスとなり、データ量として倍以上の差が出てしまいます。
●ヘッダの取得
各メーラで、必要とするヘッダを取得しています。独特なのがOutlook Expressで、X-Ref、X-Priority、X-MSMail-Priority、X-MSOESRecといった独自のヘッダも取得しています。
Becky! | 0018 UID FETCH 5070 (BODY) 3. 0019 UID FETCH 5070 (RFC822.HEADER) 4. 0020 UID FETCH 5070 (BODY[1]) 5. |
---|---|
Datula | a007 FETCH 5070 RFC822 |
Outlook Express | 0006 UID FETCH 5070 (BODY.PEEK[] UID) |
Winbiff | A1078 UID FETCH 5070 (BODYSTRUCTURE) A1079 UID FETCH 5070 (BODY.PEEK[HEADER]) A1080 UID FETCH 5070 (BODY.PEEK[1.1]) A1081 UID FETCH 5070 (BODY.PEEK[1.2]) |
IMAP4には、メールのMIME構造を解析して、特定のパートだけを取得する機能があります。メール全体ではなく、添付ファイルを除いたテキストの部分だけを取得するようなことができ、通信量を削減することができます。Becky!とWinbiffでは、MIME構造の解析を用いています。Becky!を例に取ると、3.により、メッセージの構造を取得しています。次の4.と5.では、それぞれヘッダと第1パートのデータを取得しています。
今回はPC用のメーラを例に挙げて、プロトコルの実際の流れを見てきました。これを機会にIMAP4に対応したメーラがもっと増えてくることを期待しています。特に、PalmやPocket PCなどのPDAは、ローカルのストレージが少ないこともあり、IMAP4が実現するリモートメール環境を活用するには最適の素材だと思います。すでにいくつか実装が出ていますが、これから楽しみな環境ではないでしょうか。
Copyright © ITmedia, Inc. All Rights Reserved.