2016-04-18 2 views
0

Моя команда и я кодировали почтовый компонент, который будет использоваться другими командами в нашем приложении. Этот компонент предназначен для загрузки электронных писем с использованием пользовательских условий поиска. Тот, который используется в настоящий момент, представляет собой поиск по почте между диапазоном дат из учетных записей Gmail с использованием IMAP protocol. Он работал нормально до 4 апреля 2016 года 6:00 GMT + 1, загружая только электронную почту в пределах диапазона. Однако с 8:00 по Гринвичу + 1 ответ от сервера внезапно изменился, и он начал возвращать всю папку INBOX!Различные результаты между запросом IMAP

Повторяя начальные тесты, мы обнаружили, что мы получили всю папку INBOX вместо тех, что находятся в пределах диапазона. После некоторых исследований вплоть до запроса IMAP, казалось, что Gmail изменилось количество писем возвращается при определенных условиях:

  • Когда «дата начала» SearchTerm был ComparisonTerm.GT термина, или
  • Когда " дата окончания»SearchTerm был ComparisonTerm.LE термин

В обоих случаях IMAP сервер Gmail возвращает все письма в папке. Напротив, в качестве примера, IMAP-сервер Yahoo просто возвращает те письма, которые соответствуют данному условию.

Мы открыли им билет, спросив, были ли какие-либо изменения в их ответе, но они ответили, что ничего не изменили. Конечно, нет способа доказать это (у нас еще нет машины времени).

Поскольку мы оказали большое влияние на это неожиданное поведение, мы решили продолжить исследование, и мы создали простой почтовый клиент для загрузки почты с использованием различных комбинаций условий с разных серверов IMAP.

Начиная с this link's, мы добавили функциональность для проверки с другими, но сменив библиотеку, чтобы удовлетворить нашу версию javax.mail 1.5.5. Поэтому мы избегаем различных способов реализации.

код прилагается ниже:

package gmail; 

import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.Properties; 

import javax.mail.Folder; 
import javax.mail.Message; 
import javax.mail.Session; 
import javax.mail.Store; 
import javax.mail.search.AndTerm; 
import javax.mail.search.ComparisonTerm; 
import javax.mail.search.ReceivedDateTerm; 
import javax.mail.search.SearchTerm; 

public class JavaMailTest { 

    public static void main(String[] args) { 

     JavaMailTest testClient=new JavaMailTest(); 

     //Yahoo 
     //SEARCH SINCE 3-Apr-2016 BEFORE 7-Apr-2016 ALL 
     testClient.performTest(testClient.getYahooImapProps(),ComparisonTerm.GE,ComparisonTerm.LT); 
     //Gmail 
     //SEARCH SINCE 3-Apr-2016 BEFORE 7-Apr-2016 ALL 
     testClient.performTest(testClient.getGmailImapProps(),ComparisonTerm.GE,ComparisonTerm.LT); 
     //Yahoo 
     //SEARCH SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL 
     testClient.performTest(testClient.getYahooImapProps(),ComparisonTerm.GE,ComparisonTerm.LE); 
     //Gmail 
     //SEARCH SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL 
     testClient.performTest(testClient.getGmailImapProps(),ComparisonTerm.GE,ComparisonTerm.LE); 
     //Yahoo 
     //SEARCH NOT ON 3-Apr-2016 SINCE 3-Apr-2016 BEFORE 7-Apr-2016 ALL 
     testClient.performTest(testClient.getYahooImapProps(),ComparisonTerm.GT,ComparisonTerm.LT); 
     //Gmail 
     //SEARCH NOT ON 3-Apr-2016 SINCE 3-Apr-2016 BEFORE 7-Apr-2016 ALL 
     testClient.performTest(testClient.getGmailImapProps(),ComparisonTerm.GT,ComparisonTerm.LT); 
     //Yahoo 
     //SEARCH NOT ON 3-Apr-2016 SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL 
     testClient.performTest(testClient.getYahooImapProps(),ComparisonTerm.GT,ComparisonTerm.LE); 
     //Gmail 
     //SEARCH NOT ON 3-Apr-2016 SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL 
     testClient.performTest(testClient.getGmailImapProps(),ComparisonTerm.GT,ComparisonTerm.LE); 

    } 

