サイト内で配布中のライブラリについてのスレッド。 バグ報告・質問など。 (最新15件の投稿) Atom 1.0

※ブラウザによっては新しい書き込みが表示されない場合があるようなので、返信がないか確認したい場合はF5または更新ボタンでページの更新を試してください。

: ID:cipeco0y

配布中のライブラリについてのバグ報告・要望・質問用のスレッドです。
書き込みの際は再現用のコードやログなどもあわせて書き込んで頂けると助かります。

: ID:v+9G1zYP

VB版DLLを使用してGmailからImapのメール取得を行っておりますが、
本文が文字化けてしまい上手く取得が出来ません。
以下の書き方に問題はありますでしょうか。

~Clientの定義~
For Each message As ImapMessageInfo In inbox.GetMessages(ImapSearchCriteria.Unseen)
  Dim part As ImapMessagePartInfo
    part = message.MessagePart

  body = part.ReadAllText(ImapMessageFetchBodyOptions.OmitHeader) ←ここで取得した本文が文字化けている
~本文取得後の処理~
: ID:+LyRQS9z

>>214
ライブラリをご利用いただきありがとうございます。

ご提示頂いたコードの場合、ImapMessagePartInfo.ReadAllTextは本文をデコードされていない(生の)状態で返します。

デコードされた状態の本文が必要な場合は、ImapMessageFetchBodyOptions.OmitHeader(ヘッダの省略)と同時に
ImapMessageFetchBodyOptions.DecodeContent(内容のデコード)を組み合わせて指定してください。

なお、デコード動作の詳細についてはドキュメント下記セクションの注釈をご覧ください。
http://smdn.jp/works/libs/Smdn.Net.Imap4.Client/docs/#operation_reference_messagepart_readbody

: ID:v+9G1zYP

>>215
早急な返信ありがとうございます!

デコードされた状態の本文が必要な場合は、ImapMessageFetchBodyOptions.OmitHeader(ヘッダの省略)と同時にImapMessageFetchBodyOptions.DecodeContent(内容のデコード)を組み合わせて指定してください。

とありますが、

ReadAllText(ImapMessageFetchBodyOptions.OmitHeader)

この部分で複数のオプションを組み合わせる方法があるのでしょうか?
複数のオプションを組み合わせる方法が見つけられず
度々の質問となってしまい申し訳ありませんが、ご教示頂けると幸いでございます。

: ID:v+9G1zYP

>>216

上記質問をさせて頂きましたが、
オプションを足し算して、それをImapMessageFetchBodyOptions型にCastすることにより、
複数のオプションが指定できました。

ありがとうございました。

: ID:hWCHaFlN

はじめまして。
こちらのライブラリを使用させて頂いており、大変感謝しております。

現在、Microsoft365に対してIMAP接続するプログラムを作成しておりますが、
ログイン(ImapClientのConnectメソッド)で以下のExceptionが起きております。

upgrading stream failed (callback: System.IO.Stream CreateSslStream(Smdn.Net.ConnectionBase, System.IO.Stream))

それも起きるときと起きない時があり、対応に苦慮しております。

そもそも動作状況にMicrosoft365が無いので、このライブラリを使用させて頂くこと自体
おかしいのかもしれませんが、解決の糸口になればと思い書き込みさせて頂きました。

お手数ですが、ご確認いただけますと幸いです。よろしくお願いいたします。

: ID:1ki2F+Cn

>>219
ライブラリをご利用いただきありがとうございます。

ご報告いただいた例外についてですが、例外メッセージを見る限りでは
サーバーまたはライブラリのどちらに問題があるか判別できません。

そこで恐れ入りますが、原因特定のためにライブラリのバージョンを含む
環境情報と、例外が発生した際のログ、また可能であれば接続時に指定している
パラメータをご提示いただけますでしょうか。

ログの収集については >>28 あるいは以下のページをご参照ください。
https://smdn.jp/works/libs/Smdn.Net.Imap4.Client/docs/#logging

なお動作状況に関してですが、当方ではMicrosoft365での動作確認ができていないものの、
本ライブラリは一般的なIMAPサーバーであれば概ね動作すると見込んでいるので、
本不具合をクリアすればMicrosoft365でも動作するのではないかと思います。

: ID:hWCHaFlN

