Процедуры, диагностики и безопасность в Интернет

Протокол электронной почты. Примеры и расширения

Показывать лекцию целиком

Примеры и дальнейшие расширения

Когда используется механизм внешнего тела в сочетании с типом среды multipart/alternative, это расширяет функциональность multipart/alternative, так как включает случай, когда один и тот же объект может быть получен через разные механизмы доступа. Когда это сделано, отправитель сообщения должен упорядочить части по предпочтительности формата, а затем по механизму доступа.

Для распределенных файловых систем очень трудно знать заранее группу машин, где файл может быть доступен непосредственно. Следовательно, имеет смысл предоставить как имя файла на случай его прямой доступности, так имена одного или нескольких узлов, где может быть доступен этот файл. Программные реализации могут пытаться извлечь удаленные файлы, используя FTP или другой протокол. Если внешнее тело доступно за счет нескольких механизмов, отправитель может включить несколько объектов типа message/external-body в секции тела объекта multipart/alternative.

Однако механизм внешнего тела не ограничивается извлечением файлов, как это показывается типом доступа mail-server. Помимо этого, можно предположить, например, использование видеосервера для внешнего доступа к видеоклипам.

Поля заголовка вложенного сообщения, которые появляются в теле message/external-body, должны применяться для декларации типа среды внешнего тела, если оно представляет собой нечто отличное от чистого текста US-ASCII, так как внешнее тело не имеет секции заголовка, чтобы декларировать тип. Аналогично здесь должно быть также декларировано любое транспортное кодирование, отличное от 7bit. Таким образом, полное сообщение message/external-body, относящееся к объекту в формате PostScript, может выглядеть как:

From: От кого-то
To: Кому-то
Date: Когда-то
Subject: Нечто
MIME-Version: 1.0
Message-ID: <id@itep.com>
Content-Type: multipart/alternative; boundary=42
Content-ID:
--42
Content-Type: message/external-body; name="BodyFormats.ps";
site="thumper.bellcore.com"; mode="image";
access-type=ANON-FTP; directory="pub";
expiration="Fri, 14 Jun 1991 19:13:14 -0400 (EDT)"
Content-type: application/postscript
Content-ID:
--42
Content-Type: message/external-body; access-type=local-file;
name="/u/nsb/writing/rfcs/RFC-MIME.ps";
site="thumper.bellcore.com";
expiration="Fri, 14 Jun 1991 19:13:14 -0400 (EDT)"
Content-type: application/postscript
Content-ID:
--42
Content-Type: message/external-body;access-type=mail-server
< server="listserv@bogus.bitnet">
expiration="Fri, 14 Jun 1991 19:13:14 -0400 (EDT)"
Content-type: application/postscript
Content-ID:
get RFC-MIME.DOC
--42--

Заметим, что в вышеприведенных примерах в качестве транспортного кодирования для Postscript данных предполагается 7bit.

Подобно типу message/partial, тип среды message/external-body предполагается прозрачным, т.е. передается тип данных внешнего тела, а не сообщение с телом данного типа. Таким образом, заголовки внешней и внутренней частей должны быть объединены с использованием правил, изложенных выше для message/partial. В частности, это означает, что поля Content-type и Subject переписываются, а поле From сохраняется в неизменном виде.

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

Заметим, что тело сообщения типа message/external-body регламентируется базовым синтаксисом сообщения RFC 822. В частности, все, что размещено перед первой парой CRLF является заголовком, в то время как все, что следует после заголовка, представляет собой данные, которые игнорируются для большинства типов доступа.

Подобно тому, как это рассказано в начале описания MIME, методика сконструирована так, чтобы допустить использование не-ASCII символов в заголовках сообщения, чтобы специфические почтовые программы (а) удаляли некоторые поля заголовков, сохраняя другие, (b) меняли содержимое адресов в полях To или Cc, (c) меняли вертикальный порядок размещения полей заголовка. Кроме того, некоторые почтовые программы не всегда способны корректно интерпретировать заголовки сообщений, в которых встречаются некоторые редко используемые рекомендации документа RFC 822, например, символы обратной косой черты для выделения специальных символов типа "<", "," или ":".

Расширения, описанные здесь, не базируются на редко используемых возможностях RFC-822. Вместо этого определенные последовательности обычных печатных ASCII-символов (известных как encoded-words — кодировочные слова) зарезервированы для использования в качестве кодированных данных. Синтаксис кодированных слов таков, что они вряд ли могут появиться в нормальном тексте заголовков сообщений. Более того, символы, используемые в кодировочных словах, не могут иметь специального назначения в контексте, где появляются эти слова.