    public int performTest(Properties props, int startTermCondition, int endTermCondition) 
    { 
     try { 
      Session session = Session.getDefaultInstance(props, null); 
      Message[] totalMessages = null; 

      Store store = session.getStore(props.getProperty("protocol")); 
      store.connect(props.getProperty("mail.imap.host"), props.getProperty("account"), props.getProperty("pass")); 
      Folder inbox = store.getFolder("inbox"); 
      inbox.open(Folder.READ_ONLY); 


      SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd"); 
      Date startDate = ft.parse("2016-04-03"); 
      Date endDate = ft.parse("2016-04-07"); 

      System.out.println("Testing email account: <"+props.getProperty("account")+"> with startDate: <" + startDate + "> (ComparisonTerm."+ 
        getConditionText(startTermCondition)+") and endDate: <" + endDate+"> (ComparisonTerm."+getConditionText(endTermCondition)+")"); 

      Message[] messages = inbox.getMessages(); 

      if (messages != null && messages.length > 0) { 
       SearchTerm startDateTearm = 
         new ReceivedDateTerm(startTermCondition, startDate); 

       SearchTerm endDateTerm = 
         new ReceivedDateTerm(endTermCondition, endDate); 

       SearchTerm andTerm = new AndTerm(startDateTearm, endDateTerm); 

       totalMessages = inbox.search(andTerm); 
       if(totalMessages.length > 0){ 
        System.out.println("Found "+totalMessages.length+" matching messages (Total messages in folder: "+messages.length+")"); 
       } 

       /*for (int i = 0; i < totalMessages.length; i++) { 
        System.out.println(totalMessages[i].getReceivedDate() + " --> Mail Subject:- " + totalMessages[i].getSubject()); 

       }*/ 
       //First message 
       int currentMessage=0; 
       System.out.println("First Message: "+totalMessages[currentMessage].getReceivedDate() + " --> Mail Subject: " + totalMessages[currentMessage].getSubject().substring(0, 5)); 
       //Last message 
       currentMessage=totalMessages.length-1; 
       System.out.println("Last Message: "+totalMessages[currentMessage].getReceivedDate() + " --> Mail Subject: " + totalMessages[currentMessage].getSubject().substring(0, 5)); 
      } 


      inbox.close(true); 
      store.close(); 
      return totalMessages.length; 

     } catch (Exception e) { 
      e.printStackTrace(); 
      return -1; 
     } 

    } 

    public static String getConditionText(int condition) 
    { 
     String returnValue=""; 
     switch (condition) { 
     case ComparisonTerm.EQ: 
      returnValue="EQ"; 
      break; 
     case ComparisonTerm.GE: 
      returnValue="GE"; 
      break; 
     case ComparisonTerm.GT: 
      returnValue="GT"; 
      break; 
     case ComparisonTerm.LE: 
      returnValue="LE"; 
      break; 
     case ComparisonTerm.LT: 
      returnValue="LT"; 
      break; 
     case ComparisonTerm.NE: 
      returnValue="NE"; 
      break; 
     default: 
      returnValue="Error"; 
      break; 
     } 
     return returnValue; 
    } 

    public Properties getYahooImapProps() 
    { 
     Properties props = new Properties(); 
     //Yahoo 
     String imapServer="imap.mail.yahoo.com"; 
     String imapPort="993"; 
     String account="********@yahoo.es"; 
     String pass="*********"; 

     props.setProperty("mail.imap.host", imapServer); 
     props.setProperty("mail.imap.port", imapPort); 
     props.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 
     props.setProperty("mail.imap.auth", "true"); 
     props.setProperty("account", account); 
     props.setProperty("pass", pass); 
     props.setProperty("protocol", "imaps"); 

     return props; 

    } 

    public Properties getGmailImapProps() 
    { 
     Properties props = new Properties(); 
     //Gmail 
     String imapServer="imap.gmail.com"; 
     String imapPort="143"; 
     String account="******@gmail.com"; 
     String pass="********"; 

     props.setProperty("mail.imap.host", imapServer); 
     props.setProperty("mail.imap.port", imapPort); 
     /*props.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 
     props.setProperty("mail.imap.auth", "true");*/ 
     props.setProperty("account", account); 
     props.setProperty("pass", pass); 
     props.setProperty("protocol", "imap"); 

     return props; 
    } 

} 