>>220
ご返信ありがとうございます。

早速ですが、ご依頼の情報を提示させて頂きます。

お手数ですが、ご確認をお願いいたします。

  • サーバー
    • Windows Server 2012 R2 Standard(VMware上)
    • Windows Updateは、全て適用済み(10/8時点)
  • 開発環境
    • .Net Framework4.5+C#(Visual Studio 2017)
  • ライブラリ
    • Smdn 3.0.0-beta4
    • Smdn.Formats.Mime 0.91.0
    • Smdn.Fundamental.* 3.0.0
    • Smdn.Fundamental.Bufferのみ 3.0.2
    • Smdn.Net.Imap4.Client 1.91.0
    • Smdn.Net.MessageAccessProtocols 1.91.0
    • Smdn.Security.Authentication.Sasl 1.91.0
  • 該当部分のソース
    using (var imapClient = new ImapClient("outlook.office365.com", 993, true, "ユーザー"))
    {
        try
        {
            imapClient.Connect("パスワード");
        }
        catch (Exception ex)
        {
            //...例外時処理
        }
    }
    
  • ログ(スタックトレース)
    場所 Smdn.Net.Imap4.Protocol.ImapConnectionBase.Connect(String host, Int32 port, Int32 millisecondsTimeout, UpgradeConnectionStreamCallback createAuthenticatedStreamCallback)
    場所 Smdn.Net.Imap4.Protocol.Client.ImapConnection..ctor(String host, Int32 port, Int32 millisecondsTimeout, UpgradeConnectionStreamCallback createAuthenticatedStreamCallback)
    場所 Smdn.Net.Imap4.Client.Session.ImapSession.Connect(String host, Int32 port, Int32 connectTimeout, Int32 sendTimeout, Int32 receiveTimeout, UpgradeConnectionStreamCallback createAuthenticatedStreamCallback)
    場所 Smdn.Net.Imap4.Client.Session.ImapSession..ctor(String host, Int32 port, Int32 transactionTimeout, Int32 sendTimeout, Int32 receiveTimeout, Boolean handlesReferralAsException, UpgradeConnectionStreamCallback createAuthenticatedStreamCallback)
    場所 Smdn.Net.Imap4.Client.Session.ImapSessionCreator.CreateSession(IImapSessionProfile profile, SaslClientMechanism authMechanismSpecified, UpgradeConnectionStreamCallback createSslStreamCallback, CancellationToken cancellationToken, ImapSession& session)
    場所 Smdn.Net.Imap4.Client.Session.ImapSessionCreator.CreateSession(IImapSessionProfile profile, SaslClientMechanism authMechanismSpecified, UpgradeConnectionStreamCallback createSslStreamCallback, CancellationToken cancellationToken)
    場所 Smdn.Net.Imap4.Client.ImapClient.CreateSession(ConnectParams params)
    場所 Smdn.Net.Imap4.Client.ImapClient.<>c__DisplayClass74_0.<Connect>b__0()
    場所 Smdn.Net.Imap4.Client.ImapClient.RunExclusively(Action operation, Boolean throwIfNotConnected)
    場所 Smdn.Net.Imap4.Client.ImapClient.Connect(ConnectParams params)
    場所 Smdn.Net.Imap4.Client.ImapClient.Connect(String password)
    
: ID:1ki2F+Cn

>>221
情報をご提供いただきありがとうございます。

ログに関してですが、キャッチした例外のInnerExceptionを含めた内容を
取得していただけますでしょうか?

try
{
    imapClient.Connect("パスワード");
}
catch (Exception ex)
{
    // ここでキャッチした例外の、InnerExceptionも含めた詳細が知りたい
    // DebugあるいはConsoleに出力することでInnerExceptionも含めた
    // スタックトレースが表示されるので、この内容を教えてください
    Debug.WriteLine(ex);
    Console.WriteLine(ex);
}

InnerExceptionにupgrading stream failedとなった根本原因が含まれているので
こちらの情報を知りたいと思っています。

再度のお願いで恐縮ですがよろしくお願いします。

: ID:hWCHaFlN

>>222
失礼いたしました。

改めてログを取得しましたので、ご確認のほど、よろしくお願いいたします。

