Вторник, 24.06.2025, 18:00 Приветствую Вас Гость

Мой сайт

Меню сайта
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » 2013 » Декабрь » 30 » IMAP: трудности перехода
14:03
 

IMAP: трудности перехода

12 сентября 2012 в 15:13

IMAP: трудности перехода

Какие грабли зарыты в IMAP



Уже некоторое время IMAP работает в Почте Mail.Ru в полную силу, и я готов рассказать о том, с какими проблемами мы столкнулись при его запуске. Часть из них была связана с особенностями самого протокола и с его историей, другие были обусловлены спецификой взаимодействия IMAP с нашим хранилищем. Отдельная категория трудностей вызвана многообразием почтовых клиентов.

За подробностями — добро пожаловать под кат.
gen_smtp.

Тестовые письма

Все три письма идентичны и все с вложениями. Только для последнего (первого в списке) был указан параметр application=pdf. Content-Type во всех случаях был application/pdf.
Что конкретно, мы отправлялось, не проверяли.
Если, любопытно, могу и покопаться.
Такая проблема была (и есть?) только у mail.ru.

Извиняюсь за офтоп (хотя вся ветка — оффтоп),
но на всякий пожарный приведу код:
mail( {FromName, FromEmail}, {ToName, ToEmail}, Subject, Body, {AttachName, AttachBinary} ) -> Email = {<<"multipart">>, <<"mixed">>, [ {<<"From">>, mmh_person(FromName, FromEmail)}, {<<"To">>, mmh_person(ToName, ToEmail)}, {<<"Subject">>, list_to_binary(Subject)}], [], [ %% Тело письма {<<"text">>,<<"plain">>, [], [], list_to_binary(Body)}, %% Аттачменты(PDF) {<<"application">>,<<"pdf">>, [{<<"Content-Type">>,<<"application/pdf">>}, {<<"Content-Transfer-Encoding">>,<<"base64">>}], [ {<<"content-type-params">>, [{<<"name">>, list_to_binary(AttachName)}], [{<<"x-unix-mode">>,<<"0644">>}]}, {<<"disposition">>,<<"attachment">>}, {<<"disposition-params">>,[{<<"filename">>, list_to_binary(AttachName)}]}], AttachBinary} ]}, gen_smtp_client:send( { FromEmail, [ToEmail], mimemail:encode(Email) }, ?SYS_MAIL_OPTIONS ).

Ага, т.е. речь все-таки об SMTP сервере. Я слишком плохо знаком с erlang-ом, чтобы суметь легко попробовать этот пример. Не могли бы вы сгенерить тела этих двух писем (с глюком и без), положить их в zip-архив и прислать мне на v.starodub {собака} corp.mail.ru? Мы разберемся, где именно глюк — в телах писем, или же в SMTP/веб-интерефейсе, если у нас — то с радостью починим.

Как я понимаю, генерацию производит вызов mimemail:encode(), а gen_smtp занимается уже отправкой?

SMTP сервере. — Клиенте.
Gen_smtp занимается отправкой, но только в качестве клиента. Отправкой занимается sendmail (как я понимаю), который находится удаленно.
Остальное, вы поняли правильно.

Возможно, как верно подметил ниже Макс, это как раз пример такого «чудного клиента».
Попробую сделать что вы сказали.

Думаю, что тут вряд ли дело в клиенте, т.к. SMTP — очень агностичный протокол по отношению к телу письма, smtp-клиенту редко нужно уметь парсить mime письма дальше нескольких хэдеров и вообще разбираться, что там внутри. Исключение составляет только разве что binary extension.

Нужно смотреть в тело письма.

Если я воспроизвел именно ту ошибку о которой говорил, то я немного соврал. Уж слишком давно это было. Да и во общем, вроде уже проблему решили, не актуально.

Проболема была в multipart/alternative. Т.о., с вашей стороны все было сделано, формально правильно. Однако, поведение, интерфейса почты
— странно, и несколько не предсказуемо.

Пока пытался воспроизвести, эту проблему я нашел, еще несколько интересных особенностей. Сервисы на которых, я тестировал почту были выбраны от балды (никаких предрассудков и предрасположенностей не имею), просто нужно было с чем-то сравнивать.

  1. Если указать, multipart не mixed, a alternative, в mail.ru вложение приходит то в гриде просмотра почты не отображается, что есть вложение. У mail.yandex.ru показывает, что вложение есть, но в письма вложения вообще нет (скачивать нечего). То, что вложение есть показывается не сразу после получения письма, а если немного подождать. У gmail.сom все ок.
    Если я действительно, воспроизвел ту самую проблему, понятно, почему у mail.yandex.ru она не была замечена. Не факт, что внутрь письма заглядывали, когда тестировали полгода назад.

  2. Была замечена ошибка у mail.yandex.ru. Если отправлять письмо без, Content-Transfer-Encoding: base64 то в гриде просмотра почты не отображается, что есть вложение. Всего скорее проблемы в интерфейсе. Потому что поcле просмотра письма значок аттача появляется. У mail.ru все ок. У gmail.сom все ок.
  3. Если не указать disposition-params у mail.ru, то нет аттача в гриде просмотра почты. Если открыть само письмо, то аттач есть (Untitled.pdf вместо имени). Проблема всего скорее только в интерфейсе, ибо thunderbird этот аттач видит и до открытия письма. У mail.yandex.ru в этом случае вообще не показывает аттача. У gmail.сom все ок, но вложение соответсвенно называется noname (без расширения).
  4. Была замечена ошибка у mail.yandex.ru Если отправлять письмо без, content-type-params, то в гриде просмотра почты не отображается, что есть вложение. У mail.ru все ок. У gmail.сom все ок.