Чтобы сделать вывод программы понятнее, я добавил запрос прямо перед первым выходом метода:

//SEARCH SINCE 3-Apr-2016 BEFORE 7-Apr-2016 ALL 
    Testing email account: <*********@yahoo.es> with startDate: <Sun Apr 03 00:00:00 CEST 2016> (ComparisonTerm.GE) and endDate: <Thu Apr 07 00:00:00 CEST 2016> (ComparisonTerm.LT) 
    Found 5 matching messages (Total messages in folder: 78) 
    First Message: Mon Apr 04 23:14:22 CEST 2016 --> Mail Subject: Aviso 
    Last Message: Tue Apr 05 00:48:00 CEST 2016 --> Mail Subject: Alter 
    //SEARCH SINCE 3-Apr-2016 BEFORE 7-Apr-2016 ALL 
    Testing email account: <*********@gmail.com> with startDate: <Sun Apr 03 00:00:00 CEST 2016> (ComparisonTerm.GE) and endDate: <Thu Apr 07 00:00:00 CEST 2016> (ComparisonTerm.LT) 
    Found 92 matching messages (Total messages in folder: 20138) 
    First Message: Sun Apr 03 04:08:47 CEST 2016 --> Mail Subject: Tu es 
    Last Message: Wed Apr 06 22:12:45 CEST 2016 --> Mail Subject: ¿Quie 
    //SEARCH SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL 
    Testing email account: <*********@yahoo.es> with startDate: <Sun Apr 03 00:00:00 CEST 2016> (ComparisonTerm.GE) and endDate: <Thu Apr 07 00:00:00 CEST 2016> (ComparisonTerm.LE) 
    Found 5 matching messages (Total messages in folder: 78) 
    First Message: Mon Apr 04 23:14:22 CEST 2016 --> Mail Subject: Aviso 
    Last Message: Tue Apr 05 00:48:00 CEST 2016 --> Mail Subject: Alter 
    //SEARCH SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL 
    Testing email account: <*********@gmail.com> with startDate: <Sun Apr 03 00:00:00 CEST 2016> (ComparisonTerm.GE) and endDate: <Thu Apr 07 00:00:00 CEST 2016> (ComparisonTerm.LE) 
    Found 20138 matching messages (Total messages in folder: 20138) 
    First Message: Sat Sep 04 13:23:35 CEST 2004 --> Mail Subject: Gmail 
    Last Message: Tue Apr 19 10:09:06 CEST 2016 --> Mail Subject: El re 
    //SEARCH NOT ON 3-Apr-2016 SINCE 3-Apr-2016 BEFORE 7-Apr-2016 ALL 
    Testing email account: <*********@yahoo.es> with startDate: <Sun Apr 03 00:00:00 CEST 2016> (ComparisonTerm.GT) and endDate: <Thu Apr 07 00:00:00 CEST 2016> (ComparisonTerm.LT) 
    Found 5 matching messages (Total messages in folder: 78) 
    First Message: Mon Apr 04 23:14:22 CEST 2016 --> Mail Subject: Aviso 
    Last Message: Tue Apr 05 00:48:00 CEST 2016 --> Mail Subject: Alter 
    //SEARCH NOT ON 3-Apr-2016 SINCE 3-Apr-2016 BEFORE 7-Apr-2016 ALL 
    Testing email account: <*********@gmail.com> with startDate: <Sun Apr 03 00:00:00 CEST 2016> (ComparisonTerm.GT) and endDate: <Thu Apr 07 00:00:00 CEST 2016> (ComparisonTerm.LT) 
    Found 20138 matching messages (Total messages in folder: 20138) 
    First Message: Sat Sep 04 13:23:35 CEST 2004 --> Mail Subject: Gmail 
    Last Message: Tue Apr 19 10:09:06 CEST 2016 --> Mail Subject: El re 
    //SEARCH NOT ON 3-Apr-2016 SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL 
    Testing email account: <*********@yahoo.es> with startDate: <Sun Apr 03 00:00:00 CEST 2016> (ComparisonTerm.GT) and endDate: <Thu Apr 07 00:00:00 CEST 2016> (ComparisonTerm.LE) 
    Found 5 matching messages (Total messages in folder: 78) 
    First Message: Mon Apr 04 23:14:22 CEST 2016 --> Mail Subject: Aviso 
    Last Message: Tue Apr 05 00:48:00 CEST 2016 --> Mail Subject: Alter 
    //SEARCH NOT ON 3-Apr-2016 SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL 
    Testing email account: <*********@gmail.com> with startDate: <Sun Apr 03 00:00:00 CEST 2016> (ComparisonTerm.GT) and endDate: <Thu Apr 07 00:00:00 CEST 2016> (ComparisonTerm.LE) 
    Found 20138 matching messages (Total messages in folder: 20138) 
    First Message: Sat Sep 04 13:23:35 CEST 2004 --> Mail Subject: Gmail 
    Last Message: Tue Apr 19 10:09:06 CEST 2016 --> Mail Subject: El re 