Smdn.Net.Imap4.Protocol.ImapSecureConnectionException: upgrading stream failed (callback: System.IO.Stream CreateSslStream(Smdn.Net.ConnectionBase, System.IO.Stream)) ---> Smdn.Net.Imap4.Protocol.ImapUpgradeConnectionException: upgrading stream failed (callback: System.IO.Stream CreateSslStream(Smdn.Net.ConnectionBase, System.IO.Stream)) ---> System.IO.IOException: リモート パーティがトランスポート ストリームを終了したため、認証に失敗しました。
   場所 System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   場所 System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   場所 System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   場所 System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   場所 System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   場所 System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   場所 System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
   場所 Smdn.Net.ConnectionBase.CreateClientSslStream(ConnectionBase connection, Stream baseStream, X509Certificate2Collection clientCertificates, SslProtocols enabledSslProtocols, RemoteCertificateValidationCallback serverCertificateValidationCallback, LocalCertificateSelectionCallback clientCertificateSelectionCallback)
   場所 Smdn.Net.Imap4.Client.ImapSslConnection.CreateSslStream(ConnectionBase connection, Stream baseStream)
   場所 Smdn.Net.ConnectionBase.UpgradeStream(UpgradeConnectionStreamCallback upgradeStreamCallback)
   --- 内部例外スタック トレースの終わり ---
   場所 Smdn.Net.ConnectionBase.UpgradeStream(UpgradeConnectionStreamCallback upgradeStreamCallback)
   場所 Smdn.Net.ConnectionBase.Connect(String host, Int32 port, Int32 millisecondsTimeout, UpgradeConnectionStreamCallback createAuthenticatedStreamCallback)
   場所 Smdn.Net.Imap4.Protocol.ImapConnectionBase.Connect(String host, Int32 port, Int32 millisecondsTimeout, UpgradeConnectionStreamCallback createAuthenticatedStreamCallback)
   --- 内部例外スタック トレースの終わり ---
   場所 Smdn.Net.Imap4.Protocol.ImapConnectionBase.Connect(String host, Int32 port, Int32 millisecondsTimeout, UpgradeConnectionStreamCallback createAuthenticatedStreamCallback)
   場所 Smdn.Net.Imap4.Protocol.Client.ImapConnection..ctor(String host, Int32 port, Int32 millisecondsTimeout, UpgradeConnectionStreamCallback createAuthenticatedStreamCallback)
   場所 Smdn.Net.Imap4.Client.Session.ImapSession.Connect(String host, Int32 port, Int32 connectTimeout, Int32 sendTimeout, Int32 receiveTimeout, UpgradeConnectionStreamCallback createAuthenticatedStreamCallback)
   場所 Smdn.Net.Imap4.Client.Session.ImapSession..ctor(String host, Int32 port, Int32 transactionTimeout, Int32 sendTimeout, Int32 receiveTimeout, Boolean handlesReferralAsException, UpgradeConnectionStreamCallback createAuthenticatedStreamCallback)
   場所 Smdn.Net.Imap4.Client.Session.ImapSessionCreator.CreateSession(IImapSessionProfile profile, SaslClientMechanism authMechanismSpecified, UpgradeConnectionStreamCallback createSslStreamCallback, CancellationToken cancellationToken, ImapSession& session)
   場所 Smdn.Net.Imap4.Client.Session.ImapSessionCreator.CreateSession(IImapSessionProfile profile, SaslClientMechanism authMechanismSpecified, UpgradeConnectionStreamCallback createSslStreamCallback, CancellationToken cancellationToken)
   場所 Smdn.Net.Imap4.Client.ImapClient.CreateSession(ConnectParams params)
   場所 Smdn.Net.Imap4.Client.ImapClient.<>c__DisplayClass74_0.<Connect>b__0()
   場所 Smdn.Net.Imap4.Client.ImapClient.RunExclusively(Action operation, Boolean throwIfNotConnected)
   場所 Smdn.Net.Imap4.Client.ImapClient.Connect(ConnectParams params)
   場所 Smdn.Net.Imap4.Client.ImapClient.Connect(String password)
   場所 ローカルの呼出元のため、省略
