IMAP4サーバから上手くメッセージがダウンロードできないので調べてみたら、サーバのバグだった。iMailというサーバなんだけれども、昔から色々バグがありまくって使い物にならない(のに事情により使われていたりするけど;_;)。
IMAP4のコマンドやレスポンスは()で区切られて返されるのだけれど、サーバがパースに失敗すると、括弧の対応が取れていないレスポンスを返してくる。括弧の対応が取れていないと次のレスポンスの最初を発見することもできないので、一旦セッションを切ってやり直すしかない。
ちなみに、OEの場合、メッセージリストの取得時にエラーが発生すると何も言わずにそのメールだけ表示されなくなる。だから、使っている人は見えていないことにすら気づかないということになる。無茶苦茶なレスポンスを返すサーバもサーバだけど、エラーも出さずにしらばっくれるクライアントもクライアントだよなぁ。。
QMAILはIMAP4サーバに割とむずかしめのコマンドを発行するので、結構サーバのバグが見つかったりします;_;。
2002/02/02で上手く行かないと書いた、本体のHTMLをIInternetProtocol経由でロードできない件は、IInternetProtocolSink::ReportResultの引数を変えたところ上手くいくようになった。
hr = pSink->ReportResult(S_OK, 0, 0);
のようにすればOK。余計なことを考えて、2,3番目の引数を100にしておいたのがいけなかったみたい。
しかし、できたはいいが、2002/01/31に書いた問題がやっぱり発生。MIMEタイプ渡しているのだから、いい加減なHTMLでもHTMLとして処理してくれても良さそうなものなのに。
pSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, ); pSink->ReportData(BSCF_LASTDATANOTIFICATION, 0, 0); pSink->ReportResult(S_OK, 0, 0);
の順番でやればよいということだった。
1. リモートフォルダはフォルダごとにメッセージ本体のダウンロードやフラグ変更専用のセッションを張る(ただしセッション数に上限(設定可)を設けてそれ以上になった場合には古いものを削除)
2. メッセージ本体のダウンロードやフラグの変更はメインスレッドから行う(添付ファイルのダウンロードはバックグラウンドでも行えるようにする?)
3. フォルダのリフレッシュはバックグラウンドスレッドで行う。このときには、1のセッションとは別にセッションを張る。リフレッシュ中に他のフォルダのリフレッシュがかかった場合には、実行中のスレッドをキャンセルするが、終了を待たずに別のスレッドでリフレッシュする
4. 同期・巡回は専用のスレッドを作成して、専用のセッションで行う
5. 同期・巡回と、リフレッシュは干渉せずに同時に行えるようにする(ただし同じフォルダにセッションを張る場合には、先に始まったほうの終了を待つ)
6. 同期・巡回、リフレッシュでメインスレッドはブロックさせない
7. スレッドは設定によってはプールする
1. メモリ節約のためフォルダごとにMutexをひとつずつ用意し、フォルダに対する操作と、そのフォルダ中のメッセージの操作中はそのMutexをロックする
2. フォルダごとにEventを用意し、フォルダの同期中はそのイベントを非シグナル状態にし、終了したらシグナル状態にする。フォルダの同期・リフレッシュする前に、そのEventをチェックする