public static bool Test(BaseProtocolClient ingoingMailClient, MailServerSettings settings) { try { var sResult = ingoingMailClient.Authorize(settings, settings.MailServerOperationTimeoutInMilliseconds); if (sResult.ToLower().IndexOf("success", StringComparison.Ordinal) == -1 && sResult.ToLower().IndexOf("+", StringComparison.Ordinal) == -1 && sResult.ToLower().IndexOf("ok", StringComparison.Ordinal) == -1) { if (ingoingMailClient is Imap4Client) throw new ImapConnectionException(sResult); if(ingoingMailClient is Pop3Client) throw new Pop3ConnectionException(sResult); else throw new SmtpConnectionException(sResult); } return true; } catch (TargetInvocationException exTarget) { if (ingoingMailClient is Imap4Client) throw new ImapConnectionException(exTarget.InnerException.Message); if(ingoingMailClient is Pop3Client) throw new Pop3ConnectionException(exTarget.InnerException.Message); else throw new SmtpConnectionException(exTarget.InnerException.Message); } catch (TimeoutException) { if (ingoingMailClient is Imap4Client) throw new ImapConnectionTimeoutException(); if (ingoingMailClient is Pop3Client) throw new Pop3ConnectionTimeoutException(); else throw new SmtpConnectionTimeoutException(); } finally { if (ingoingMailClient.IsConnected) { try { ingoingMailClient.Disconnect(); } catch {} } } }
protected abstract bool ProcessMessages(BaseProtocolClient baseProtocolClient);
static public bool Test(BaseProtocolClient ingoing_mail_client, MailServerSettings settings) { try { IAsyncResult async_res; switch (settings.EncryptionType) { case EncryptionType.StartTLS: async_res = ingoing_mail_client.BeginConnect(settings.Url, settings.Port, null); break; case EncryptionType.SSL: async_res = ingoing_mail_client.BeginConnectSsl(settings.Url, settings.Port, null); break; default: async_res = ingoing_mail_client.BeginConnect(settings.Url, settings.Port, null); break; } if (!async_res.AsyncWaitHandle.WaitOne(WAIT_TIMEOUT)) throw new ImapConnectionTimeoutException(); if (settings.EncryptionType == EncryptionType.StartTLS) { ingoing_mail_client.StartTLS(settings.Url); } if (settings.AuthenticationType == SaslMechanism.Login) { ingoing_mail_client.Login(settings.AccountName, settings.AccountPass, ""); } else { async_res = ingoing_mail_client.BeginAuthenticate(settings.AccountName, settings.AccountPass, settings.AuthenticationType, null); } if (!async_res.AsyncWaitHandle.WaitOne(WAIT_TIMEOUT)) throw new ImapConnectionTimeoutException(); if (async_res.AsyncState == null) throw new AuthenticationException("Auth failed. Check your settings."); string s_result = ingoing_mail_client.EndConnectSsl(async_res).ToLowerInvariant(); if (s_result.IndexOf("success", StringComparison.Ordinal) == -1 && s_result.IndexOf("+", StringComparison.Ordinal) == -1 && s_result.IndexOf("ok", StringComparison.Ordinal) == -1) throw new ImapConnectionException(s_result); return true; } finally { if (ingoing_mail_client.IsConnected) { ingoing_mail_client.Disconnect(); } } }
protected override bool ProcessMessages(BaseProtocolClient baseProtocolClient) { var client = (Pop3Client) baseProtocolClient; UpdateTimeCheckedIfNeeded(); var badMessagesExist = false; if (!_isUidlSupported) { log.Info("UIDL is not supported! Account '{0}' has been skiped.", Account.EMail); return true; } var newMessages = GetPop3NewMessagesIDs(client); var quotaErrorFlag = false; if (client.IsConnected) { if (newMessages.Count == 0) log.Debug("New messages not found.\r\n"); else { log.Debug("Found {0} new messages.\r\n", newMessages.Count); if (newMessages.Count > 1) { log.Debug("Calculating order"); try { var firstHeader = client.RetrieveHeaderObject(newMessages.First().Key); var lastHeader = client.RetrieveHeaderObject(newMessages.Last().Key); if (firstHeader.Date < lastHeader.Date) { log.Debug("Account '{0}' order is DESC", Account.EMail.Address); newMessages = newMessages .OrderByDescending(item => item.Key) // This is to ensure that the newest message would be handled primarily. .ToDictionary(id => id.Key, id => id.Value); } else log.Debug("Account '{0}' order is ASC", Account.EMail.Address); } catch (Exception) { log.Warn("Calculating order skipped! Account '{0}' order is ASC", Account.EMail.Address); } } var skipOnDate = Account.BeginDate != MailBoxManager.MinBeginDate; var skipBreakOnDate = MailQueueItemSettings.PopUnorderedDomains.Contains(Account.Server.ToLowerInvariant()); foreach (var newMessage in newMessages) { var hasParseError = false; cancelToken.ThrowIfCancellationRequested(); try { if (_maxMessagesPerSession == 0) { log.Debug("Limit of max messages per session is exceeded!"); break; } if (!client.IsConnected) { log.Warn("POP3-server is disconnected. Skip another messages."); badMessagesExist = true; break; } log.Debug("Processing new message\tUID: {0}\tUIDL: {1}\t", newMessage.Key, newMessage.Value); var message = client.RetrieveMessageObject(newMessage.Key); if (message.HasParseError) { log.Error("ActiveUp: message parsed with some errors."); hasParseError = true; } UpdateTimeCheckedIfNeeded(); if (message.Date < Account.BeginDate && skipOnDate) { if (!skipBreakOnDate) { log.Info("Skip other messages older then {0}.", Account.BeginDate); break; } log.Debug("Skip message (Date = {0}) on BeginDate = {1}", message.Date, Account.BeginDate); continue; } var uniqueIdentifier = string.Format("{0}|{1}|{2}|{3}", message.From.Email, message.Subject, message.DateString, message.MessageId); var headerMd5 = uniqueIdentifier.GetMd5(); RetrieveMessage(message, MailFolder.Ids.inbox, newMessage.Value, headerMd5, hasParseError); } catch (Exception e) { var commonError = string.Format( "ProcessMessages() Tenant={0} User='******' Account='{2}', MailboxId={3}, MessageIndex={4}, UIDL='{5}' Exception:\r\n{6}\r\n", Account.TenantId, Account.UserId, Account.EMail.Address, Account.MailBoxId, newMessage.Key, newMessage.Value, e); if (e is IOException || e is MailBoxOutException) { _maxMessagesPerSession = 0; //It needed for stop messsages proccessing. badMessagesExist = true; if (e is IOException) log.Error(commonError); else log.Info(commonError); break; } if (e is TenantQuotaException) { log.Info("Tenant {0} quota exception: {1}", Account.TenantId, e.Message); quotaErrorFlag = true; } else { badMessagesExist = true; log.Error(commonError); } } UpdateTimeCheckedIfNeeded(); _maxMessagesPerSession--; } } } else { log.Debug("POP3 server is disconnected."); badMessagesExist = true; } if (Account.QuotaError != quotaErrorFlag && !Account.QuotaErrorChanged) { Account.QuotaError = quotaErrorFlag; Account.QuotaErrorChanged = true; } return !badMessagesExist && _maxMessagesPerSession > 0; }
protected override bool ProcessMessages(BaseProtocolClient baseProtocolClient) { var client = (Imap4Client)baseProtocolClient; var mailboxes = client.GetImapMailboxes(Account.Server, MailQueueItemSettings.SpecialDomainFolders, MailQueueItemSettings.SkipImapFlags, MailQueueItemSettings.ImapFlags) .Reverse() .OrderBy(m => m.folder_id) .ToList(); if (!mailboxes.Any()) log.Error("There was no folder parsed! MailboxId={0}", Account.MailBoxId); var index = mailboxes.FindIndex(x => x.name.ToUpperInvariant() == "INBOX"); if (index > 0) { //Move folder INBOX to top of list in order to quickly receive new messages var item = mailboxes[index]; mailboxes[index] = mailboxes[0]; mailboxes[0] = item; } var quotaErrorByTotalFolders = false; foreach (var mailbox in mailboxes) { log.Info("Select imap folder: {0}", mailbox.name); Mailbox mbObj; cancelToken.ThrowIfCancellationRequested(); if (!client.IsConnected) break; try { mbObj = client.SelectMailbox(mailbox.name); } catch (Exception ex) { log.Error("imap.SelectMailbox(\"{0}\") in MailboxId={1} failed with exception:\r\n{2}", mailbox.name, Account.MailBoxId, ex.ToString()); continue; } bool quotaErrorFlag; _maxMessagesPerSession = LoadMailboxMessage(mbObj, mailbox.folder_id, _maxMessagesPerSession, mailbox.tags, out quotaErrorFlag); if (quotaErrorFlag) quotaErrorByTotalFolders = true; if (0 == _maxMessagesPerSession) break; UpdateTimeCheckedIfNeeded(); } if (Account.QuotaError != quotaErrorByTotalFolders && !Account.QuotaErrorChanged) { Account.QuotaError = quotaErrorByTotalFolders; Account.QuotaErrorChanged = true; } return true; }