Smdn.Net.Imap4.Protocol.ImapSecureConnectionException: upgrading stream failed (callback: System.IO.Stream CreateSslStream(Smdn.Net.ConnectionBase, System.IO.Stream)) ---> Smdn.Net.Imap4.Protocol.ImapUpgradeConnectionException: upgrading stream failed (callback: System.IO.Stream CreateSslStream(Smdn.Net.ConnectionBase, System.IO.Stream)) ---> System.IO.IOException: リモート パーティがトランスポート ストリームを終了したため、認証に失敗しました。
   場所 System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   場所 System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   場所 System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   場所 System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   場所 System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   場所 System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   場所 System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
   場所 Smdn.Net.ConnectionBase.CreateClientSslStream(ConnectionBase connection, Stream baseStream, X509Certificate2Collection clientCertificates, SslProtocols enabledSslProtocols, RemoteCertificateValidationCallback serverCertificateValidationCallback, LocalCertificateSelectionCallback clientCertificateSelectionCallback)
   場所 Smdn.Net.Imap4.Client.ImapSslConnection.CreateSslStream(ConnectionBase connection, Stream baseStream)
   場所 Smdn.Net.ConnectionBase.UpgradeStream(UpgradeConnectionStreamCallback upgradeStreamCallback)
   --- 内部例外スタック トレースの終わり ---
   場所 Smdn.Net.ConnectionBase.UpgradeStream(UpgradeConnectionStreamCallback upgradeStreamCallback)
   場所 Smdn.Net.ConnectionBase.Connect(String host, Int32 port, Int32 millisecondsTimeout, UpgradeConnectionStreamCallback createAuthenticatedStreamCallback)
   場所 Smdn.Net.Imap4.Protocol.ImapConnectionBase.Connect(String host, Int32 port, Int32 millisecondsTimeout, UpgradeConnectionStreamCallback createAuthenticatedStreamCallback)
   --- 内部例外スタック トレースの終わり ---
   場所 Smdn.Net.Imap4.Protocol.ImapConnectionBase.Connect(String host, Int32 port, Int32 millisecondsTimeout, UpgradeConnectionStreamCallback createAuthenticatedStreamCallback)
   場所 Smdn.Net.Imap4.Protocol.Client.ImapConnection..ctor(String host, Int32 port, Int32 millisecondsTimeout, UpgradeConnectionStreamCallback createAuthenticatedStreamCallback)
   場所 Smdn.Net.Imap4.Client.Session.ImapSession.Connect(String host, Int32 port, Int32 connectTimeout, Int32 sendTimeout, Int32 receiveTimeout, UpgradeConnectionStreamCallback createAuthenticatedStreamCallback)
   場所 Smdn.Net.Imap4.Client.Session.ImapSession..ctor(String host, Int32 port, Int32 transactionTimeout, Int32 sendTimeout, Int32 receiveTimeout, Boolean handlesReferralAsException, UpgradeConnectionStreamCallback createAuthenticatedStreamCallback)
   場所 Smdn.Net.Imap4.Client.Session.ImapSessionCreator.CreateSession(IImapSessionProfile profile, SaslClientMechanism authMechanismSpecified, UpgradeConnectionStreamCallback createSslStreamCallback, CancellationToken cancellationToken, ImapSession& session)
   場所 Smdn.Net.Imap4.Client.Session.ImapSessionCreator.CreateSession(IImapSessionProfile profile, SaslClientMechanism authMechanismSpecified, UpgradeConnectionStreamCallback createSslStreamCallback, CancellationToken cancellationToken)
   場所 Smdn.Net.Imap4.Client.ImapClient.CreateSession(ConnectParams params)
   場所 Smdn.Net.Imap4.Client.ImapClient.<>c__DisplayClass74_0.<Connect>b__0()
   場所 Smdn.Net.Imap4.Client.ImapClient.RunExclusively(Action operation, Boolean throwIfNotConnected)
   場所 Smdn.Net.Imap4.Client.ImapClient.Connect(ConnectParams params)
   場所 Smdn.Net.Imap4.Client.ImapClient.Connect(String password)
   場所 ローカルの呼出元のため、省略
: ID:1ki2F+Cn

>>223
例外詳細のご提供ありがとうございます。

原因は特定できていないものの、以下のようにTLS 1.2を使用することで
接続できる可能性があります。 ですので、まずはこれを試してください。

// SSL/TLS接続時にTLS 1.2を用いるように指定する
ImapSslConnection.EnabledSslProtocols = SslProtocols.Tls12;

