JavaMail. Поиск IMAP с использованием литерала в Gmail - PullRequest
0 голосов
/ 02 мая 2018

Мне нужна помощь со следующим вопросом:

Мне нужно выполнить поиск, используя не-ascii символы на Gmail ( Кириллица (например Русский или Украинский ) ). Когда я использую стандартную команду IMAP SEARCH, я получаю сообщение об ошибке:

A12 SEARCH CHARSET UTF-8 SUBJECT "текст" ALL
A12 BAD Could not parse command

В Java это выглядит как

Message[] foundMessages = imapFolder.search(new SubjectTerm("текст"));

Здесь я нашел некоторую помощь Поиск в IMAP не-ascii символов . Используя openssl s_client -crlf -connect imap.gmail.com:993 Я подключился к своему почтовому ящику через Terminal и получил следующие результаты:

A12 SEARCH CHARSET UTF-8 X-GM-RAW {10}
+ go ahead
текст
* SEARCH 226
A13 OK SEARCH completed (Success)

Главный вопрос - как это реализовать на Java?

UPDATE

Я провел некоторые исследования исходного кода JavaMail. Я нашел следующие строки

// if server supports UTF-8, enable it for client use
// note that this is safe to enable even if mail.mime.allowutf8=false
if (p.hasCapability("UTF8=ACCEPT") || p.hasCapability("UTF8=ONLY"))
    p.enable("UTF8=ACCEPT");
}

и с сервера Gmail мы получаем следующие возможности

A1 LOGIN test@gmail.com password
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN
X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH 
UTF8=ACCEPT LIST-EXTENDED LIST-STATUS 
LITERAL-SPECIAL-USE APPENDLIMIT=35651584

Итак, JavaMail автоматически устанавливает mail.mime.allowutf8 в true. Но в этом случае JavaMail выполняет поиск с помощью следующей команды

C6 SEARCH CHARSET UTF-8 X-GM-RAW "текст" ALL

И я получаю ошибку

C6 BAD Could not parse command

Я пошел вперед и исследовал https://github.com/javaee/javamail/blob/52e04fc107d0b83fa794e6f622f7c76b9e85e395/mail/src/main/java/com/sun/mail/iap/Argument.java#L313

Argument.nastring(byte[] bytes, Protocol protocol, boolean doQuote)

boolean utf8 = protocol.supportsUtf8 (); -> Для Gmail это правда . Вот почему JavaMail не использует литерал.

byte b;
for (int i = 0; i < len; i++) {
    b = bytes[i];
    if (b == '\0' || b == '\r' || b == '\n' ||
        (!utf8 && ((b & 0xff) > 0177))) {
    // NUL, CR or LF means the bytes need to be sent as literals
    literal(bytes, protocol);
    return;
    }
    if (b == '*' || b == '%' || b == '(' || b == ')' || b == '{' ||
        b == '"' || b == '\\' ||
        ((b & 0xff) <= ' ') || ((b & 0xff) > 0177)) {
    quote = true;
    if (b == '"' || b == '\\') // need to escape these characters
        escape = true;
    }
}

Я проверил другого провайдера электронной почты, у которого нет UTF8=ACCEPT. И все отлично работает.

K11 SEARCH CHARSET UTF-8 SUBJECT {10}
+ continue
текст ALL
* SEARCH 1194
K11 OK SEARCH completed

1 Ответ

0 голосов
/ 02 мая 2018

При быстром взгляде на источник, он должен просто работать, если вы используете javamail 1.6.1. Возможно, вы захотите / должны установить для свойства mail.mime.allowutf8 значение true.

Более подробно: в 1.6 добавлена ​​поддержка адресов электронной почты в Юникоде, таких как jøran@blåbærsyltetøy.gulbrandsen.priv.no, что в качестве побочного эффекта регулирует использование UTF8 практически везде. Когда вы подключаетесь к gmail, javamail 1.6 должен отправить команду входа в систему, затем автоматически одну из команд a04 enable utf8=accept, и после того, как gmail подтвердит utf8 = accept, a12 search subject "текст" all станет допустимым синтаксисом, который должен делать то, что вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...