Вообще, encoded-word представляет собой последовательность печатных ASCII-символов, которая начинается с "=?", завершается "?=" и имеет два "?" между ними. Оно специфицирует символьный набор и метод кодирования, а также включает в себя оригинальный текст в виде графических ASCII-символов, созданный согласно правилам данного метода кодирования.

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

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

Данный документ в заметной мере базируется на нотации и терминах RFC-822 и RFC-2045. В частности, синтаксис для ABNF, применяемый здесь, определен в RFC-822. Среди терминов, определенных в RFC-822 и использованных в данном документе: addr-spec (спецификация адреса), атом, CHAR, комментарий, CTL, ctext, linear-white-space (HT|SP|CRLF), фраза, quoted-pair, закавыченная строка, пробел и слово. Успешная реализация расширения этого протокола требует тщательного внимания к определениям этих терминов в RFC-822.

Когда в данном документе встречается термин ASCII, он относится к 7-битовому стандарту, ANSI X3.4-1986. Имя этого символьного набора в MIME US-ASCII.

Синтаксис кодировочных слов (encoded-words)

Кодировочное слово определено согласно следующей ABNF-грамматике. Используется нотация RFC-822, за исключением того, что символы white space (HT и SP – символы табуляции и пробела) не должны появляться между компонентами кодировочного слова.

encoded-word = "=?" charset "?" encoding "?" encoded-text "?="
charset = token
encoding = token
token = 1*
especials = "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / 
  " <"> / "/" / "[" / "]" / "?" / "." / "="
encoded-text = 1*<Любой печатный ASCII-символ, отличный от "?" или пробела (SP)>
; (см. "Использование encoded-words в заголовках сообщений")

Слова encoding и charset не зависят от регистра, в котором напечатаны. Таким образом, символьный набор с именем ISO-8859-1 эквивалентен iso-8859-1, а кодирование с именем "Q" может записываться как "Q" или "q".

Кодировочное слово не может быть длиннее 75 символов, включая charset, encoding, encoded-text и разделители. Если желательно закодировать текст, больший, чем 75 символов, можно использовать несколько кодировочных слов, разделенных CRLF SP.

Хотя ограничений на длину многострочного поля заголовка нет, каждая строка поля заголовка, которая содержит одно или более кодировочных слов, ограничена 76 символами.

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

Кодировочные слова сконструированы так, чтобы быть узнаваемыми как атомы программой грамматического разбора RFC-822. Как следствие, незакодированные символы SP и HT в пределах кодировочных слов запрещены. Например, символьная последовательность

=?iso-8859-1?q?this is some text?=

будет воспринята программой разборки RFC-822 как четыре атома, а не как один атом или как кодировочное слово (в случае программы разборки, воспринимающей кодировочные слова). Правильный способ закодировать строку "this is some text" — это кодировать и сами пробелы, например:

=?iso-8859-1?q?this=20is=20some=20text?=

Символьный набор

Секция charset кодировочного слова специфицирует символьный набор, соответствующий незакодированному тексту. Charset может представлять любой символьный набор, разрешенный параметром charset MIME части тела text/plain, или любой символьный набор с именем, зарегистрированным IANA для использования с типом содержимого text/plain MIME.

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

Когда имеется возможность использования более одного символьного набора для представления текста в кодировочном слове и в отсутствие частного соглашения между отправителем и получателем сообщения, рекомендуется использовать объекты символьного семейства ISO-8859-*.

Кодирование

Первоначально легальными значениями кодирования являются Q и B. Эти кодировки описаны ниже. Кодирование Q рекомендуется для использования, когда большинство символов, которые нужно преобразовать, представлены в наборе ASCII; в противном случае, следует использовать B-кодирование. Несмотря ни на что, программа, читающая почту, которая воспринимает кодировочные слова, должна быть способна обрабатывать любые кодировки для любых символьных наборов, которые она поддерживает.

В кодированном тексте может использоваться только субнабор печатных ASCII-символов. Символы SP и HT не допустимы, чтобы начало и конец кодировочного слова были выделены однозначно. Символ "?" используется в кодировочном слове для разделения различных частей этого слова друг от друга. По этой причине "?" не может появляться в секциях кодировочного слова. Другие символы могут также оказаться нелегальными в определенном контексте. Например, encoded-word во фразе, предшествующей адресу в поле заголовка From, не может содержать какие-либо специальные символы, определенные в RFC-822. Наконец, некоторые другие символы также недопустимы в определенных контекстах, это связано с необходимостью обеспечить надежность пересылки сообщений через почтовые шлюзы.

B-кодирование автоматически отвечает этим требованиям. Q-кодирование допускает использование широкого перечня печатных символов в некритических позициях заголовка сообщения (например, в Subject), с ограниченным списком символов, допустимых в других полях. B-кодирование идентично BASE64, описанному RFC-2045.