// 以下現在と同様のコードで可
using (var imapClient = new ImapClient("outlook.office365.com", 993, true, "ユーザー"))
{
    imapClient.Connect("パスワード");
        ︙
        ︙

ImapSslConnectionクラスについては以下を参照してください。
https://smdn.jp/works/libs/Smdn.Net.Imap4.Client/docs/#connection_ssl

また、これは根本的な解決にはなりませんが、もし接続失敗するときに発生する
例外の種類が常に今回と同じものであり、かつ、何度かリトライすれば接続できる
状況なのであれば、以下のように接続できるまで接続を試行するという方法も
とることができます。

using (var imapClient = new ImapClient("outlook.office365.com", 993, true, "ユーザー")) {
  bool connected = false;

  while (!connected) {
    try {
      imapClient.Connect("パスワード");

      connected = true;
    }
    catch (ImapConnectionException ex) {
      // 接続に関する例外が発生した場合、多少時間を開けた後…
      Thread.Sleep(1000);
      // …接続をリトライする
      continue;
    }
  }

  // 以降、接続出来た場合の処理を継続する
}

以下は例外から推測できる原因についてです。

頂いたログから確認できる限りでは、SSL/TLSでの接続を開始する際に、
サーバー側から処理が中断されているようです。

その理由ははっきりしませんが、一つ可能性があるのが、TLS 1.0および1.1の廃止です。
(参考: https://docs.microsoft.com/ja-jp/microsoft-365/compliance/tls-1.0-and-1.1-deprecation-for-office-365)
この場合、SslProtocols.Tls12を指定することで回避できます。

もう一つ、同時接続数などサーバー側での制限の可能性も考えられます。
この場合は、先に上げたコードのようにリトライすることで対応できます。

ただ、原因がTLSのバージョンなら、例外が起きる場合と起きない場合がある点が不可解で、
接続数等の制限が原因ならSSL/TLSのネゴシエーション途中で中断されている点が
若干不可解です。
このため、他に理由がある可能性も考えられます。

いずれにしても、少なくともサーバー側の理由で接続処理が中断されている
ようなので、根本的な原因についてはサーバー側の設定等をご確認ください。

もし提示いただいた以外の例外がスローされるようなら、クライアント側の問題の
可能性もあるので、その場合はご相談ください。

: ID:hWCHaFlN

>>223
調査、ありがとうございます。

ひとまず、TLS1.2の設定を入れてしばらく様子を見てみます。
もしまた例外が起こるようでしたら、リトライ処理を入れることも検討いたします。

いずれにしろ、後ほど結果をご報告いたします。

また、作者様の方で提供してほしい情報がありましたら、ご連絡いただければ、
できる範囲で対応いたしますので、お申し付けください。

引き続きよろしくお願いいたします。

: ID:hWCHaFlN

>>225
すみません、アンカー間違えました。
正しくは、>>224 への返信でした。

: ID:hWCHaFlN

>>226
お世話になっております。

ご教授頂いたTLS1.2を使用することでエラーが発生しなくなりました。
1週間ほど経過していますが、1度もエラーが発生しておりません。

大変助かりました。ありがとうございました。

今後ともどうぞよろしくお願いいたします。

: ID:1ki2F+Cn

>>227
結果をお知らせ頂きありがとうございます。
Microsoft365での動作に関する情報をいただけてこちらも助かりました。

⚠一度書き込みが完了すると、以降は投稿内容を編集できません
  • >>1と入力すると1番へのアンカーになります。
  • 投稿内容はPukiWiki記法で整形されます。
    • 以下のPukiWiki記法が使えます。
      • 引用文
      • 番号付きリスト、番号なしリスト、定義リスト
      • 整形済みテキスト
        • 複数行のコードブロックを書き込むには次のように記入してください。
          #code{{
          int x = 2;
          int y = 3;
          }}
        • 複数行のコマンド出力を書き込むには次のように記入してください。
          #prompt{{
          C:\> echo "foo"
          "foo"
          }}
      • 表組み
      • 見出し
      • 強調・斜体、取り消し線・下線
      • 文字色(&color)、文字サイズ(&size)
      • 注釈
    • URL・メールアドレスは自動的にリンクになります。
    • 詳しくはPukiWikiのFormattingRulesを参照してください。