Несколько урезанные версии писем на которых тестировалось:
gist.github.com/b5bb40d982604b40b5b7
Полные версии продублировал на почту.

>Уже некоторое время IMAP работает в Почте Mail.Ru в полную силу
Гмайл IMAP с 2008 г.
Яндекс IMAP с 2009 г.
Про IMAP на Mail.Ru в 2012 смешно читать, как и о почте на Mail.Ru, уж извините, хотя за статью спасибо.

Я рад, что наша статья вызывает у вас положительные эмоции. Сейчас обхохочетесь еще больше:

Newmail.ru IMAP с 2001 г.
Hotbox.ru IMAP с 2002 г.
Gmail IMAP с 2008 г.

Обе почте несколько лет назад объединились в составе mail.qip.ru и здравствуют и поныне.

Обе эти почты — это сейчас mail.qip.ru, которая по российской дневной аудитории где-то на уровне Rambler-почты, т.е. четвертая почта после Mail.Ru, Yandex и GMail. mail.qip.ru, конечно, по российской суточной аудитории отличается в разы от ближайшего к ней GMail, но и GMail в разы меньше Mail.Ru по тому же параметру.

Как раз в те годы, когда там внедряли имап, эти сервисы были достаточно популярны, не только сейчас. Навскидку: у меня именно в 2001-м основной ящик был на newmail.ru, как и у многих моих друзей.

Актуальность имапа тогда была достаточно высока: веб-интерфейсы были убогие по современным меркам, почтовые программы были бесспорно удобнее. Интернет был дорогой и слабый, возможность не качать весь свой ящик, работать с папками на сервере выглядела достаточно привлекательно. Поддержка имапа этими сервисами в своем роде даже большее достижение, чем имап на гмейле в 2008-м.

Но если говорить именно про «сейчас», так в современном своем виде имап более актуален для мобильных клиентов, которые в силу своих ограничений по объему persistent-хранилища просто не могут адекватно работать с pop3. Если посмотреть на графики, то мобильных клиентов больше половины.

Но нормальная поддержка имапа, более-менее соответствующая RFC и работающая не только с gmail-ом и еще парой серверов, например, в андроиде появилась чуть позже появления версии 2.2, а это был уже 2010 год. В 2008-м не было такого рынка устройств, корректно поддерживающих imap, соответственно актуальность самого протокола была не так высока.

С 2008 года поменялось многое: команда почты mail.ru поменялась практически целиком, как поменялись и приоритеты. К сожалению, я не мог написать имап в 2008 году, как бы ни хотел, т.к. я еще тогда не работал в команде почты и в mail.ru вообще, а Денис тогда как раз делал поддержку имапа в яндексе :)

В своем посте я систематизировал технические нюансы реализации imap-а. Возможно, кому-то это будет просто любопытно, кому-то подкинет мыслей, скажем, при написании imap-клиента. Если бы я что-то в этом роде прочитал перед написанием сервера — мне это бы сэкономило некоторое количество времени. Если вам это неинтересно и вызывает лишь скептицизм — простите меня за то, что вы решили прочесть эту статью.

Спасибо за статью! А можно вкратце про dovecot — помимо сложностей с прикручиванием к хранилищу, какие ещё с ним были проблемы? От него пришлось отказаться в основном из-за хранилища, или это была только половина проблемы?

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

Но у нас сервер, к сожалению, писался не совсем абстрактно: есть уже хранилище с достаточно громоздким C-шным API, кроме того, внутри проекта почты сервер-сайд сейчас пишут на С/C++, perl-е и python-е. Программистов на эрланге у нас в команде просто нет. Т.е. даже если сервер на нем и написать, то читать его код будет потом некому. Плюс, надо изобретать какие-то обертки для C-шного кода в эрланг, либо поддерживать 2 версии клиентской библиотеки к стороджу.

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

Да и на самом деле, на C++ при правильном подходе, код оказался довольно лаконичным: со всеми хаками для всех клиентов, там имапной специфики около 5000 строк. :)

Плюс, надо изобретать какие-то обертки для C-шного кода в эрланг

Для таких вещей все и придумывалось. Наш стримящий сервер был написан тоже в лохматые времена на C. Не мешает его испрльзовать через erlang. Тем более, не надо ничего изобретать!
www.erlang.org/doc/tutorial/c_port.html
Реальный пример использования:
github.com/zavr/erlxslt (многопоточная обертка над libxslt)