Q-кодирование

Q-кодирование подобно закавыченным строкам печатных символов (Quoted-Printable), описанным в RFC-2045. Оно создано, чтобы позволить читать текст, содержащий по большей части ASCII-символы, на алфавитно-цифровом терминале без декодирования.

  • Любой 8-битовый код может быть представлен с помощью символа "=", за которым следуют два шестнадцатеричных числа. Например, если бы используемый символьный набор был ISO-8859-1, символ "=" кодировался как "=3D", а пробел (SP) как "=20". (Для шестнадцатеричных чисел следует использовать верхний регистр "A" - "F".)
  • 8-битовое шестнадцатеричное число 20 (напр., ISO-8859-1 SPACE) может быть представлено как "_" (знак подчеркивания, ASCII 95). (Этот символ может не пройти через некоторые почтовые шлюзы, но его использование существенно улучшает читаемость Q-кодированных данных в почтовых системах, которые поддерживают этот вид кодирования). Заметим, что "_" всегда представляется шестнадцатеричным кодом 20, даже если символ пробел (SPACE) занимает другую кодовую позицию в используемом символьном наборе
  • 8-битовые значения, которые соответствуют печатным ASCII-символам, отличным от "=", "?" и "_", могут быть представлены самими собой. SP и HT не должны представляться самими собой в пределах кодировочных слов
  • Использование кодировочных слов в заголовках сообщений

    Encoded-word может появиться в заголовке сообщения или в заголовке тела секции в соответствии со следующими правилами.

  • encoded-word может заменить текстовую лексему (как это определено в RFC-822) в любом из полей заголовка Subject или Comments, в любом поле расширения заголовка или любом поле секции тела MIME. Обычный ASCII-текст и кодировочные слова могут появляться совместно в пределах одного и того же поля заголовка. Однако кодировочное слово, появляющееся в поле заголовка, определенное как '*text', должно быть отделено от любого смежного encoded-word или текста с помощью LWS (HT|SP|CRLF)
  • encoded-word может появляться внутри комментария, ограниченного "(" и ")", т.е., там, где допустим 'ctext'. Более точно, ABNF-определение (RFC-822) для 'comment' следует скорректировать как:
    comment = "(" *(ctext | quoted-pair | comment | encoded-word) ")"

    Q-кодированное encoded-word, которое появляется в комментарии, не должно содержать символов "(", ")" или ". Кодировочное слово, появляющееся в комментарии, должно отделяться от смежного encoded-word или ctext с помощью LWS.

    Важно заметить, что комментарии распознаются только внутри структурированных полей тела. В полях, чьи тела определены как '*text', "(" и ")" обрабатываются как обычные символы, а не как разделители комментариев, и применимо правило (1) этой секции.

  • encoded-word может появляться в качестве замены для объекта word во фразе, например, перед адресом в заголовке From, To или Cc. ABNF-определение для phrase RFC-822 приобретает вид:
    phrase = 1*( encoded-word / word)

    В этом случае набор символов, который можно использовать с Q-кодированным encoded-word, ограничивается до: <ASCII-буква верхнего и нижнего регистров, десятичные цифры, "!", "*", "+", "-", "/", "=" и "_" (ASCII 95)>. Кодировочное слово, которое появляется внутри фразы, должно быть отделено от любого смежного слова, текста или специального символа посредством LWS. Это единственные места, где может появиться encoded-word. В частности:

  • encoded-word не должно появляться в любой части addr-spec ;
  • encoded-word не должно появляться в пределах quoted-string (закавыченная строка);
  • encoded-word не должно использоваться в поле заголовка Received ;
  • encoded-word не должно использоваться в параметре MIME поля Content-Type, или Content-Disposition, или в любом структурированном поле тела, за исключением comment или phrase.
  • Кодированный текст не должен продолжаться от одного encodedword к другому. Это предполагает, что секция кодированного текста будет иметь длину, кратную 4 символам; для Q-encoded-word, за любым символом "=", который появляется в секции кодированного текста, следуют две шестнадцатеричные цифры.

    Каждое encoded-word должно кодировать полное число октетов. Кодированный текст в каждом encoded-word должен быть хорошо оформлен согласно специфицированному кодированию.

    Каждое encoded-word должно представлять собой целое число символов. Многооктетные символы не могут расщепляться между смежными кодировочными словами.

    Поддержка кодировочных слов в программах чтения почты. Распознавание кодировочных слов в заголовках сообщений

    Программа чтения почты должна осуществлять разбор сообщения и заголовков секций согласно правилам RFC-822, чтобы правильно распознать кодировочные слова. При этом следует выполнять следующие правила.

  • Поле заголовка любого сообщения или части тела, определенное как '*text', или любое поле заголовка, определенное пользователем, должно разбираться следующим образом. Начало обозначается LWS (HR|SP|CRLF); любая последовательность, вплоть до 75 печатных символов (не содержащая LWS) должна рассматриваться как кандидат в кодировочные слова и проверяться на соблюдение правил синтаксиса, описанных выше. Любую другую последовательность печатных символов следует рассматривать как обычный ASCII-текст
  • Любое поле заголовка, не определенное как '*text', должно разбираться согласно синтаксическим правилам для данного поля заголовка. Однако любое слово, которое появляется в пределах фразы, должно обрабатываться как кодировочное слово, если оно отвечает синтаксическим правилам. В противном случае оно должно обрабатываться как обычное слово
  • Внутри комментария любая последовательность с длиной до 75 символов (не содержащая LWS), которая отвечает синтаксическим правилам, должна обрабатываться как кодировочное слово. В противном случае она должно обрабатываться как обычный текст комментария
  • Поле заголовка MIME-Version может отсутствовать в кодировочных словах, которые обрабатываются согласно данной спецификации. Причиной является то, что программа чтения почты не предполагает разбирать весь заголовок сообщения, прежде чем отображать строки, которые могут содержать кодировочные слова
  • Транспортное кодирование

    Транспортное кодирование представляет собой преобразование, применяемое к типам среды MIME после преобразования в каноническую форму. Транспортное кодирование используется в нескольких целях.

  • Многие виды транспорта, особенно пересылка сообщений, могут обрабатывать только данные, состоящие из относительно коротких строк текста. Существуют также строгие ограничения на то, какие символы могут использоваться в этих строках текста. Некоторые виды транспортировки допускают использование только субнабора US-ASCII, а другие не могут работать с некоторыми символьными последовательностями. Транспортное кодирование используется для того, чтобы преобразовать двоичные данные в текстовую форму. Примеры такого сорта транспортного кодирования включают применение base64 и закавыченных строк печатных символов, определенных в RFC-2045
  • Изображение, аудио, видео и даже объекты приложений имеют иногда довольно большой размер. Алгоритмы сжатия часто весьма эффективны для сокращения объектов большого размера. Транспортное кодирование может использоваться также для того, чтобы с помощью универсальных алгоритмов сжатия без потерь сократить размер MIME-объектов
  • Транспортное кодирование может быть определено как средства представления существующих форматов кодирования в контексте MIME.
  • Стандартизация большого числа видов транспортного кодирования представляется серьезным барьером для обеспечения совместной работы различных узлов. Несмотря ни на что, определена процедура для обеспечения средств определения дополнительных транспортных кодировок.

    Каноническая модель кодирования

    Процесс формирования объекта MIME можно смоделировать в виде цепочки последовательных шагов. Заметим, что эти шаги сходны с используемыми в PEM [RFC-1421] и они реализуются для каждого внутреннего уровня тела сообщения.

  • Создание локальной формы.

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

  • Преобразование в каноническую форму.

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

    Например, в случае чистого текста данные должны преобразовываться с использованием поддерживаемого символьного набора, а строки должны завершаться CRLF, как этого требует RFC-822. Заметьте, что ограничения на длины строк, налагаемые RFC-822, игнорируются, если на следующем шаге выполняется кодирование с использованием base64 или закавыченных строк печатных символов.

  • Применение транспортного кодирования.

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

  • Вставление в объект.

    Закодированное тело вкладывается в объект MIME, снабженный соответствующими заголовками. Объект затем вкладывается в объект более высокого уровня, если это требуется.

  • Преобразование из формата объекта в локальную форму представления производится в обратном порядке. Заметим, что реверсирование этих шагов может вызвать различный результат, так как не существует гарантии, что исходная и оконечная формы окажутся идентичными. Очень важно учесть, что эти шаги являются лишь моделью, а не руководством к тому, как на самом деле следует строить систему. В частности, модель не срабатывает в двух достаточно общих случаях.

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

    Content-type: text/foo; charset=bar
    Content-Transfer-Encoding: base64

    должно быть сначала представлено в форме text/foo, затем, если необходимо, представлено в символьном наборе и, наконец, трансформировано с использованием алгоритма base64 в формат, безопасный для пересылки через любые шлюзы.

    Некоторые проблемы вызывают почтовые системы, которые для обозначения перехода на новую строку используют нечто отличное от CRLF, принятого в стандарте RFC-822. Важно отметить, что эти форматы не являются каноническими RFC-822/MIME. Заметим также, что форматы, где вместо последовательности CRLF заносится, например, LF, не способны представлять сообщения MIME, содержащие двоичные данные с октетами LF, которые не являются частью последовательности CRLF.

    Вернуться к учебному плану