Из этого результата можно сказать следующее :

  • Yahoo возвращает правильное количество писем с учетом данных условий Java.
  • Запрос Javamail, вероятно, слишком неоднозначен.
  • @Gmail: учитывая множество условий в некоторых запросах ... почему вы просто решили вернуть всю папку?
  • Почему существует другой ответ на тот же запрос?
  • Кто вернул почту прямо?
  • Не протоколы, предназначенные для хранения вещей вместо того, чтобы сделать его еще хуже?

Мы также пробовали с учетной записью Outlook с тем же результатом, что и Gmail.

+0

Протоколы обычно предназначены для стандартизации, но это не обязательно единственная цель, и иногда это не главный приоритет. Иногда это конфликтует с простотой реализации и проигрывает. В случае поиска по дате IMAP явно не определяет обработку часового пояса, поэтому, если предел SINCE отличается на несколько часов между серверами, это разрешено. Конечно, это не то, что вы видите: я предлагаю только комментарий, а не ответ. – arnt

ответ

0

Это похоже на ошибку в Gmail для меня. Я смог воспроизвести его сам. Я действительно удивлен, если Outlook.com имеет ту же ошибку.

Почему, по вашему мнению, запрос неоднозначен? Спецификация IMAP довольно ясна.

Несколько замечаний ...

+0

Я помню, что заметил javamail ИЛИ и задался вопросом, что за ошибка, с которой вы работали. И теперь я вижу, что это была ошибка, а не обходной путь;) – arnt

+0

Мой контакт в Google подтвердил, что это ошибка Gmail, которая будет исправлена ​​очень скоро. –

0

@BillShannon

Я думаю, @ popilla20k видит запрос неоднозначный, потому что, когда он делает запрос с "GT" И "LE" SEARCHTERM (andTerm), он разлагается, например, :

// ПОИСК SINCE 3-апрель-2016 ИЛИ ПЕРЕД 7-апр-2016 7-апр-2016 ВСЕ

Я должен сказать, что я видел изменения в поведении Google, 6 апреля. За несколько дней до этого я получил все письма, которые с условием «GT» и «LE» searchTerm. После 6 апреля я вижу такое же поведение, показанное @ popilla20k (используя javamail 1.5.5)

Несмотря на это, я думаю, что статья ИЛИ ПЕРЕД инвалидами первой. Разве это должно быть предложение И, не так ли? Во всяком случае, за несколько дней до 6 апреля на те же запросы ответили иначе, чем сейчас.

Спасибо.

+0

Вы неправильно понимаете синтаксис запроса IMAP. OR - это префиксный оператор, применяемый к двум поисковым терминам, которые приходят после него - к терминам BEFORE и терминам ON. Термин OR объединяется с термином SINCE, используя операцию по умолчанию И для нескольких условий поиска. –

+0

Вы правы. Итак, для меня ясно, что мы имеем дело с ошибкой IMAP Google. Спасибо, Билл. – santhai

Смежные вопросы