Программистов на эрланге у нас в команде просто нет.

Вопрос двух недель. У нас тоже не было.

Если Вы любите, TeX, пример — есть такие хорошие понятия в TeX как «блоки» и «клей». В переложении на мир технологий, erlang — и есть этот «клей». Это не просто еще один язык разработки, в том-то и его преимущество (мы же Вам не ocaml или haskell предлагаем).
Можно писать, на самом erlang все, но если уже что-то есть сделанное, не обязательно переписывать. Составные части, как мне кажется, логично продолжить писать на сях, а вот склеивать их эрлангом. Но это мое скромное мнение.
Вам, в вашей ситуации виднее.

Хм, ну уж нет. Я, например, лично не готов :) Толстовато, в общем)

Вообще, это странная тема… я могу более-менее читаемо, быстро и лаконично писать на C++(надеюсь, что так). Вы — на erlang. Если мы поменяемся местами, то, скорее всего, наша продуктивность резко снизится (во всяком случае, моя уж точно). Хуже от этого будет только пользователям mail.ru, которые получат имап позже :) При этом, при всех прелестях erlang-а, вряд ли я сразу напишу maintainable код.

А кроме erlang-а еще много интересных технологий. Говорят, в последнем .NET-е интересные фишки в плане асинхронности добавили, а еще он тоже быстро компилируется. Scala тоже интересный и красивый язык с функциональными плюшками.

Но если все пробовать, то кто и когда код писать-то будет? Да и по мне, так добавление еще одного языка, даже самого передового, в любой корпоративный зоопарк технологий только усложняет интеграцию.

А как же синергетический эффект? )

в плане асинхронности добавили

К сожалению, особенности .NET и java-машины, не позволяют, на мой взгляд, сделать полноценную асинхронность. Во общем, есть на то математические основания.

получат имап позже

Возможно, а возможно и раньше. + есть одна важная деталь — сопровождение. Не только сегодняшним днем живем. И не в любых своих (и чужих) исходниках двухлетней давности приятно разбираться.

Как раз для изучения плюсов и минусов той или иной технологии, применительно к текущим задачам и нужны в компании консультанты.

В плане .NET — я на нем писал давно и не очень много. Но об этих улучшениях написано в release notes, друзья говорили, что стало удобнее. Это был просто пример того, что есть и другие интересные технологии, которые в принципе можно попробовать :)

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

Я лично, как инженер, считаю, что язык программирования — не главное. На практически любом языке можно сделать удобную для проекта и задач платформу. Главное — хорошо владеть выбранным инструментом.

Консультанты — это хорошо, но я помню, что в Parallels, например, по совету консультантов начали пытаться переписывать всю автоматизацию на java. Имхо, это был очень странный шаг, который стоил компании нескольких толковых специалистов и отнял порядочно времени. С любым подходом главное — не перестараться :)

Это ветка, конечно, похожа на холивар, но Вы приводите интересные и очень разумные аргументы, потому предлагаю продолжить.
Получат позже Я с Вами согласен, что применять что-то пилотное в активном и критически важном проекте — не правильно. Но, как мне кажется, нужно смотреть дальше чем один проект. Живем не сегодняшним днем, и Ваши 5k строк через некоторое время могут превратиться в 50k, 500k строк (и это нормально) и их надо будет как-то поддерживать. Если есть немного свободного времени, посмотрите Cesarini F. Erlang programming, и сравните с тем что уже имеете.
язык программирования Согласен, но как лингвист, я скажу что любые языки принципиально не эквивалентны. Сам язык, что — просто набор правил над некоторым множеством символов. Но за каждым естественным языком стоит его культура. За искусственным — парадигма, или архитектура абстрактной машины этого языка.
Знание внешней оболочки языка, без понимания основания делает человека «языковым чудищем». Вы просто спросили как пройти, а вам морду набили.
Парадигмы-то они эквивалентны, но некоторые вещи в лямда выражениях выглядят проще, удобнее, эффективнее, чем в рамках стековой машины (java, .net, python) или машины фон Неймана (C\C++, Fortran).
сделать удобную для проекта и задач платформу По сути, тоже реализация некоторого языка, на основе существующего. А такое лучше делать на функционального подхода. + Делать платформу — это тоже время. А если она станет одноразовой, и даже частично не применимой, к чему-то другому — слишком дорого.
Локальные решения это хорошо, но только они не позволяют находить других локальных решений, которые, может быть, лучше. Траншею можно копать саперной лопаткой, а можно экскаватором. Если траншея одна в принципе, то лопатой, конечно быстрее. Она получится даже аккуратнее. А на экскаваторщика придется еще учиться. Но если траншей сотни, то лопата уже не применима.
Просмотров: 227 | Добавил: wicepten | Рейтинг: 0.0/0
Всего комментариев: 0
Поиск
Календарь
«  Декабрь 2013  »
Пн Вт Ср Чт Пт Сб Вс
      1
2345678
9101112131415
16171819202122
23242526272829
3031
Архив записей
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Copyright MyCorp © 2025 Бесплатный конструктор сайтовuCoz