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

Протокол электронной почты

Разбить на страницы
Показывать лекцию целиком

Протокол электронной почты

Главной целью протокола SMTP (Simple Mail Transfer Protocol, RFC-821, -822) служит надежная и эффективная доставка электронных почтовых сообщений. SMTP является довольно независимой субсистемой и требует только надежного канала связи. Средой для SMTP может служить отдельная локальная сеть, система сетей или весь Интернет.

SMTP базируется на следующей модели коммуникаций: в ответ на запрос пользователя почтовая программа-отправитель устанавливает двухстороннюю связь с программой-приемником (TCP, порт 25). Получателем может быть оконечный или промежуточный адресат. SMTP -команды генерируются отправителем и посылаются получателю. На каждую команду должен быть отправлен и получен отклик.

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

tn dxmint.cern.ch 25 (команда telnet с использованием порта 25)
220 dxmint.cern.ch sendmail ready at sun, 9 jul 1995 11:13:57 +0200 
  (связь установлена, код отклика 220 является положительным)
EHLO dxmint.cern.ch (поддерживает ли сервер расширение mime?)
500 command unrecognized (не поддерживает)
HELO crnvma.cern.ch (команда выхода на конкретный сервер)
250 dxmint.cern.ch hello crnvma.cern.ch, pleased to meet you 
  (отклик 250 также является положительным)
mail from:<> (так как на моей PC нет резидентной почтовой программы, я
не указываю обратного адреса, по этой причине принимающая программа
может счесть данное сообщение SPAM'ом)
250 <>... sender ok (команда прошла успешно)
RCPT TO: ysemenov@cernvm.cern.ch (указываем адрес места назначения)
250 ... recipient ok
DATA (начало ввода текста сообщения)
nu-i-nu... (текст сообщения)
. (знак конца сообщения)
QUIT (прерывание или завершение процедуры)
221 dxmint.cern.ch closing connection 
   (сообщение об успешном завершении процедуры)

Почтовое сообщение отправлено без использования доступа к локальной почтовой программе. Следует отметить, что работа через порт 25 в данном случае открывает богатые возможности для хакеров. Вообще опытный программист может многого достичь, умело используя номера портов. Здесь есть над чем поработать людям, ответственным за безопасность сетей. Аналогично, не имея авторизации, можно выявить клиентов почтового сервера, используя команду VRFY (если она не блокирована административно):

tn ns.itep.ru 25
220 ns.itep.ru 5.67a8/ida-1.5 sendmail is ready at sat, 29 jul 1995 13:53:03
vrfy bobyshev
250 andrey bobyshev
и т.д.
quit

SMTP -отправитель и SMTP -получатель могут вести диалог с несколькими оконечными пользователями (рис 2.1). Любое почтовое сообщение завершается специальной последовательностью символов. Если получатель успешно завершил прием и обработку почтового сообщения, он посылает положительное подтверждение.

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

(рис 2.1) Схема взаимодействия различных частей почтовой системы

Для решения поставленной задачи SMTP -сервер должен знать имя конечного получателя и название почтового ящика места назначения. Аргументом команды MAIL является адрес отправителя (обратный адрес). Аргументом команды RCPT служит адрес конечного получателя. Обратный адрес используется для посылки сообщения в случае ошибки.

Все отклики имеют цифровые коды. Команды, отклики и имена ЭВМ не чувствительны к тому, строчные или прописные символы использованы при их написании, но это не всегда справедливо при написании имен и адресов получателя.

Почтовый протокол SMTP работает только с ASCII-символами. Если транспортный канал работает с октетами, 7-битные коды будут дополнены нулевым восьмым битом. Именно здесь коренилась проблема пересылки почтовых сообщений на русском языке (русский алфавит требует 8-битового представления). Проблема усугубляется тем, что для русского алфавита принято 4 кодовых представления, здесь мы впереди планеты всей…

Как уже было сказано, процедура отправки почтового сообщения начинается с посылки команды MAIL, которая имеет формат:

MAIL <SP> FROM:<reverse-path> <CRLF>,

где <SP> — пробел, <CRLF> — комбинация кодов возврата каретки и перехода на новую строку, а <reverse-path> — обратный путь (имя почтового ящика отправителя). Именно этот адрес используется, если получатель сообщения воспользуется командой reply.

Эта команда сообщает SMTP -получателю, что стартует новая процедура и следует сбросить в исходное состояние все статусные таблицы, буферы и т.д. Если команда прошла, получатель реагирует откликом: 250 OK.

Аргумент может содержать не только адрес почтового ящика — в общем случае он является списком адресов ЭВМ-серверов, через которые пришло данное сообщение, включая, разумеется, и адрес почтового ящика отправителя. Первым в списке <reverse-path> стоит адрес ЭВМ-отправителя. После прохождения команды MAIL посылается команда RCPT:

RCPT <SP> TO:<forward-path> <CRLF>

Эта команда указывает адрес конечного получателя ( <forward-path> ). При благополучном прохождении команды получатель посылает кодотклик 250 OK, и запоминает полученный адрес. Если получатель неизвестен, SMTP -сервер пошлет отклик 550 Failure reply. Команда RCPT может повторяться сколько угодно раз, если адресат не один.

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

DATA <CRLF>

При правильном приеме этого сообщения SMTP -сервер реагирует посылкой отклика 354 Intermediate reply (промежуточный отклик), и рассматривает все последующие строки в качестве почтового текста. При получении кода конца текста отправляется отклик: 250 OK.

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

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

1. 251 User not local; will forward to <forward-path>

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

2. 551 User not local; please try <forward-path>

Получатель знает правильный адрес и предлагает отправителю переадресовать сообщение по адресу <forward-path>.

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

Реакция на команду VRFY зависит от аргумента. Так если среди клиентов почтового сервера имеется два пользователя с именем Ivanov, откликом на команду "VRFY Ivanov" будет "553 User ambiguous". В общем случае команда VRFY Ivanov может получить в качестве откликов:

250 Vasja Ivanov Ivanov@cl.itep.ru
или:
251 User not local; will forward to Ivanov@cl.itep.ru
или:
550 String does not match anything (данная строка ничему не соответству-
ет).
или:
551 User not local; please try Vasja@ns.itep.ru
или:
VRFY Chtozachertovchina
553 User ambiguous (несуществующее имя)

В случае распечатки списка адресов отклик занимает несколько строк, например:

EXPN Example-People
250-Juri Semenov Semenov@ns.itep.ru
250-Alexey Sher Sher@suncom.itep.ru
250-Andrey Bobyshev Bobyshev@ns.itep.ru
250-Igor Gursky Gursky@ns.itep.ru

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

Основной задачей почты служит доставка сообщений в почтовый ящик адресата. Сходную форму услуги оказывают некоторые ЭВМ, доставляя сообщения на экран терминала (в рамках SMTP ). Для посылки сообщений на экран терминала адресата предусмотрено три команды:

1. SEND <SP> FROM:<reverse-path> <CRLF>

Команда SEND требует, чтобы почтовое сообщение было доставлено на терминал. Если терминал адресата не активен в данный момент, то откликом на команду RCPT будет код 450.

2. SOML <SP> FROM:<reverse-path> <CRLF>

Команда Send Or MaiL (SOML) пересылает сообщение на экран адресата, если он активен, в противном случае сообщение будет уложено в его почтовый ящик.

3. SAML <SP> FROM:<reverse-path> <CRLF>

Команда Send And MaiL (SAML) предполагает доставку сообщение на экран терминала адресата и занесение в его почтовый ящик. Для открытия и закрытия коммуникационного канала используются команды:

HELO <SP> <domain> <CRLF>, где <domain> — имя запрашивающего домена. 
QUIT <CRLF>

Выражение <forward-path> может быть маршрутом, имеющим вид "@ONE,@TWO:VANJA@THREE", где ONE, TWO и THREE — имена ЭВМ. Это подчеркивает различие между адресом и маршрутом. Концептуально элементы из <forward-path> переносятся в <reverse-path> при пересылке сообщений от одного SMTP -сервера к другому.

Если SMTP -сервер обнаружит, что доставка сообщения по адресу невозможна, тогда он формирует сообщение о "недоставленном письме", используя <reverse-path>. Следует также помнить, что и прямой, и обратный адреса-маршруты, вообще говоря, могут не иметь ничего общего с текстом заголовка почтового сообщения.

При определенных условиях и ошибках в задании прямых и обратных адресов-маршрутов возможно зацикливание сообщений об этих ошибках. Чтобы заведомо избежать этого, можно выдавать команду MAIL c нулевым обратным маршрутом:

MAIL FROM:< >

Если вы или ваша программа не указали обратного адреса, не следует думать, что это помешает работе почтовой программы и она не будет знать, куда посылать отклики. Практически все почтовые программы позволяют произвольно модифицировать поле <reverse-path>. Это может быть удобно, если вы собираетесь в командировку, но эта возможность широко используется и спамерами.

Поле <reverse-path> применяется почтовой программой, когда вы отвечаете на полученное сообщение с помощью утилиты Reply. Таким образом, ваш возмущенный ответ спамеру может прийти, например, к вам самому.

Следует помнить, что обратный IP-адрес (адрес отправителя) указан в каждом пакете, посылаемом адресату!

Некоторые другие команды, используемые в SMTP

Команда TURN нужна для того, чтобы поменять местами функции программ, взаимодействовавших по телекоммуникационному каналу. Программа-отправитель становится получателем (после того как она выдаст команду TURN и получит отклик 250 ), а программа-получатель — отправителем. Если программа не хочет или не может поменять свою функцию, она пошлет отклик 502. Эта команда позволяет организовать диалог между отправителем и получателем в реальном масштабе времени.

Команда RESET (RSET) прерывает текущую процедуру отправки почтового сообщения. Все буферы и таблицы очищаются, получатель должен послать отклик 250 OK.

Команда HELP вынуждает получателя послать справочную информацию отправителю команды HELP. Команда может содержать аргумент (имя команды). Она не изменяет состояния таблиц или буферов.

Команда NOOP не оказывает влияния на какие-либо параметры или результаты предшествующих команд, она только вынуждает получателя послать отклик 250 OK. Может использоваться для проверки работоспособности TCP-канала.

Допустимо написание команд строчными или прописными символами, например: MAIL, Mail, mail, MAil или mAil.

Для того, чтобы программа SMTP -сервера была работоспособна, она должна понимать следующий минимум команд: HELO, MAIL, RCPT, DATA, RSET, NOOP, QUIT.

Предельная длина имени пользователя или домена равна 64 символам. Максимальная длина <reverse-path> или <forward-path> составляет 256 символов, включая разделители (пробелы, точки, запятые и пр.). Командная строка не должна быть длиннее 512 символов. Максимальный размер строки отклика не должен превышать 512 символов, включая его код и <CRLF>. Максимальная длина строки составляет, включая <CRLF>, 1000 символов. Предельно допустимое число адресатов равно 100, последнее полезно помнить, если вы храните этот список в файле.

Многоцелевое расширение почты Интернет (MIME)

Стандарт STD 11 (RFC 822) определяет протокол представления сообщений, структуру их заголовков. При этом предполагается, что текст сообщения построен исключительно из кодов US-ASCII (смотри также http://book.itep.ru/4/4/mime.htm). Набор документов MIME (Multipurpose Internet Mail Extensions; RFC-2045-49) задает формат сообщений, который предоставляет следующие возможности.

  • Передача текстовых сообщений с символьным набором, отличным от US-ASCII.
  • Передача сообщений нетекстового формата (например, звукового письма или изображения).
  • Использование комбинированных сообщений, содержащих разнородные части.
  • Размещение в заголовке информации в символьном наборе, отличном от US-ASCII.
  • Документ RFC-2045 характеризует различные заголовки, которые служат для описания структуры MIME-сообщений. RFC 2046 определяет общую структуру MIME и исходный набор типов среды. RFC 2047 описывает расширения документа RFC 822, позволяя применение в полях заголовков символьных наборов, отличных US-ASCII. RFC 2048 специфицирует различные ограничения, вводимые IANA, для процедур, сопряженных с MIME. RFC 2049 характеризует критерии соответствия требованиям MIME, содержит примеры допустимых форматов и библиографию. Новейшие усовершенствования протокола MIME (особенно в направлении безопасности) можно найти в документах: RFC-2045-49, -2110, -2156, -2184, -2231, -2387, -2425, -2480, -2557, -2634, -2912-13, -3030, -3156, -3204, -3250, -3302, -3335, -3454, -3555, -3735, -3802 -03, -3839, -3850-51, -3850-35, -4021.

    Документ RFC 822, который прослужил без малого 20 лет, регламентировал работу лишь с текстовыми сообщениями (передача аудио-, видео- или графических сообщений в нем не была предусмотрена). Но даже в случае чисто текстовых документов возникали проблемы при работе с языковыми наборами, требующими символов, которые отсутствуют в наборе US-ASCII.

    Одним из существенных ограничений традиционной электронной почты, базирующейся на RFC 821-822, является установка предельного размера строки (1000 7-битовых US-ASCII символов). Это вынуждало пользователей конвертировать текст различными методами в последовательность US-ASCII-кодов (например, процедура uuencode или преобразование в коды Base-64).

    Существенные проблемы возникали при почтовом обмене между узлами, поддерживающими протоколы RFC 822 и X.400. Протокол X.400 [X400] определяет механизм включения нетекстовых материалов в почтовые сообщения. Существующие протоколы согласования работы X.400 и RFC 822 предполагают, что X.400 осуществляет преобразование нетекстовых вставок в формат IA5Text или такие сообщения просто выбрасываются. Отправитель сообщения часто не знает о возможностях получателя, и в результате последний, получив сообщения, попросту не сможет его прочесть. Таким образом, нужен механизм согласования возможностей отправителя и получателя на начальной стадии их взаимодействия до начала передачи тела сообщения. В протоколе MIME регламентируется:

  • поле заголовка MIME-Version, которое характеризует версию протокола и позволяет почтовым агентам согласовать свои возможности и исключить конфликты с устаревшим программным обеспечением;
  • поле заголовка Content-Type, которое используется для спецификации типа среды и субтипа данных в теле сообщения, а также для описания канонической формы этих данных;
  • поле заголовка Content-Transfer-Encoding, которое может использоваться для задания типа преобразования;
  • два дополнительные поля заголовка, предусмотренные для уточнения описания данных в теле сообщения (Content-ID и Content-Description).
  • Важно заметить, что основополагающими принципами при создании MIME были совместимость с существующими стандартами и надежность работы. Для тех, кто попытается реализовать протокол MIME, определенный интерес могут представлять документы RFC 1344, RFC 1345 и RFC 1524.

    Далее все цифровые величины и октеты приводятся в десятичном представлении. Все значения типа среды, субтипы и имена параметров безразличны к регистру их написания. Значения параметров, напротив, зависимы от того, строчными или прописными буквами они записаны.

    Терм CRLF в данном описании относится к последовательности октетов, соответствующих ASCII-символам CR (десятичный код 13) и LF (десятичный код 10), которые обозначают разрыв строки.

    Выражение "символьный набор" используется в MIME для того, чтобы обозначить метод преобразования последовательности октетов в последовательность символов. Заметим, что безусловное и однозначное преобразование в обратном направлении не требуется, то есть не все символы могут быть представлены через данный символьный набор (более чем одна последовательность октетов может соответствовать одной и той же последовательности символов).

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

    Термин "символьный набор" был первоначально введен для описания прямых схем преобразования, таких, как ASCII и ISO-8859-1, для которых характерна однозначная связь символов и кодовых октетов. Многооктетные кодированные символьные наборы и методики переключения несколько осложнили ситуацию.

    Термин "сообщение" обозначает сообщение типа RFC 822, передаваемое по сети, либо сообщение, инкапсулированное в тело типа "message/rfc822" или "message/partial".

    Термин "объект" (entity) относится к полям заголовка MIME и содержимому сообщения или его части в случае, если оно составное. Спецификация таких объектов определяется исключительно MIME. Так как содержимое объекта часто называется "тело", имеет смысл говорить о теле объекта. Любой вид поля может быть представлен в заголовке объекта, но только поля, имена которых начинаются с "content-", имеют значение, связанное с протоколом MIME.

    Выражение "7-битовые данные" относится к данным, которые образуют относительно короткие строки с длиной менее 998 октетов, завершающиеся последовательностью CRLF [RFC-821]. Октеты с кодом больше чем 127 или равные нулю недопустимы. Октеты CR (десятичный код 13) и LF (десятичный код 10) могут встречаться только в виде последовательности, отмечающей конец строки.

    Выражение "8-битовые данные" относится к данным, которые образуют относительно короткие строки с длиной менее 998 октетов, завершающиеся последовательностью CRLF [RFC-821]. Но здесь разрешены октеты с десятичными значениями кодов, превышающими 127 (нулевые коды не допускаются).

    Строки в данном контексте представляют собой последовательности октетов, завершающиеся CRLF. Это согласуется с документами RFC 821 и RFC 822.

    MIME определяет ряд новых полей заголовков по сравнению с RFC 822. Они описывают содержимое MIME-объекта. Эти поля заголовков используются в двух контекстах:

  • в качестве части стандартного заголовка RFC 822;
  • в MIME-заголовке в рамках составной конструкции сообщения.
  • Ниже представлено формальное описание этих полей заголовка.

    entity-headers := [ content CRLF ] [ encoding CRLF ] [ id CRLF ] [ description CRLF ]
    *( MIME-extension-field CRLF )
    MIME-message-headers := entity-headers fields version CRLF

    Порядок полей заголовка, представленный в данном BNF-определении, не имеет никакого значения.

    MIME-part-headers := entity-headers [ fields ]

    Любое поле, не начинающееся с "content-", не может иметь какого-либо значения и может игнорироваться.

    Порядок полей заголовка, представленный в данном BNF-определении, не имеет никакого значения.

    Так как документ RFC 822 был опубликован в 1982 году, там имелся только один формат для сообщений, передаваемых по каналам Интернет, и по этой причине не было необходимости декларировать тип такого стандарта. MIME является независимым дополнением документа RFC 822. Хотя протокол MIME строился так, чтобы обеспечить совместимость с RFC 822, бывают обстоятельства, когда почтовому агенту желательно выяснить, составлено ли сообщение с учетом нового стандарта. Поле заголовка "MIME-Version" служит как раз для того, чтобы можно было определить, какому стандарту соответствует тело сообщения. Сообщения, соответствующие MIME обязаны содержать такое поле заголовка со следующим текстом:

    MIME-Version: 1.0

    Присутствие этого поля заголовка означает, что сообщение подготовлено согласно требованиям MIME. Так как существует возможность того, что в будущем формат документов может быть изменен, формальное BNF-представление поля MIME-Version следует записать следующим образом:

    version := "MIME-Version" ":" 1*DIGIT "." 1*DIGIT

    Таким образом, будущие спецификаторы формата, которые могут заменить версию 1.0, ограничены двумя цифровыми полями, разделенными точкой. Если сообщение получено со значением поля MIME-version, отличным от "1.0", оно может не соответствовать данному описанию.

    Заметим, что поле заголовка MIME-Version должно располагаться в самом начале сообщения. При составном сообщении не требуется, чтобы каждая из частей начиналась с поля версии. Это необходимо лишь в случае, когда заголовки встроенных сообщений типа "message/rfc822" или "message/partial" объявляют о совместимости со стандартом MIME.

    Для некоторых приложений согласование версий должно проводиться независимо. Некоторые форматы (такие, как application/postscript) имеют внутреннюю систему нумерации версий для каждого типа среды. Там, где выполняется такое соглашение, MIME не предпринимает попыток подменить эту систему. Там, где такого соглашения нет, тип среды MIME может использовать параметр version в поле типа содержимого. При проверке значений MIME-Version любые строки комментария RFC 822 должны игнорироваться. В частности, следующие четыре записи поля

    MIME-Version эквивалентны.
    MIME-Version: 1.0
    MIME-Version: 1.0 (produced by MetaSend Vx.x)
    MIME-Version: (produced by MetaSend Vx.x) 1.0
    MIME-Version: 1.(produced by MetaSend Vx.x)0

    В отсутствии поля MIME-Version, принимающий почтовый агент (следующий стандарту MIME или нет) может опционно интерпретировать сообщения согласно локальным соглашениям.

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

    Поле заголовка Content-Type

    Задачей поля Content-Type является описание информации, содержащейся в теле сообщения. Этого описания должно быть достаточно, чтобы принимающий агент пользователя был способен воспринять и отобразить полученные данные. Значение этого поля называется типом среды.

    Введение поля тип среды (Content-Type) решило не только проблемы почты, оно открыло возможности мультимедийного отображения в HTTP и других приложениях.

    Поле заголовка Content-Type было первым определенным в документе RFC-1049. В RFC-1049 использовался более простой и менее мощный синтаксис, который, впрочем, вполне согласуется с регламентациями MIME.

    Поле заголовка Content-Type специфицирует природу данных в теле объекта, сообщая тип среды и идентификаторы субтипа, а также предоставляя вспомогательную информацию, которая может требоваться для определенного типа среды. После типа среды и имен субтипов может следовать набор параметров, который описывается в нотации атрибут = значение. Порядок параметров не имеет значения. Тип среды верхнего уровня используется для декларирования общего типа данных, в то время как субтип определяет специфический формат информации. Таким образом, типа среды image/xyz достаточно, чтобы сообщить агенту пользователя, что данные представляют собой изображение, даже если агент пользователя не имеет представления о формате изображения xyz. Такая информация может применяться, например, для того, чтобы решить, следует ли показывать пользователю исходные данные нераспознанного субтипа. Такая операция разумна для нераспознанного субтипа текста, но бессмысленна для изображения или звука. По этой причине зарегистрированные субтипы текста, изображения, аудио и видео не должны содержать вложенной информации другого типа. Такой составной формат должен быть представлен с использованием multipart или application типов.

    Параметры являются модификаторами субтипа среды и по этой причине не могут существенно влиять на природу содержимого. Набор значимых параметров зависит от типа и субтипа среды. Большинство параметров связано с одним специфическим субтипом. Однако тип среды верхнего уровня может определить параметры, которые применимы к любому субтипу данного типа. Параметры могут быть необходимы для определенных типов и субтипов, могут они быть и опционными. Реализации MIME должны игнорировать любые параметры, если их имена не распознаны.

    Например, параметр charset применим к любому субтипу текста, в то время как параметр boundary необходим для любого субтипа типа среды multipart. Не существует параметров, применимых для всех типов среды.

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

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

    В нотации BNF значение поля заголовка Content-Type определяется следующим образом:

    content := "Content-Type" ":" type "/" subtype *(";" parameter) Распознавание типа и субтипа среды всегда не зависит от регистра, в котором они напечатаны.
    type := discrete-type / composite-type
    discrete-type := "text" / "image" / "audio" / "video" / "application" / extension-token
    composite-type := "message" / "multipart" / extension-token
    extension-token := ietf-token / x-token
    ietf-token := <Лексема расширения, определенная стандартом RFC и зарегистрированная IANA.>
    x-token := <Два символа "X-" или "x-", за которыми следует без пробела лексема (token)>
    subtype := extension-token / iana-token
    iana-token := <Общедоступная лексема расширения. Лексемы этой формы должны быть зарегистрированы IANA, как это указано в RFC 2048.>
    parameter := attribute "=" value
    attribute := token Распознавание атрибутов не зависит от регистра, в котором они напечатаны.
    value := token / quoted-string
    token := 1*
    tspecials := "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / "\" / <"> "/" / "[" / "]" / "?" / "="

    Заметим, что определение tspecials совпадает с определением specials в RFC 822 с добавлением трех символов "/", "?" и "=" и удалением "." (точка).

    Заметим также, что спецификация субтипа является обязательной (MANDATORY) — она не может быть удалена из поля заголовка Content-Type. Не существует субтипов по умолчанию. Тип, субтип и имена параметров не зависят от регистра, в которых они напечатаны. Например, TEXT, Text и TeXt являются эквивалентными типами среды верхнего уровня. Значения же параметров в норме чувствительны к регистру, в котором они напечатаны, но иногда интерпретируются без учета регистра — в зависимости от приложения. (Например, границы типа multipart являются чувствительными к регистру, а параметр access-type для сообщения message/External-body не чувствителен).

    Обратите внимание, что значение строки в кавычках не включает в себя сами кавычки. В полях заголовка в соответствии с RFC 822 допускаются комментарии. Таким образом, две приведенные ниже формы являются эквивалентными.

    Content-type: text/plain; charset=us-ascii (Plain text)
    Content-type: text/plain; charset="us-ascii".

    Предполагается, что имена субтипов при их применении не вызовут конфликтов. Так, недопустимо, чтобы в различных приложениях "Content-Type: application/foobar" означало различные вещи. Существует два приемлемых механизма определения новых субтипов среды.

  • Частные значения (начинающиеся с X-) могут быть определены для двух взаимодействующих агентов без официальной регистрации или стандартизации.
  • Новые стандартные значения должны регистрироваться IANA, как это описано в RFC 2048.
  • Сообщения по умолчанию без MIME-заголовка Content-Type, согласно протоколу, должны содержать простой текст с символьным набором ASCII, который может быть специфицирован явно.

    Content-type: text/plain; charset=us-ascii

    Это значение подразумевается, если не специфицировано поле заголовка Content-Type. Рекомендуется, чтобы это значение по умолчанию использовалось в случае, когда встретилась нераспознанное значение поля заголовка Content-Type. В присутствии поля заголовка MIME-Version и отсутствии поля Content-Type, принимающий агент пользователя может также предположить, что отправитель предлагает простой текст в ASCII-кодировке. Простой ASCII-текст может предполагаться в отсутствии MIME-Version или в присутствии синтаксически некорректного поля заголовка Content-Type, хотя это может и не совпадать с намерениями отправителя.

    Многие типы среды, которые могут передаваться посредством электронной почты, представляются в своем естественном формате, таком, как 8-битовые символы или двоичные данные. Такие данные не могут быть переданы посредством некоторых транспортных протоколов. Например, RFC 821 ( SMTP ) ограничивает почтовые сообщения 7-битовым символьным набором ASCII со строками, короче 1000 символов, включая строчные разделители CRLF.

    Таким образом, необходимо определить стандартный механизм кодировки таких данных в 7-битный формат с короткими строками. В MIME для этой цели используется поле заголовка "Content-Transfer-Encoding".

    Значения полей Content-Transfer-Encoding представляют собой лексему, характеризующую тип кодирования, как это описано ниже.

    Encoding := "Content-Transfer-Encoding" ":" mechanism
    mechanism := "7bit" / "8bit" / "binary" / "quoted-printable" / " base64 " / ietf-token / x-token

    Эти значения не чувствительны к регистру, в котором напечатаны. Записи Base64, BASE64 и bAsE64 эквивалентны. Тип кодировки 7BIT требует, чтобы тело уже имело 7-битовое представление, пригодное для передачи. Это значение по умолчанию означает, что в отсутствии поля Transfer-Encoding предполагается "Content-Transfer-Encoding: 7BIT".

    Лексема Content-Transfer-Encoding предоставляет два вида информации. Она специфицирует, какому виду кодового преобразования подвергнуто тело сообщения и, следовательно, какая процедура декодирования должна использоваться при восстановлении исходного вида сообщения.

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

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

    Значения Content-Transfer-Encoding 7bit, 8bit и binary означают, что никакого преобразования не произведено. Они указывают на тип тела сообщения, и позволяют предполагать, какое кодирование может потребоваться при передаче данных.

    Кодирование в последовательность печатных символов или в кодовую последовательность base64 предполагает преобразование из произвольного исходного формата в представление 7bit, что позволяет передачу через любые транспортные среды.

    Всегда должна использоваться корректная метка Content-Transfer-Encoding. Пометка данных, преобразованных программой UUENCODE и содержащих 8-битовые символы, как 7bit не допустима — такие данные должны помечаться только как binary.

    При прочих равных условиях предпочтительным представлением является последовательность печатных символов или кодов base64.

    Передача почтовых сообщений, закодированных программой uuencode, описана в документе RFC 1652. Но следует иметь в виду, что ни при каких обстоятельствах Content-Transfer-Encoding binary нельзя считать приемлемым для e-mail. Однако когда используется MIME, двоичное тело сообщения может быть помечено как таковое.

    Программисты могут, если необходимо, определить частные значения Content-Transfer-Encoding. При этом должны использоваться x-лексемы, которые представляют собой имена с префиксом X-, что указывает на нестандартный статус, например, "Content-Transfer-Encoding: x-my-newencoding". Дополнительные стандартизованные значения Content-Transfer-Encoding должны быть специфицированы в официальных документах RFC.

    В отличие от типов среды и субтипов, формирование новых значений Content-Transfer-Encoding категорически не рекомендуется, так как может привести к полному выходу из строя системы.

    Если поле заголовка Content-Transfer-Encoding появляется как часть заголовка сообщения, оно относится ко всему телу сообщения. Если поле заголовка Content-Transfer-Encoding появляется в качестве части заголовка объекта, то зоной его действия будет тело этого объекта. Если объект имеет тип multipart, то Content-Transfer-Encoding не может иметь значение 7bit, 8bit или binary. Следует заметить, что большинство типов среды определены в терминах октетов, а не бит, поэтому описываемые механизмы относятся к кодировке произвольных потоков октетов, а не бит. Если необходимо закодировать битовую последовательность, она должна быть преобразована в последовательность октетов с сетевой последовательностью бит (big-endian), в которой более ранние биты становятся старшими битами октетов. Битовые потоки, длина которых не кратна 8, должны быть дополнены нулями.

    Механизмы кодировки, определенные здесь, осуществляют преобразование любых данных в ASCII. Таким образом, предположим, например, что объект имеет следующие поля заголовка:

    Content-Type: text/plain; charset=ISO-8859-1
    Content-transfer-encoding: base64

    Это должно интерпретироваться так, что тело имеет кодировку base64, а исходные данные имели представление в ISO-8859-1.

    Определенные значения Content-Transfer-Encoding могут использоваться только с определенными типами среды. В частности, категорически запрещено применять любую кодировку отличную от 7bit, 8bit или binary с любым составным типом среды, т.e. включающим и другие поля Content-Type. В настоящее время разрешены составные типы среды multipart и message. Все кодировки, допустимые для тел типа multipart или message должны использоваться на самом внутреннем уровне.

    Следует также заметить, что по определению, если составной объект имеет значение transfer-encoding равное 7bit, но один из составляющих объектов имеет менее регламентирующее значение, например, 8bit, тогда либо внешняя метка 7bit является ошибкой, либо внутренняя метка 8bit устанавливает слишком высокое требование к транспортной системе (следовало проставить 7bit).

    Хотя запрет использования content-transfer-encodings для составного тела может показаться чрезмерно регламентирующим, следует избегать вложенных кодирований, в которых данные подвергаются последовательно обработке несколькими алгоритмами. Вложенные кодирования заметно повышают сложность агентов пользователя. Помимо очевидных проблем эффективности при множественном кодировании, они могут затемнить базовую структуру сообщения. В частности, они могут подразумевать, что необходимо несколько операций декодирования, чтобы определить, какие типы тел содержит сообщение. Запрет вложенных кодировок может осложнить работу некоторых почтовых шлюзов, но это представляется меньшей бедой, чем осложнение жизни агентов пользователя при вложенном кодировании.

    Любой объект с нераспознанным значением Content-Transfer-Encoding должен рассматриваться, как если бы он имел код Content-type "application/octet-stream", вне зависимости от того, что утверждается полем заголовка Content-Type.

    Может показаться, что Content-Transfer-Encoding может быть выяснено из характеристик среды, для которой нужно осуществить кодирование, или, по крайней мере, что определенное Content-Transfer-Encodings может быть предназначено для использования с определенными типами среды. Есть несколько причин, почему это не так. Во-первых, существуют различные типы транспорта, используемые для почты, некоторые кодирования могут подходить для определенных комбинаций типов среды и транспорта, но быть непригодными для других. Например, при 8-битовой передаче, при определенном символьном наборе для текста не потребуется никакого кодирования, в то время как такое кодирование очевидно необходимо для 7-битового SMTP.

    Во-вторых, определенные типы среды могут требовать различного транспортного кодирования при разных обстоятельствах. Например, многие PostScript-тела могут целиком состоять из коротких строк 7-битовых кодов и, следовательно, совсем не требуют кодирования. Другие тела PostScript (в особенности те, что используют механизм двоичного кодирования уровня 2 PostScript) могут быть представлены с использованием двоичного транспортного кодирования. Наконец, так как поле Content-Type ориентировано на то, чтобы предоставлять открытые механизмы спецификации, строгие ассоциации типов среды и кодирования эффективно соединяют спецификацию прикладного протокола с определенным транспортом нижнего уровня. Это нежелательно, так как разработчики типа среды не должны заботиться обо всех видах транспорта и их особенностях.

    Кодирование с использованием закавыченных строк печатных символов и кодов base64 устроено так, чтобы позволить взаимные преобразования. Единственная проблема, которая здесь возникает, — это обработка принудительных разрывов строк для закавыченных последовательностей печатных символов. При преобразовании закавыченных строк в коды base64 принудительные разрывы строк отображаются последовательностями CRLF. Аналогично, последовательность CRLF в канонической форме данных, полученной после декодирования из base64, должна преобразоваться в принудительный разрыв строки в случае представления текста в виде закавыченной строки печатных символов. Каноническая модель кодирования представлена в документе RFC 2049.

    Кодирование Quoted-Printable имеет целью представление данных, состоящих по большей части из октетов, которые соответствуют печатным символам ASCII-набора. Оно преобразует данные таким образом, что результирующие октеты не будут видоизменены при транспортировке почты. Если преобразуемые данные представляют собой ASCII-текст, то после кодирования они сохранят читабельность. Тело, которое целиком состоит из ASCII-кодов, может быть также представлено в виде закавыченной строки печатных символов. При этом сохраняется целостность текста в процессе прохождении через шлюз, который осуществляет трансляцию символов и/или обработку разрывов строк. При таком кодировании октеты должны определяться согласно изложенным ниже правилам.

  • 8-битовое представление. Любой октет (за исключением CR или LF, которые являются частью последовательности разрыва строки CRLF) канонического (стандартного) формата данных может быть представлен с помощью символа "=", за которым следуют две шестнадцатеричные цифры, характеризующие значение октета. Для этих целей используются цифры шестнадцатеричного алфавита "0123456789ABCDEF". Должны применяться прописные буквы; использование строчных букв недопустимо. Так, например, десятичное значение 12 (ASCII FF) может быть представлено как "=0C", а десятичное значение 61 (ASCII символ знака равенства) представляется с помощью "=3D". Это правило должно выполняться всегда за исключением случаев, когда правила допускают альтернативное кодирование
  • Литеральное представление. Октеты с десятичными кодами в интервале 33 - 60 включительно и 62 - 126, включительно могут представляться ASCII-символами, которые соответствуют этим октетам (с "!" до "<" и с ">" до "~" соответственно)
  • Пробелы. Октеты со значениями кодов 9 и 32 могут отображаться с помощью ASCII-символов TAB (HT) и пробел, соответственно, но не должны использоваться в конце строки. За любым символом TAB (HT) или пробел в кодируемой строке должен следовать печатный символ. В частности, символ "=" в конце каждой кодируемой строки, обозначающий "мягкий" разрыв строки (смотри правило #5), может следовать за одним или более символами TAB(HT) или SP. Отсюда следует, что октет, равный 9 или 32, появляющийся в конце кодируемой строки должен быть представлен в форме, указанной правилом #1. Это правило необходимо, так как некоторые MTA (Message Transport Agents, программы, которые передают сообщения от одного пользователя другому) дополняют строки пробелами, а другие удаляют пробелы ( HT или SP ) в конце строки. Следовательно, при декодировании тела, представленного в форме закавыченных печатных последовательностей, любые HT или SP должны быть удалены
  • Разрывы строк. Разрыв строки в теле текста, представленный последовательностью CRLF в канонической форме, для закавыченной печатной строки отмечается CRLF. Последовательности типа "=0D", "=0A", "=0A=0D" и "=0D=0A" появляются в нетекстовых данных, представленных в виде закавыченных строк печатных символов. Заметим, что многие реализации могут выбрать для кодирования непосредственно локальное представление различных типов содержимого, а не преобразование в каноническую форму, кодирование и только затем преобразование в локальное представление. В частности, такая техника может быть применена к простому тексту в системах, которые используют для межстрочных разрывов последовательности, отличные от CRLF. Такая оптимизация конкретной программной реализации вполне допустима, но только когда комбинированный шаг канонизация-кодирование эквивалентен выполнению всех трех шагов отдельно
  • Мягкие разрывы строки. Кодирование с помощью закавыченных строк печатных символов требует, чтобы строки содержали не более 76 символов. Если нужно закодировать более длинные строки, вводятся мягкие разрывы строк. Символ равенства в конце строки как раз и обозначает такой разрыв
  • Пусть имеется следующий текст, который надо преобразовать:

    Now’s the time for all folk to come to the aid of their country.

    Он может быть представлен следующим образом с помощью закавыченных строк печатных символов:

    Now’s the time =
    for all folk to come=
    to the aid of their country.

    Это предоставляет механизм, с помощью которого длинные строки преобразуются таким образом, как они должны быть запомнены агентом пользователя. Ограничение в 76 символов не учитывает завершающие строку CRLF, но содержит все прочие символы, включая знаки равенства. Так как символ дефис ("-") может отображаться в закавыченных строках самим собой, нужно следить за тем, чтобы при инкапсуляции закодированного фрагмента в одном или более составных объектов пограничные разделители не появились в закодированном теле. Хорошей стратегией является выбор в качестве границы последовательности символов "=_", которая не может встретиться в закавыченной строке печатных символов.

    Преобразование в закавыченные строки печатных символов представляет собой компромисс между читабельностью и надежностью при транспортировке. Тела, закодированные с помощью закавыченных строк печатных символов, пропускаются без проблем большинством почтовых шлюзов. Проблемы могут возникать только со шлюзами, осуществляющими трансляцию в коды EBCDIC. Кодирование с помощью base64 обеспечивает более высокий уровень надежности. Методом получения разумно высокой надежности транспортировки через шлюзы EBCDIC является представление символов !"#$@[\]^'{|}~ согласно правилу #1.

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

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

  • Символ "=", за которым следует две шестнадцатеричные цифры, одна или обе из которых являются строчными символами (abcdef), является нелегальным. Надежные реализации могут распознавать их как прописные буквы
  • Символ "=", за которым следует символ, не являющийся ни шестнадцатеричной цифрой (включая abcdef), ни CR из комбинации CRLF, является нелегальным. Это не может стать частью ASCII-текста, включенного в сообщение, без преобразования в закавыченную последовательность печатных кодов. Разумным решением для надежной реализации может быть: включить символ "=" и следующие за ним коды в декодированную последовательность без какого-либо преобразования и, если возможно, дать сигнал агенту пользователя, что декодирование в этом месте оказалось невозможным
  • Символ "=" не может быть последним или предпоследним символом в кодируемом объекте. Решением проблемы можно считать способ, предложенный в пункте (2)
  • Управляющие символы, отличные от TAB или CR и LF (в качестве части CRLF), не должны присутствовать. То же справедливо для октетов с десятичными значениями больше, чем 126. Если такие коды обнаруживаются в приходящих закавыченных последовательностях печатных символов, корректная реализация может исключить их из декодированных данных и предупредить пользователя о том, что обнаружен нелегальный символ
  • Закодированные строки не должны быть длиннее 76 символов, не считая завершающие CRLF. Если во входном потоке обнаружены более длинные строки, надежная реализация может их декодировать, но должна предупредить пользователя об ошибке
  • Если двоичные данные закодированы в виде закавыченных последовательностей печатных символов, следует позаботиться о том, чтобы символы CR и LF были представлены в виде "=0D" и "=0A", соответственно. В частности, последовательность CRLF в двоичных данных должна кодироваться как "=0D=0A". В противном случае, если CRLF была бы представлена как жесткий разрыв строки, она может декодироваться некорректно на платформах с различными способами обработки разрывов строки. С формальной точки зрения, закавыченные последовательности печатных символов подчиняются следующей грамматике.

    quoted-printable := qp-line *(CRLF qp-line)
    qp-line := *(qp-segment transportpadding CRLF) qp-part transport-padding
    qp-part := qp-section ; Максимальна длина 76 символов
    qp-segment := qp-section *(SPACE / TAB) "=" ; Максимальна длина 76 символов
    qp-section := [*(ptext / SPACE / TAB) ptext]
    ptext := hex-octet / safe-char
    safe-char := <любой октет с десятичным кодом от 33 до 60 включительно, и от 62 до 126> ; Символы, не включенные в список "mail-safe" RFC 2049, не рекомендуются к применению
    hex-octet := "=" 2(DIGIT / "A" / "B" / "C" / "D" / "E" / "F") ; Октет должен использоваться для символов с кодами > 127, =, SP или TAB в конце строк, и рекомендуется для любого символа не указанного в списке "mailsafe" документа RFC 2049
    transport-padding := *LWSP-char ; Составители не должны генерировать заполнители ненулевой длины, но получатели должны быть способны обрабатывать заполнители, добавленные при транспортировке

    Добавление LWSP между элементами, показанное в данном BNF-представлении, не допустимо, так как данное BNF не специфицирует структурированных полей заголовка.

    Транспортное кодирование на основе Base64 создано для представления произвольной последовательности октетов в форме, которая не обязательно должна быть приемлемой для прочтения человеком. Алгоритмы кодирования и декодирования просты. Это кодирование сходно с тем, что используется в почтовом приложении PEM (Privacy Enhanced Mail), как это определено в RFC-1421.

    Здесь используется 65-символьный субнабор ASCII, для каждого печатного символа выделено по 6 бит. Дополнительный 65-ый символ "=", используется для обозначения специальных функций обработки.

    Этот субнабор имеет важное свойство, которое заключается в том, что он представляется идентично во всех версиях ISO 646, включая US-ASCII, и все символы субнабора имеют аналоги во всех версиях EBCDIC. Другие популярные кодировки, такие, как применяемые утилитой uuencode, Macintosh binhex 4.0 [RFC-1741] и base85, специфицированная как часть уровня 2 PostScript, имеют отличающиеся свойства и, следовательно, не выполняют условий переносимости, которым должно удовлетворять двоичное транспортное кодирование электронной почты.

    При кодировании входные 24-битовые группы преобразуются в 4 символа. Входная группа формируется из трех 8-битовых кодов и обрабатывается слева направо. Эти 24 бита рассматриваются в дальнейшем как 4 6-битовые группы, каждая из которых транслируется в одно число из алфавита base64. Когда кодируется битовый поток с использованием base64, предполагается, что старший бит передается первым. То есть, первый бит потока станет старшим битом первого 8-битового байта, а 8-ой бит станет его последним битом.

    Каждая 6-битовая группа используется как индекс массива из 64 печатных символов. Символ, на который указывает индекс, берется из массива и помещается в выходной поток. Эти символы представлены в таблице 1.10, из их перечня исключены коды, имеющие особое значение для протокола SMTP (например, ".", CR, LF), а также разграничитель секций составного сообщения "-" (RFC-2046).

    Коды Base64
    Код символа (6 бит) ASCII символ Код символа (6 бит) ASCII символ Код символа (6 бит) ASCII символ Код символа (6 бит) ASCII символ
    0 A 10 Q 20 g 30 W
    1 B 11 R 21 h 31 X
    2 C 12 S 22 i 32 Y
    3 D 13 T 23 j 33 Z
    4 E 14 U 24 k 34 0
    5 F 15 V 25 l 35 1
    6 G 16 W 26 m 36 2
    7 H 17 X 27 n 37 3
    8 I 18 Y 28 o 38 4
    9 J 19 Z 29 p 39 5
    A K 1A a 2A q 3A 6
    B L 1B b 2B r 3B 7
    C M 1C c 2C s 3C 8
    D N 1D d 2D t 3D 9
    E O 1E e 2E u 3E +
    F P 1F f 2F v 3F /

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

    Если число бит в группе меньше 24, используется специальная обработка. Неполная битовая группа дополняется нулями справа до 24. Заполнение в конце информационной группы осуществляется с использованием символа "=". Так как последовательность кодов base64 представляет собой поток октетов, возможны следующие случаи:

  • последний блок кодируемых данных кратен 24 битам; здесь, завершающий выходной блок будет содержать в себе 4 символа и никакого заполнителя;
  • завершающий блок кодируемых данных содержит ровно 8 бит; здесь, оконечный выходной блок будет содержать два символа, за которыми будут следовать два символа заполнителя; или
  • последний блок кодируемой информации содержит ровно 16 бит; здесь, оконечный блок на выходе будет иметь три символа плюс один символ заполнителя "=".
  • Так как "=" используется для дополнения, его наличие указывает на то, что мы достигли конца массива данных. Такая уверенность невозможна, когда число переданных октетов кратно трем и нет ни одного символа "=". Любые символы, не входящие в алфавит base64, должны игнорироваться.

    Следует позаботиться о том, чтобы использовались корректные октеты в качестве разделителей строк при работе с base64. В частности, разрывы строк должны быть преобразованы в последовательности CRLF до выполнения кодирования base64.

    При создании агента пользователя высокого уровня, может быть желательно, разрешить одному телу сообщения ссылаться на другое. Тела могут быть помечены с помощью поля заголовка "Content-ID", которое синтаксически идентично полю "Message-ID":

    id := "Content-ID" ":" msg-id

    Подобно значениям Message-ID, значения Content-ID должны генерироваться уникальными.

    Значение Content-ID может использоваться для идентификации MIME-объектов в нескольких контекстах, в частности, для кэширования данных с доступом через механизм message/external-body. Хотя заголовок Content-ID является обычно опционным, его применение является обязательным в приложениях, которые генерируют данные опционного типа среды MIME message/external-body. По этой причине каждый объект message/external-body должен иметь поле Content-ID, чтобы разрешить кэширование таких данных.

    Часто оказывается желательным установить соответствие между описательной информацией и данным телом. Например, может быть полезным пометить тело типа image как изображение старта космического корабля. Такой текст может быть помещен в поле заголовка Content-Description. Это поле всегда является опционным.

    description := "Content-Description" ":" *text

    Предполагается, что описание дается с использованием символьного набора US-ASCII, хотя механизм, специфицированный в RFC 2047, может быть использован и для значений Content-Description, не соответствующих стандарту US-ASCII.

    Будущие документы могут содержать дополнительные поля заголовков MIME для различных целей. Любое новое поле заголовка, которое описывает содержимое сообщения, должно начинаться со строки "Content-", чтобы такие поля можно было с гарантией отличить от обычных полей заголовков сообщения, следующих стандарту RFC-822. MIME-extension-field := <Любое поле заголовка RFC-822, которое начинается со строки "Content-">

    Используя поля заголовка MIME-Version, Content-Type и Content-Transfer-Encoding, можно подключить стандартным образом произвольные типы данных и добиться совместимости с требованиями документа RFC-822. Никакие ограничения, введенные документами RFC-821 или RFC-822, не нарушаются, — были приняты меры, чтобы исключить проблемы, связанные с дополнительными ограничениями из-за свойств некоторых механизмов пересылки почты по Интернет (см. RFC-2049).

    Типы среды

    Поле Content-Type используется для спецификации природы информации в теле MIME-объекта путем присвоения идентификаторов типа и субтипа среды и предоставления дополнительной информации, которая может быть необходима для данной разновидности среды. За именами типа и субтипа среды в поле следует набор параметров, заданных в нотации атрибут/значение. Порядок следования параметров не существенен.

    Тип среды верхнего уровня используется для декларации общего типа данных, в то время как субтип определяет специфический формат данного типа информации. Таким образом, тип среды "image/xyz" говорит агенту пользователя, что данные характеризуют изображение и имеют формат xyz. Такая информация может применяться для того, чтобы решить, отображать ли пользователю исходные данные нераспознанного субтипа. Эти действия могут быть разумными для нераспознанного фрагмента субтипа text, но не для субтипов image или audio. По этой причине зарегистрированные субтипы text, image, audio и video не должны содержать встроенных фрагментов другого типа. Такие составные форматы должны использовать типы multipart или application.

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

    Поле заголовка Content-Type и механизм типа среды спроектированы так, чтобы сохранить масштабируемость, обеспечивая постепенный рост со временем числа пар тип/субтип и сопряженных с ними параметров. Транспортное кодирование MIME, а также типы доступа message/externalbody со временем могут обрести новые значения. Чтобы гарантировать, что такие значения разработаны и специфицированы корректно, в MIME предусмотрен процесс регистрации, который использует IANA (Internet Assigned Numbers Authority) в качестве главного органа, контролирующего данный процесс (см. RFC 2048). В данном разделе описаны семь стандартизованных типов среды верхнего уровня.

    Составляющие определения типа среды верхнего уровня

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

  • text — текстовая информация. Субтип plain, в частности, указывает, что текст не содержит команд форматирования или каких-либо директив. Такой текст нужно отображать как он есть. Не нужно никакого специального программного обеспечения для восприятия такого текста, помимо поддержки указанного символьного набора. Другие субтипы должны использоваться для форматированного текста ( enriched ) в форме, где прикладное программное обеспечение может улучшить представление текста. Но такая программа не нужна для общей обработки содержимого. Возможные субтипы text включают в себя любые форматы, которые могут быть прочитаны без обращения к программе, которая понимает этот формат. В частности, форматы, которые используют встроенное двоичное форматирование, не считаются непосредственно читаемыми. Очень простой и портативный субтип, richtext, был определен в документе RFC 1341, и позднее пересмотрен в RFC 1896 под именем enriched.
  • image — графические данные. Image требует устройства отображения (такого, как графический дисплей, графический принтер или факс) для того, чтобы просмотреть информацию. Первичный субтип определен для широко используемого формата изображения JPEG. Субтипы определены для двух широко используемых форматов изображения — jpeg и gif
  • audio — звуковые данные. Audio требует выходного устройства (такого, как громкоговоритель или телефон) для воспроизведения содержимого
  • video — видеоданные. Vidео требует выходного устройства, способного воспроизвести движущееся изображение. В данном документе определен первичный субтип mpeg
  • application — некоторые другие типы данных, обычно не интерпретированные двоичные данные или информация, которая должна быть обработана приложением. Субтип octet-stream следует использовать в случае не интерпретируемых двоичных данных, здесь простейшей рекомендацией может служить передача этой информации в файл пользователя. Субтип PostScript определен для транспортировки PostScript текстов
  • Существует два составных типа среды высшего уровня.

  • multipart — данные, состоящие из нескольких объектов с различными типами данных. Определены четыре первичных субтипов, включая: базовый субтип mixed, специфицирующий смешанный набор частей; alternative — для представления одних и тех же данных в различных форматах; parallel — для частей, которые должны представляться одновременно, и digest — для составных объектов, в которых каждая часть имеет тип по умолчанию "message/rfc822"
  • message — инкапсулированное сообщение. Тело типа среды message составляет часть или весь объект сообщения некоторого типа. Такие объекты могут содержать в свою очередь другие объекты. Субтип rfc822 используется, когда инкапсулированное содержимое само является сообщением RFC 822. Субтип partial определен для частичных сообщений вида RFC 822, чтобы разрешить по-фрагментную передачу слишком длинных тел сообщения. Другой субтип external-body определен для спецификации протяженных тел с помощью ссылок на внешние источники информации
  • Пять из семи базовых значений типа среды относятся к дискретным телам. Содержимое этих типов должно обрабатываться с использование механизмов за пределами MIME, они непрозрачны для MIME-процессоров.

    Тип среды Text

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

    Помимо чистого текста существует много форматов, называемых "форматированный" текст (rich text). Интересной характеристикой многих таких представлений является то, что они читабельны даже без программы, которая его интерпретирует. Полезно затем отличать их на верхнем уровне от таких нечитабельных данных, как изображения, звук или текст, представленный в нечитаемом виде. В отсутствии подходящей интерпретирующей программы разумно показать субтипы text пользователю, в то время как это неразумно для большей части нетекстовых данных. Такие форматированные текстовые данные должны представляться с помощью субтипов text.

    Каноническая форма любого субтипа MIME text должна всегда оформлять разрыв строки с помощью последовательности CRLF. Аналогично, любое появление CRLF в тексте MIME должно означать разрыв строки. Использование CR и LF по отдельности вне обозначения разрыва строки запрещено. Это правило работает вне зависимости от используемого символьного набора.

    Правильная интерпретация разрывов строк при отображении текста зависит от типа среды. Следует учитывать, что одно и то же оформление разрывов строк при отображении text/plain может восприниматься корректно, в то время как для других субтипов text, например, text/enriched [RFC-1896], аналогичные разрывы строк будут восприниматься как неверные. Нет необходимости в добавлении каких-либо разрывов строк при отображении text/plain, в то время как отображение text/enriched требует введения соответствующего оформления разрывов строк.

    Некоторые протоколы определяют максимальную длину строки. Например, SMTP [RFC-821] допускает максимум 998 октетов перед последовательностью CRLF. Для того, чтобы реализовать транспортировку посредством такого протокола, данные, содержащие слишком длинные сегменты без CRLF, должны быть закодированы с применением соответствующего content-transfer-encoding.

    Критическим параметром, который может быть специфицирован в поле Content-Type для данных text/plain, является символьный набор. Он специфицируется параметром charset, например, как:

    Content-type: text/plain; charset=iso-8859-1

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

    Для других субтипов text семантика параметра charset должна быть определена аналогично параметрам, заданным для text/plain, т.e., тело состоит полностью из символов данного набора. В частности, авторы будущих определений субтипов text должны уделить особое внимание мультиоктетным символьным наборам. Параметр charset для субтипов text дает имя символьному набору, как это определено в RFC 2045.

    Заметим, что специфицированный символьный набор включает в себя 8-битовые коды и эти символы используются в теле и в поле заголовка Content-Transfer-Encoding, а для передачи данных с помощью транспортных протоколов (например, SMTP ) необходима соответствующая кодировка, такая, как [RFC-821].

    Значение символьного набора по умолчанию, равное US-ASCII, являлось причиной многих неурядиц в прошлом. Чтобы исключить какие-либо неопределенности в будущем, настоятельно рекомендуется новым агентам пользователя задавать символьный набор в явном виде в качестве параметра типа среды в поле заголовка Content-Type. US-ASCII не указывает на произвольный 7-битовый символьный набор, а говорит о том, что все октеты в теле должны интерпретироваться как символы US-ASCII. Национальные и ориентированные на приложения версии ISO 646 [ISO-646] обычно не идентичны US-ASCII, и их непосредственное применение в электронной почте может вызвать проблемы. Имя символьного набора US-ASCII относится к кодам, заданным в документе ANSI X3.4-1986 [US-ASCII].

    Полный набор символов US-ASCII представлен в ANSI X3.4-1986. Заметим, что управляющие символы, включая DEL (0-31, 127), не имеют определенного значения, исключение составляет комбинация CRLF (US-ASCII значения 13 и 10), обозначающая разрыв строки. Два символа имеют широко используемые функции: это FF (12) — продолжить последующий текст с начала новой страницы, и TAB или HT (9), часто (хотя и не всегда) означющий "переместить курсор в следующую колонку". Колонки нумеруются, начиная с нуля, и их позиции кратны 8. Помимо этих случаев, любые управляющие символы или DEL в теле объекта могут появиться при следующих условиях.

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

  • US-ASCII — как это определено в ANSI X3.4-1986 [US-ASCII].
  • ISO-8859-X — где "X" следует замещать, как это требуется для частей ISO-8859 [ISO-8859]. Допустимыми подменами "X" являются цифры от 1 до 10.
  • Символы с кодами в диапазоне 128-159 не имеют стандартизованных значений в рамках ISO-8859-X. Символы с кодами меньше 128 в ISO-8859-X имеют те же значения, что и в US-ASCII.

    Значения символьных наборов ISO-8859-6 и ISO-8859-8 специфицируют применение визуального метода [RFC-1556].

    Все эти символьные наборы применяются как чисто 7-битовые или 8-битовые без модификаций, связанных c <shift> или <escape>.

    Никакие символьные наборы, отличные от определенных выше, не могут использоваться в электронной почте без публикации и формальной регистрации в IANA. Допустимы частные соглашения, в этом случае имя символьного набора должно начинаться с X-.

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

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

    Простейшим и наиболее важным субтипом text является plain. Он указывает, что текст не содержит форматирующих команд или директив. Чистый текст может отображаться непосредственно без какой-либо обработки. По умолчанию для электронной почты предполагается тип среды text/plain; charset=us-ascii.

    Не распознанные субтипы text должны обрабатываться как чистый текст (plain), поскольку реализация MIME знает, как работать с данным символьным набором. Не распознанные субтипы, которые также специфицируют нераспознаваемый символьный набор, должны обрабатываться как application/octet- stream.

    Тип среды Image

    Тип среды image указывает, что тело содержит изображение. Субтип называет имя специфического формата изображения. Эти имена не чувствительны к регистру. Исходным субтипом является jpeg, который использует кодировку JFIF для формата JPEG [JPEG]. Не распознанные субтипы image должны обрабатываться как application/octet-stream.

    Тип среды Audio

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

    Содержимое субтипа audio/basic представляет собой моноканальное звуковое кодирование, использующее 8-битный ISDN-стандарт с $$\mu$$ -функцией преобразования [PCM] с частотой стробирования 8000 Гц. Не распознанные субтипы audio должны обрабатываться как application/octet-stream.

    Тип среды Video

    Тип среды video указывает, что тело содержит движущееся изображение, возможно, цветное и в сопровождении звука. Термин video используется в самом общем значении и не подразумевает какого-то конкретного формата. Субтип mpeg относится к видео, закодированному согласно стандарту MPEG [MPEG]. Не распознанные субтипы video должны обрабатываться как application/octet-stream.

    (1) В список опасных операций языка PostScript входят deletefile, renamefile, filenameforall и file. File является единственной опасной процедурой, которая применяется для входных/выходных потоков нестандартных данных. Конкретные реализации могут определить нестандартные файловые операторы, которые могут также представлять угрозу безопасности. Filenameforall, — оператор поиска файлов, может показаться на первый взгляд безобидным. Заметим, что этот оператор может раскрыть информацию о том, к каким файлам имеет доступ пользователь, а эти данные могут облегчить задачу хакеру. Отправители сообщений должны избегать использования потенциально опасных файловых операторов, так как такие операторы, скорее всего, недоступны в PostScript приложениях, где приняты меры по обеспечению безопасности. Программное обеспечение, которое используется для приема и отображения, должно блокировать потенциально опасные файловые операторы или принять меры по ограничению их возможностей
    (2) Язык PostScript предоставляет возможность для выхода из цикла интерпретатора или сервера. Операторы, сопряженные с выходом интерпретатора из цикла, могут интерферировать с процедурами последующей обработки документов. Операторы PostScript, которые выводят интерпретатор из цикла, включают в себя серверы выхода и начала задания. Программе отправки сообщения не следует генерировать PostScript, который зависит от функционирования выхода интерпретатора из цикла, так как такая процедура может отсутствовать в реализациях с повышенной безопасностью. Программа приема сообщений должна полностью блокировать работу операторов startjob и exitserver, а также какие-либо изменения в среде PostScript на постоянной основе. Если эти операции не могут быть полностью исключены, для их выполнения должен быть организован контролируемый доступ с необходимостью ввода пароля
    (3) PostScript предоставляет операторы для установки системных параметров и специфических параметров внешних устройств. Эти установки параметров могут влиять неблагоприятным образом на работу интерпретатора. Процедуры PostScript, которые устанавливают системные параметры, могут включать в себя операторы setsystemparams и setdevparams. Программа отправки не должна генерировать PostScript-сообщений, которые зависят от установки системных параметров. Программа приема и отображения сообщений должна блокировать изменение системных параметров. Если блокировка по каким-либо причинам невозможна, процедура установки параметров должна требовать специфического пароля
    (4) Некоторые реализации PostScript предоставляют нестандартные возможности для прямой загрузки и исполнения машинных кодов. Такие возможности чреваты злоупотреблениями. Программа отправки сообщений не должна использовать такие возможности. Программа приема и отображения сообщений не должна позволять применение таких операторов, если они имеются
    (5) PostScript является расширяемым языком, и многое, если не большинство, его реализаций предоставляют большое число расширений. Программа отправки сообщений не должна использовать нестандартные расширения. Программа приема и отображения сообщений должна быть уверена, что эти нестандартные расширения не представляют угрозы
    (6) Имеется возможность написания такой PostScript-программы, которая потребует огромных системных ресурсов. Можно также написать PostScript-фрагмент, который реализует бесконечный цикл. Оба варианта представляют угрозу для ничего не подозревающего получателя. Программа отправки сообщений должна избегать создания и распространения таких кодов. Программа приема и отображения сообщений должна предоставлять подходящий механизм для блокировки исполнения и удаления таких программ по истечении некоторого заданного времени
    (7) Существует возможность включения двоичной информации в PostScript-текст. Это не рекомендуется в электронной почте, так как это не поддерживается всеми PostScript-интерпретаторами, потому что сильно усложняет использование транспортного кодирования MIME.
    (8) Наконец, в некоторых интерпретаторах PostScript вполне возможны ошибки, которые могут использоваться для получения не авторизованного доступа к системе получателя

    Тип среды Application

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

    Такие приложения могут быть определены как субтипы типа среды application. В данном документе определены два субтипа: octet-stream и PostScript.

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

  • TYPE — общий тип или категория двоичных данных. Это параметр предназначен для оператора-получателя, а не для программы обработки
  • PADDING — число бит заполнителя, который добавлен к потоку бит, представляющему действительное содержимое, для того чтобы получить байт-ориентированный поток. Используется, когда число бит в теле не кратно 8
  • Оба эти параметра являются опционными.

    Тип среды application/postscript указывает на программу PostScript. В настоящее время допускается два варианта языка PostScript. Исходный вариант уровня 1 описан в [POSTSCRIPT], а более новый вариант уровня 2 рассмотрен в [POSTSCRIPT2].

    Описания языка PostScript предоставляет возможности внутренней пометки специфических возможностей данного приложения. Эта пометка, называемая DSC (document structuring conventions) PostScript, предоставляет существенно больше информации, чем уровень языка. Использование DSC рекомендуется даже тогда, когда это непосредственно не требуется, так как обеспечивает более широкую совместимость. Документы, которые недостаточно структурированы, не могут быть проверены с целью выяснения того, могут ли они работать в данной среде.

    Работа универсальных интерпретаторов PostScript представляет серьезную угрозу безопасности, разработчикам не рекомендуется просто посылать тела PostScript имеющимся ("off-the-shelf") интерпретаторам. В то время как посылка PostScript-файла на принтер обычно безопасна, программисты должны рассмотреть все возможные последствия, прежде чем ввести интерактивное отображение тел типа PostScript на их читающих средствах MIME.

    Оставшиеся два из семи исходных значений Content-Type относятся к составным объектам. Составные объекты обрабатываются с использованием механизмов MIME — процессор MIME обрабатывает тело объекта непосредственно.

    Тип среды Multipart

    В случае составных объектов, когда один или более различных наборов данных объединяется в одном теле, в заголовке объекта должно присутствовать поле типа среды multipart. Тело должно тогда содержать одну или более частей, каждая из которых начинается с разделительной строки. За разделительной строкой следует заголовок, пустая строка и тело объекта. Таким образом, часть тела по своему синтаксису аналогична сообщению в RFC-822, но имеет другое назначение.

    Часть тела является объектом и, следовательно, не должна интерпретироваться как сообщение RFC-822. Начнем с того, что части тела должны иметь заголовки. Допустимы части тела, которые начинаются с пустой строки. В таком случае отсутствие заголовка Content-Type обычно указывает, что соответствующее тело имеет тип содержимого text/plain;charset=US-ASCII.

    Единственные поля заголовка, которые определяют назначение частей тела, имеют имена, начинающиеся с Content-. Все другие поля в заголовке части тела могут игнорироваться. Для экспериментальных или частных назначений могут создаваться поля с именами, начинающимися с X-. Информация, содержащаяся в этих полях, может теряться в некоторых шлюзах.

    Различие между сообщением RFC-822 и частью тела не велико, но существенно. Шлюз между Интернет и почтовым сервером X.400, например, должен быть способен различать части тела, содержащие изображение, и инкапсулированное сообщение, тело которого представляет собой JPEG-образ. Для того, чтобы представить последнее, часть тела должна иметь Content-Type: message/rfc822, и ее тело после пустой строки должно представлять собой инкапсулированное сообщение со своим собственным полем заголовка Content-Type: image/jpeg. Применение подобного синтаксиса способствует преобразованию сообщений в части тела и обратно.

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

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

    Как задано в определении поля Content-Transfer-Encoding [RFC-2045], никакие кодировки кроме 7bit, 8bit или binary не разрешены для объектов типа multipart. Граничные разделители и поля заголовков multipart всегда представляются как 7-битовые коды US-ASCII, а данные внутри частей тела могут быть закодированы по-разному и иметь свои поля Content-Transfer-Encoding для каждой из частей.

    Поле Content-Type для составных объектов требует одного параметра — boundary. Строка-разделитель определяется как строка, содержащая два символа дефис ("-", десятичный код 45), за которыми следует значение пограничного параметра из поля заголовка Content-Type, опционный строчный пробел и заключительные CRLF.

    Символы дефис служат для некоторой совместимости с ранним методом (RFC-934) инкапсуляции сообщений и для облегчения поиска границ для некоторых приложений. Однако следует заметить, что составные сообщения не вполне совместимы с инкапсуляцией, описанной в RFC-934. В частности, они не подчиняются RFC-934 регламентации использования кавычек для вложенных строк, которые начинаются с дефиса. Этот механизм был выбран помимо RFC-934, потому что при данной схеме происходит удлинение строк для каждого уровня закавычивания. Возрастание длины строк, а также то, что некоторые реализации SMTP осуществляют разрыв строк, делают механизм RFC-934 неприменимым для составных сообщений при большой глубине вложений.

    Грамматика для параметров поля Content-type такова, что в строке Content-type часто приходится помещать пограничный параметр в кавычки. Это необходимо не всегда, но никогда не повредит. Программисты должны тщательно изучить грамматику, чтобы избежать генерации некорректных полей Content-type. Таким образом, типичное поле заголовка multipart Content-Type может выглядеть как:

    Content-Type: multipart/mixed; boundary=gc0p4Jq0M2Yt08j34c0p

    Но следующая запись некорректна: Content-Type: multipart/mixed; boundary=gc0pJq0M:08jU534c0p (из-за двоеточия) и должна вместо этого выглядеть как:

    Content-Type: multipart/mixed; boundary="gc0pJq0M:08jU534c0p"

    Это значение Content-Type указывает, что содержимое состоит из одной или более частей со структурой, которая синтаксически идентична сообщению RFC-822, за исключением того, что область заголовка может быть совершенно пустой, а каждая из частей начинается со строки

    --gc0pJq0M:08jU534c0p

    Пограничный разделитель должен размещаться в начале строки, т.e., следовать за CRLF, а начальный CRLF рассматривается объединенным со строкой пограничного разделителя, а не частью предшествующей секции. За границей может следовать нуль или более символов строчного пробела (HT, SP). Далее следует еще один CRLF и поля заголовка следующей части или два CRLF, что означает отсутствие полей заголовка следующей части. Если поле Content-Type отсутствует, предполагается объект типа message/rfc822 в сообщении multipart/digest, в противном случае text/plain.

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

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

    --gc0pJq0M:08jU534c0p--

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

    Имеется место для дополнительной информации перед пограничным разделителем и после оконечного разграничителя. Эти области следует в нормальной ситуации оставлять пустыми, а программные реализации должны игнорировать размещенную там информацию. Некоторые реализации используют эти ниши для пересылки сообщений принимающим программам.

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

    Ниже представлен простой пример составного сообщения, имеющего две части, каждая из которых содержит чистый текст, введенный явно и неявно:

    From: Nathaniel Borenstein
    To: Ned Freed
    Date: Sun, 21 Mar 1993 23:56:48 -0800 (PST)
    Subject: Sample message
    MIME-Version: 1.0
    Content-type: multipart/mixed; boundary="simple boundary"

    Это преамбула. Она будет проигнорирована, но, тем не менее, это удобное место, чтобы отправитель мог поместить сообщение для принимающей стороны, которая не поддерживает MIME.

    --simple boundary Это неявно введенный чистый US-ASCII-текст. Он не завершается на данной строке
    --simple boundary Content-type: text/plain; charset=us-ascii. Это явно введенный чистый US-ASCII-текст. Он завершается на данной строке
    --simple boundary Это эпилог. Он также игнорируется

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

    Практика показала, что тип multipart с единственной составной частью полезен для посылки сообщений с нетекстовым типом среды. Он имеет возможность формирования преамбулы как места, где можно поместить инструкции по декодированию. Кроме того, многие шлюзы SMTP перемещают или удаляют заголовки MIME, и хороший MIME-декодер таким путем может получить необходимую информацию даже в отсутствие заголовка Content-Type и корректно декодировать сообщение.

    Единственным обязательным глобальным параметром для типа среды multipart является граничный параметр, состоящий из 1 - 70 кодов символьного набора, который надежен по отношению преобразований, осуществляемых почтовыми шлюзами. Значение параметра не должно завершаться пробелом. Формально это записывается в BNF-представлении следующим образом.

    boundary := 0*69 bcharsnospace
    bchars := bcharsnospace / " "
    bcharsnospace := DIGIT / ALPHA / "’" / "(" / ")" / "+" / "_" /
       "," / "-" / "." / "/" / ":" / "=" / "?"

    Вообще тело объекта multipart может быть специфицировано как:

    dash-boundary := "--" boundary
    ; boundary берется из значения граничного параметра поля Content-Type.
    multipart-body := [preamble CRLF]
    dash-boundary transport-padding
    CRLF
    body-part *encapsulation
    close-delimiter transport-padding
    [CRLF epilogue]
    transport-padding := *LWSP-char ; Отправители не должны генерировать
    ; транспортные заполнители ненулевой
    ; длины, но получатели должны уметь
    ; обрабатывать заполнители, введенные
    ; при транспортировке.
    encapsulation := delimiter transport-padding CRLF body-part
    delimiter := CRLF dash-boundary
    close-delimiter := delimiter "--"
    epilogue := discard-text
    ; Строки части тела не должны начинаться с дефис-границы, а разделитель
    ; не должен появляться где-либо в теле секции. Заметим, что семантика части
    ; тела отличается от семантики сообщения, как это описано в тексте.
    OCTET := <любое значение октета 0-255 >

    Введение пробелов (HT, SP) и комментариев RFC 822 между элементами, показанными выше, недопустимо, так как эти BNF не специфицируют структурированное поле заголовка.

    В определенных транспортных зонах регламентации RFC 822, такие, как ограничение применения каких-либо символов, помимо печатных кодов US-ASCII, могут не действовать. Ослабление этих ограничений может рассматриваться как локальное расширение определения тел, например, чтобы включить октеты вне набора US-ASCII, так как эти расширения поддерживаются системой передачи и соответствующим образом документированы в поле заголовка Content-Transfer-Encoding. Однако заголовки ни в коем случае не могут содержать чего-либо помимо кодов US-ASCII.

    Субтип message/rfc822 не имеет других условий завершения, кроме окончания массива данных. Аналогично, некорректно укороченный составной объект не может иметь завершающего разделителя, что может вызвать нарушение работы почтовой системы.

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

    Субтип mixed типа multipart предназначен для использования в условиях, когда части тела независимы и должны объединяться в определенном порядке. Любые субтипы multipart, которые не распознаны программой, должны восприниматься как субтип mixed.

    Тип multipart/alternative синтаксически идентичен multipart/mixed, но имеет иную семантику. В частности, каждая часть тела является альтернативой одной и той же информации.

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

    Multipart/alternative может использоваться, например, для посылки сообщения в любом формате таким образом, чтобы его было легко отобразить:

    From: Nathaniel Borenstein
    To: Ned Freed
    Date: Mon, 22 Mar 1993 09:41:09 -0800 (PST)
    Subject: Formatted text mail
    MIME-Version: 1.0
    Content-Type: multipart/alternative; boundary=boundary42
    --boundary42
    Content-Type: text/plain; charset=us-ascii
    ... здесь следует версия сообщения в виде чистого текста ...
    --boundary42
    Content-Type: text/enriched
    ... здесь следует версия сообщения RFC 1896 в виде форматированного текста
    (text/enriched) ...
    --boundary42
    Content-Type: application/x-whatever
    ... здесь следует наиболее причудливая версия сообщения ...
    --boundary42--

    В этом примере пользователи, чья почтовая система может работать с форматом application/x-whatever, увидят только причудливую версию сообщения, в то время как другие пользователи увидят версию с форматированным или чистым текстом, в зависимости от возможностей их системы.

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

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

    Каждая часть объекта multipart/alternative представляет одну и ту же информацию, версии не обязательно тождественны. Например, информация теряется, когда осуществляется трансляция ODA в PostScript или в чистый текст. Рекомендуется, чтобы каждая часть имела свое значение Content-ID в тех случаях, когда содержимое частей неэквивалентно. Например, там, где несколько частей типа message/external-body специфицируют способы доступа к идентичной информации, следует использовать одни и те же значения поля Content-ID. Возможен вариант, когда одно значение Content-ID может относиться к объекту multipart/alternative, в то время как одно или более других значений Content-ID будут относиться к частям внутри объекта.

    Этот документ определяет субтип digest типа содержимого multipart. Этот тип синтаксически идентичен multipart/mixed, но их семантика различна. В частности, в дайджесте значение по умолчанию Content-Type для части тела меняется с text/plain на message/rfc822. Это сделано, чтобы допустить более читаемый формат дайджеста, совместимый с RFC-934.

    Хотя можно специфицировать значение Content-Type для части тела в дайджесте, который отличается от message/rfc822, такая часть, как text/plain, содержащая описание материала в дайджесте, делает это нежелательным. Тип содержимого multipart/digest предназначен для использования при посылке группы сообщений. Если необходима часть text/plain, она должна быть включена как отдельная компонента сообщения multipart/mixed. Дайджест в этом формате может выглядеть как:

    From: Moderator-Address
    To: Recipient-List
    Date: Mon, 22 Mar 1994 13:34:51 +0000
    Subject: Internet Digest, volume 42
    MIME-Version: 1.0
    Content-Type: multipart/mixed;
    boundary="---- main boundary ----"
    ------ main boundary ----
    ...Вводный текст или содержимое таблицы...
    ------ main boundary ----
    Content-Type: multipart/digest;
    boundary="---- next message ----"
    ------ next message ----
    From: someone-else
    Date: Fri, 26 Mar 1993 11:13:32 +0200
    Subject: my opinion
    ... здесь размещается тело...
    ------ next message ----
    From: someone-else-again
    Date: Fri, 26 Mar 1993 10:07:13 -0500
    Subject: my different opinion
    ... здесь размещается следующее тело ...
    ------ next message ------
    ------ main boundary ------

    Этот документ определяет субтип parallel типа содержимого multipart. Этот тип синтаксически идентичен multipart/mixed, но их семантика различна. В частности, в параллельном объекте порядок частей тела не играет роли.

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

    Тип среды Message

    Часто желательно при посылке почты вложить туда какое-то другое сообщение. Для решения этой задачи определен специальный тип среды message. В частности, для вложения в сообщения RFC-822 служит субтип rfc822.

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

    Тип среды message/rfc822 указывает, что тело содержит инкапсулированное сообщение. Однако в отличие от сообщений верхнего уровня RFC-822, ограничение, связанное с обязательным присутствием в теле message/rfc822 заголовков From, Date, и, по крайней мере, одного адреса места назначения, здесь удалено. Необходимо лишь присутствие одного из заголовков From, Subject или Date. Следует заметить, что, несмотря на использование чисел 822, объект message/rfc822 не должен абсолютно следовать регламентациям RFC-822. Более того, сообщение message/rfc822 может быть статьей новостей или сообщением MIME.

    В теле объекта message/rfc822 не разрешены никакие кодировки помимо 7bit, 8bit или binary. Поля заголовка сообщения содержат только US-ASCII в любом регистре, а информация в теле может быть закодирована. Не-US-ASCII-текст в заголовках инкапсулированного сообщения может быть специфицирован с использованием механизма, описанного в документе RFC-2047.

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

    Так как данные типа message могут не быть закодированы в виде base64 или закавыченной строки печатных символов, может возникнуть проблема, если объекты message/partial созданы в среде, которая поддерживает двоичный или 8-битовый обмен. Проблема возникает из-за того, что двоичные данные надо будет разбить на несколько сообщений message/partial, каждое из которых требует двоичного транспорта. Если такие сообщения встретят по пути шлюз с 7-битовой передачей, не будет никакой возможности перекодировать эти фрагменты для 7-битовой среды. Можно, конечно, дождаться прихода всех составных частей, собрать исходный объект, закодировать его с помощью, например, base64, после чего начать все с начала. Но даже такой сложный сценарий может оказаться неосуществимым из-за того, что фрагменты могут транспортироваться разными путями. По этой причине было специфицировано, что объекты типа message/partial должны всегда иметь транспортное кодирование 7bit (по умолчанию). В частности, даже для сред, которые поддерживают двоичный или 8-битовый обмен, использование транспортного кодирования 8bit или binary для MIME-объектов типа message/partial запрещено. Это, в свою очередь, предполагает, что внутреннее сообщение не должно использовать кодирование 8bit или binary. Так как некоторые агенты пересылки сообщений могут выбрать автоматическую фрагментацию длинных сообщений, а также из-за того, что эти агенты могут использовать разные пороги фрагментации, может так получиться, что фрагменты после сборки в свою очередь окажутся частями сообщения. Это вполне допустимо.

    В поле Content-Type типа message/partial необходимо специфицировать три параметра. id — уникальный идентификатор, который должен использоваться для привязки фрагментов друг к другу. number — целое число, которое является номером фрагмента. total — целое число, характеризующее полное число фрагментов. Число фрагментов является опционным и обязательно присутствует только в последнем фрагменте. Заметим также, что эти параметры могут быть заданы в любом порядке. Таким образом, второй сегмент 3-фрагментного сообщения может иметь поля заголовка одного из следующих видов.

    Content-Type: Message/Partial; number=2; total=3;
    Id="oc=jpbe0M2Yt4s@thumper.bellcore.com"
    Content-Type: Message/Partial;
    Id="oc=jpbe0M2Yt4s@thumper.bellcore.com";
    number=2

    Но в третьем сегменте должно быть специфицировано полное число фрагментов.

    Content-Type: Message/Partial; number=3; total=3;
    Id="oc=jpbe0M2Yt4s@thumper.bellcore.com"

    Заметьте, что нумерация фрагментов начинается с 1, а не c 0.

    Когда фрагменты объекта, разорванные таким способом, складываются вместе, результатом всегда будет исходный MIME-объект, который может иметь свое собственное поле заголовка Content-Type и, следовательно, иметь любой другой тип данных.

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

  • Фрагментирующие агенты должны разделять сообщения только по границам строк. Это ограничение вводится из-за того, что при несоблюдении данного правила возникнет транспортная проблема сохранения семантики сообщения, не заканчивающегося последовательностью CRLF. Многие виды транспорта не способны решить такую задачу
  • Все поля заголовка исходного вложенного сообщения, за исключением тех, чьи имена начинаются с "Content-", и специфических полей заголовка Subject, Message-ID, Encrypted и MIMEVersion, должны копироваться в новое сообщение
  • Поля заголовка вложенного сообщения, начинающиеся с "Content-", плюс поля Subject, Message-ID, Encrypted и MIMEVersion, должны быть добавлены к полям нового сообщения. Любые поля заголовка, которые не начинаются с "Content-" (за исключением полей Subject, Message-ID, Encrypted и MIMEVersion) будут проигнорированы и отброшены
  • Все поля заголовка второго и любых последующих вложенных сообщений отбрасываются принимающей программой в процессе сборки
  • Если аудио-сообщение разделено на два фрагмента, первая часть может выглядеть как:

    X-Weird-Header-1: Foo
    From: Bill@host.com
    Date: Fri, 26 Mar 1993 12:59:38 -0500 (EST)
    Subject: Audio mail (part 1 of 2)
    Message-ID:
    MIME-Version: 1.0
    Content-type: message/partial; id="ABC@host.com";
    number=1; total=2
    X-Weird-Header-1: Bar
    X-Weird-Header-2: Hello
    Message-ID:
    Subject: Audio mail
    Content-type: audio/basic
    Content-transfer-encoding: base64
    ... здесь помещается первая половина закодированных аудиоданных ...

    а вторая часть может выглядеть следующим образом:

    From: Bill@host.com
    To: joe@otherhost.com
    Date: Fri, 26 Mar 1993 12:59:38 -0500 (EST)
    Subject: Audio mail (part 2 of 2)
    MIME-Version: 1.0
    Message-ID:
    Content-type: message/partial;
    id="ABC@host.com"; number=2; total=2
    ... здесь помещается вторая половина закодированных аудиоданных ...

    Затем, когда фрагментируемое сообщение оказывается собрано, результат, отображаемый для пользователя, должен выглядеть как:

    X-Weird-Header-1: Foo
    From: Bill@host.com
    To: joe@otherhost.com
    Date: Fri, 26 Mar 1993 12:59:38 -0500 (EST)
    Subject: Audio mail
    Message-ID:
    MIME-Version: 1.0
    Content-type: audio/basic
    Content-transfer-encoding: base64
    ... здесь помещается первая половина закодированных аудиоданных ...
    ... здесь помещается вторая половина закодированных аудиоданных ...

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

    Наконец, следует заметить, что поле Encrypted заголовка является устаревшим из-за внедрения конфиденциальной почты PEM (Privacy Enhanced Messaging; RFC-1421, RFC-1422, RFC-1423, RFC-1424), но правила, описанные выше, несмотря ни на что, описывают правильный путь его обработки, если оно встретится в контексте прямого и обратного преобразования фрагментов message/partial.

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

    Когда объект MIME имеет тип message/external-body, он состоит из заголовка, двух последовательностей CRLF и заголовка для инкапсулированного сообщения. Если появится еще одна пара последовательностей CRLF, это завершит заголовок инкапсулированного сообщения. Однако, так как тело инкапсулированного сообщения само является внешним, оно не появится вслед за заголовком. Например, рассмотрим следующее сообщение:

    Content-type: message/external-body;
    access-type=local-file;
    name="/u/nsb/Me.jpeg"
    Content-type: image/jpeg
    Content-ID:
    Content-Transfer-Encoding: binary
    Это в действительности не тело!

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

    Инкапсулированные заголовки во всех объектах message/externalbody должны включать в себя поле заголовка Content-ID, чтобы предоставить уникальный идентификатор, который служит для ссылки на данные. Этот идентификатор может быть использован в процессе кэширования и для распознавания входных данных, когда типом доступа является mailserver.

    Заметим, что, как это специфицировано здесь, лексемы, которые описывают данные внешнего тела, такие, как имена файлов и команды почтового сервера, должны быть записаны с использованием символьного набора US-ASCII.

    Как с message/partial, объекты MIME типа message/external-body имеют транспортное кодирование 7-бит (по умолчанию). В частности, даже в среде, которая поддерживает 8-битовую транспортировку, использование транспортного кодирования 8bit или binary категорически запрещено для объектов типа message/external-body.

    Типы доступа ftp и tftp

    Тип доступа FTP или TFTP указывают, что тело сообщения доступно в виде файла с помощью протоколов FTP [RFC-959] или TFTP [RFC-783], соответственно. Для этих типов доступа необходимы следующие параметры.

  • NAME (имя). Имя файла, который содержит тело данных
  • SITE (узел). ЭВМ, с которой может быть получен файл с помощью данного протокола. Это должно быть официально зарегистрированное имя, а не псевдоним
  • Прежде чем какие-либо данные будут извлечены с помощью FTP, пользователь должен выполнить процедуру аутентификации (ввести имя и пароль) на машине, указанной в параметре SITE. По соображениям безопасности имя и пароль не специфицируются параметрами типа доступа, они должны быть получены непосредственно от пользователя
  • Кроме того, следующие параметры являются опционными:

  • DIRECTORY (каталог). Каталог, из которого должен быть взят файл с именем, заданным параметром NAME
  • MODE (режим). Строка символов, не зависящая от регистра ввода и указывающая на режим, который должен использоваться при извлечении информации. Допустимыми значениями параметра типа доступа TFTP являются NETASCII, OCTET и MAIL, как это определено для протокола TFTP [RFC- 783]. Допустимыми значениями параметра для типа доступа FTP являются ASCII, EBCDIC, IMAGE и LOCALn, где "n" — целое число, обычно 8. Они соответствуют типам представления "A" "E" "I" и "L n", как это задано протоколом FTP [RFC-959]. Заметим, что BINARY и TENEX не являются корректными значениями для MODE и что вместо этого следует использовать OCTET, IMAGE или LOCAL8. Если параметр MODE не задан, значением по умолчанию является NETASCII для TFTP и ASCII во всех прочих случаях
  • Тип доступа local-file

    Тип доступа local-file указывает, что тело данных доступно в виде файла на локальной ЭВМ. Для этого типа доступа определены два дополнительные параметра.

  • NAME (имя). Имя файла, который содержит тело данных. Этот параметр является обязательным для типа доступа local-file
  • SITE (узел). Спецификатор домена для данной ЭВМ или набора машин, которые имеют доступ к данному информационному файлу. Этот опционный параметр используется для описания локального указателя на данные, т.е., узел или группу узлов, откуда данный файл доступен. В качестве символов подмены в имени домена могут использоваться звездочки, как, например, в "*.bellcore.com", чтобы указать на группу ЭВМ, откуда данные доступны непосредственно
  • Тип доступа mail-server

    Тип доступа mail-server указывает, что тело данных доступно на почтовом сервере. Для этого типа доступа определены два дополнительные параметра.

  • SERVER (сервер). Спецификация адреса почтового сервера, с которого могут быть получены данные. Этот параметр является обязательным для типа доступа mail-server
  • SUBJECT (тема сообщения). Тема сообщения (subject), которая используется в почтовом сообщении с целью получения данных. Этот параметр является опционным
  • Так как почтовые серверы воспринимают разнообразные синтаксисы, некоторые из которых являются многострочными, полная команда, которая должна быть послана почтовому серверу, не включается в качестве параметра с полем заголовка content-type. Вместо этого она заносится как тело-фантом, когда тип среды соответствует message/external-body, а типом доступа — mail-server.

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

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

    Страницы:

    Протокол электронной почты

    Главной целью протокола SMTP (Simple Mail Transfer Protocol, RFC-821, -822) служит надежная и эффективная доставка электронных почтовых сообщений. SMTP является довольно независимой субсистемой и требует только надежного канала связи. Средой для SMTP может служить отдельная локальная сеть, система сетей или весь Интернет.

    SMTP базируется на следующей модели коммуникаций: в ответ на запрос пользователя почтовая программа-отправитель устанавливает двухстороннюю связь с программой-приемником (TCP, порт 25). Получателем может быть оконечный или промежуточный адресат. SMTP -команды генерируются отправителем и посылаются получателю. На каждую команду должен быть отправлен и получен отклик.

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

    tn dxmint.cern.ch 25 (команда telnet с использованием порта 25)
    220 dxmint.cern.ch sendmail ready at sun, 9 jul 1995 11:13:57 +0200 
      (связь установлена, код отклика 220 является положительным)
    EHLO dxmint.cern.ch (поддерживает ли сервер расширение mime?)
    500 command unrecognized (не поддерживает)
    HELO crnvma.cern.ch (команда выхода на конкретный сервер)
    250 dxmint.cern.ch hello crnvma.cern.ch, pleased to meet you 
      (отклик 250 также является положительным)
    mail from:<> (так как на моей PC нет резидентной почтовой программы, я
    не указываю обратного адреса, по этой причине принимающая программа
    может счесть данное сообщение SPAM'ом)
    250 <>... sender ok (команда прошла успешно)
    RCPT TO: ysemenov@cernvm.cern.ch (указываем адрес места назначения)
    250 ... recipient ok
    DATA (начало ввода текста сообщения)
    nu-i-nu... (текст сообщения)
    . (знак конца сообщения)
    QUIT (прерывание или завершение процедуры)
    221 dxmint.cern.ch closing connection 
       (сообщение об успешном завершении процедуры)

    Почтовое сообщение отправлено без использования доступа к локальной почтовой программе. Следует отметить, что работа через порт 25 в данном случае открывает богатые возможности для хакеров. Вообще опытный программист может многого достичь, умело используя номера портов. Здесь есть над чем поработать людям, ответственным за безопасность сетей. Аналогично, не имея авторизации, можно выявить клиентов почтового сервера, используя команду VRFY (если она не блокирована административно):

    tn ns.itep.ru 25
    220 ns.itep.ru 5.67a8/ida-1.5 sendmail is ready at sat, 29 jul 1995 13:53:03
    vrfy bobyshev
    250 andrey bobyshev
    и т.д.
    quit

    SMTP -отправитель и SMTP -получатель могут вести диалог с несколькими оконечными пользователями (рис 2.1). Любое почтовое сообщение завершается специальной последовательностью символов. Если получатель успешно завершил прием и обработку почтового сообщения, он посылает положительное подтверждение.

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

    (рис 2.1) Схема взаимодействия различных частей почтовой системы

    Для решения поставленной задачи SMTP -сервер должен знать имя конечного получателя и название почтового ящика места назначения. Аргументом команды MAIL является адрес отправителя (обратный адрес). Аргументом команды RCPT служит адрес конечного получателя. Обратный адрес используется для посылки сообщения в случае ошибки.

    Все отклики имеют цифровые коды. Команды, отклики и имена ЭВМ не чувствительны к тому, строчные или прописные символы использованы при их написании, но это не всегда справедливо при написании имен и адресов получателя.

    Почтовый протокол SMTP работает только с ASCII-символами. Если транспортный канал работает с октетами, 7-битные коды будут дополнены нулевым восьмым битом. Именно здесь коренилась проблема пересылки почтовых сообщений на русском языке (русский алфавит требует 8-битового представления). Проблема усугубляется тем, что для русского алфавита принято 4 кодовых представления, здесь мы впереди планеты всей…

    Как уже было сказано, процедура отправки почтового сообщения начинается с посылки команды MAIL, которая имеет формат:

    MAIL <SP> FROM:<reverse-path> <CRLF>,

    где <SP> — пробел, <CRLF> — комбинация кодов возврата каретки и перехода на новую строку, а <reverse-path> — обратный путь (имя почтового ящика отправителя). Именно этот адрес используется, если получатель сообщения воспользуется командой reply.

    Эта команда сообщает SMTP -получателю, что стартует новая процедура и следует сбросить в исходное состояние все статусные таблицы, буферы и т.д. Если команда прошла, получатель реагирует откликом: 250 OK.

    Аргумент может содержать не только адрес почтового ящика — в общем случае он является списком адресов ЭВМ-серверов, через которые пришло данное сообщение, включая, разумеется, и адрес почтового ящика отправителя. Первым в списке <reverse-path> стоит адрес ЭВМ-отправителя. После прохождения команды MAIL посылается команда RCPT:

    RCPT <SP> TO:<forward-path> <CRLF>

    Эта команда указывает адрес конечного получателя ( <forward-path> ). При благополучном прохождении команды получатель посылает кодотклик 250 OK, и запоминает полученный адрес. Если получатель неизвестен, SMTP -сервер пошлет отклик 550 Failure reply. Команда RCPT может повторяться сколько угодно раз, если адресат не один.

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

    DATA <CRLF>

    При правильном приеме этого сообщения SMTP -сервер реагирует посылкой отклика 354 Intermediate reply (промежуточный отклик), и рассматривает все последующие строки в качестве почтового текста. При получении кода конца текста отправляется отклик: 250 OK.

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

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

    1. 251 User not local; will forward to <forward-path>

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

    2. 551 User not local; please try <forward-path>

    Получатель знает правильный адрес и предлагает отправителю переадресовать сообщение по адресу <forward-path>.

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

    Реакция на команду VRFY зависит от аргумента. Так если среди клиентов почтового сервера имеется два пользователя с именем Ivanov, откликом на команду "VRFY Ivanov" будет "553 User ambiguous". В общем случае команда VRFY Ivanov может получить в качестве откликов:

    250 Vasja Ivanov Ivanov@cl.itep.ru
    или:
    251 User not local; will forward to Ivanov@cl.itep.ru
    или:
    550 String does not match anything (данная строка ничему не соответству-
    ет).
    или:
    551 User not local; please try Vasja@ns.itep.ru
    или:
    VRFY Chtozachertovchina
    553 User ambiguous (несуществующее имя)

    В случае распечатки списка адресов отклик занимает несколько строк, например:

    EXPN Example-People
    250-Juri Semenov Semenov@ns.itep.ru
    250-Alexey Sher Sher@suncom.itep.ru
    250-Andrey Bobyshev Bobyshev@ns.itep.ru
    250-Igor Gursky Gursky@ns.itep.ru

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

    Основной задачей почты служит доставка сообщений в почтовый ящик адресата. Сходную форму услуги оказывают некоторые ЭВМ, доставляя сообщения на экран терминала (в рамках SMTP ). Для посылки сообщений на экран терминала адресата предусмотрено три команды:

    1. SEND <SP> FROM:<reverse-path> <CRLF>

    Команда SEND требует, чтобы почтовое сообщение было доставлено на терминал. Если терминал адресата не активен в данный момент, то откликом на команду RCPT будет код 450.

    2. SOML <SP> FROM:<reverse-path> <CRLF>

    Команда Send Or MaiL (SOML) пересылает сообщение на экран адресата, если он активен, в противном случае сообщение будет уложено в его почтовый ящик.

    3. SAML <SP> FROM:<reverse-path> <CRLF>

    Команда Send And MaiL (SAML) предполагает доставку сообщение на экран терминала адресата и занесение в его почтовый ящик. Для открытия и закрытия коммуникационного канала используются команды:

    HELO <SP> <domain> <CRLF>, где <domain> — имя запрашивающего домена. 
    QUIT <CRLF>

    Выражение <forward-path> может быть маршрутом, имеющим вид "@ONE,@TWO:VANJA@THREE", где ONE, TWO и THREE — имена ЭВМ. Это подчеркивает различие между адресом и маршрутом. Концептуально элементы из <forward-path> переносятся в <reverse-path> при пересылке сообщений от одного SMTP -сервера к другому.

    Если SMTP -сервер обнаружит, что доставка сообщения по адресу невозможна, тогда он формирует сообщение о "недоставленном письме", используя <reverse-path>. Следует также помнить, что и прямой, и обратный адреса-маршруты, вообще говоря, могут не иметь ничего общего с текстом заголовка почтового сообщения.

    При определенных условиях и ошибках в задании прямых и обратных адресов-маршрутов возможно зацикливание сообщений об этих ошибках. Чтобы заведомо избежать этого, можно выдавать команду MAIL c нулевым обратным маршрутом:

    MAIL FROM:< >

    Если вы или ваша программа не указали обратного адреса, не следует думать, что это помешает работе почтовой программы и она не будет знать, куда посылать отклики. Практически все почтовые программы позволяют произвольно модифицировать поле <reverse-path>. Это может быть удобно, если вы собираетесь в командировку, но эта возможность широко используется и спамерами.

    Поле <reverse-path> применяется почтовой программой, когда вы отвечаете на полученное сообщение с помощью утилиты Reply. Таким образом, ваш возмущенный ответ спамеру может прийти, например, к вам самому.

    Следует помнить, что обратный IP-адрес (адрес отправителя) указан в каждом пакете, посылаемом адресату!

    Некоторые другие команды, используемые в SMTP

    Команда TURN нужна для того, чтобы поменять местами функции программ, взаимодействовавших по телекоммуникационному каналу. Программа-отправитель становится получателем (после того как она выдаст команду TURN и получит отклик 250 ), а программа-получатель — отправителем. Если программа не хочет или не может поменять свою функцию, она пошлет отклик 502. Эта команда позволяет организовать диалог между отправителем и получателем в реальном масштабе времени.

    Команда RESET (RSET) прерывает текущую процедуру отправки почтового сообщения. Все буферы и таблицы очищаются, получатель должен послать отклик 250 OK.

    Команда HELP вынуждает получателя послать справочную информацию отправителю команды HELP. Команда может содержать аргумент (имя команды). Она не изменяет состояния таблиц или буферов.

    Команда NOOP не оказывает влияния на какие-либо параметры или результаты предшествующих команд, она только вынуждает получателя послать отклик 250 OK. Может использоваться для проверки работоспособности TCP-канала.

    Допустимо написание команд строчными или прописными символами, например: MAIL, Mail, mail, MAil или mAil.

    Для того, чтобы программа SMTP -сервера была работоспособна, она должна понимать следующий минимум команд: HELO, MAIL, RCPT, DATA, RSET, NOOP, QUIT.

    Предельная длина имени пользователя или домена равна 64 символам. Максимальная длина <reverse-path> или <forward-path> составляет 256 символов, включая разделители (пробелы, точки, запятые и пр.). Командная строка не должна быть длиннее 512 символов. Максимальный размер строки отклика не должен превышать 512 символов, включая его код и <CRLF>. Максимальная длина строки составляет, включая <CRLF>, 1000 символов. Предельно допустимое число адресатов равно 100, последнее полезно помнить, если вы храните этот список в файле.

    Многоцелевое расширение почты Интернет (MIME)

    Стандарт STD 11 (RFC 822) определяет протокол представления сообщений, структуру их заголовков. При этом предполагается, что текст сообщения построен исключительно из кодов US-ASCII (смотри также http://book.itep.ru/4/4/mime.htm). Набор документов MIME (Multipurpose Internet Mail Extensions; RFC-2045-49) задает формат сообщений, который предоставляет следующие возможности.

  • Передача текстовых сообщений с символьным набором, отличным от US-ASCII.
  • Передача сообщений нетекстового формата (например, звукового письма или изображения).
  • Использование комбинированных сообщений, содержащих разнородные части.
  • Размещение в заголовке информации в символьном наборе, отличном от US-ASCII.
  • Документ RFC-2045 характеризует различные заголовки, которые служат для описания структуры MIME-сообщений. RFC 2046 определяет общую структуру MIME и исходный набор типов среды. RFC 2047 описывает расширения документа RFC 822, позволяя применение в полях заголовков символьных наборов, отличных US-ASCII. RFC 2048 специфицирует различные ограничения, вводимые IANA, для процедур, сопряженных с MIME. RFC 2049 характеризует критерии соответствия требованиям MIME, содержит примеры допустимых форматов и библиографию. Новейшие усовершенствования протокола MIME (особенно в направлении безопасности) можно найти в документах: RFC-2045-49, -2110, -2156, -2184, -2231, -2387, -2425, -2480, -2557, -2634, -2912-13, -3030, -3156, -3204, -3250, -3302, -3335, -3454, -3555, -3735, -3802 -03, -3839, -3850-51, -3850-35, -4021.

    Документ RFC 822, который прослужил без малого 20 лет, регламентировал работу лишь с текстовыми сообщениями (передача аудио-, видео- или графических сообщений в нем не была предусмотрена). Но даже в случае чисто текстовых документов возникали проблемы при работе с языковыми наборами, требующими символов, которые отсутствуют в наборе US-ASCII.

    Одним из существенных ограничений традиционной электронной почты, базирующейся на RFC 821-822, является установка предельного размера строки (1000 7-битовых US-ASCII символов). Это вынуждало пользователей конвертировать текст различными методами в последовательность US-ASCII-кодов (например, процедура uuencode или преобразование в коды Base-64).

    Существенные проблемы возникали при почтовом обмене между узлами, поддерживающими протоколы RFC 822 и X.400. Протокол X.400 [X400] определяет механизм включения нетекстовых материалов в почтовые сообщения. Существующие протоколы согласования работы X.400 и RFC 822 предполагают, что X.400 осуществляет преобразование нетекстовых вставок в формат IA5Text или такие сообщения просто выбрасываются. Отправитель сообщения часто не знает о возможностях получателя, и в результате последний, получив сообщения, попросту не сможет его прочесть. Таким образом, нужен механизм согласования возможностей отправителя и получателя на начальной стадии их взаимодействия до начала передачи тела сообщения. В протоколе MIME регламентируется:

  • поле заголовка MIME-Version, которое характеризует версию протокола и позволяет почтовым агентам согласовать свои возможности и исключить конфликты с устаревшим программным обеспечением;
  • поле заголовка Content-Type, которое используется для спецификации типа среды и субтипа данных в теле сообщения, а также для описания канонической формы этих данных;
  • поле заголовка Content-Transfer-Encoding, которое может использоваться для задания типа преобразования;
  • два дополнительные поля заголовка, предусмотренные для уточнения описания данных в теле сообщения (Content-ID и Content-Description).
  • Важно заметить, что основополагающими принципами при создании MIME были совместимость с существующими стандартами и надежность работы. Для тех, кто попытается реализовать протокол MIME, определенный интерес могут представлять документы RFC 1344, RFC 1345 и RFC 1524.

    Далее все цифровые величины и октеты приводятся в десятичном представлении. Все значения типа среды, субтипы и имена параметров безразличны к регистру их написания. Значения параметров, напротив, зависимы от того, строчными или прописными буквами они записаны.

    Терм CRLF в данном описании относится к последовательности октетов, соответствующих ASCII-символам CR (десятичный код 13) и LF (десятичный код 10), которые обозначают разрыв строки.

    Выражение "символьный набор" используется в MIME для того, чтобы обозначить метод преобразования последовательности октетов в последовательность символов. Заметим, что безусловное и однозначное преобразование в обратном направлении не требуется, то есть не все символы могут быть представлены через данный символьный набор (более чем одна последовательность октетов может соответствовать одной и той же последовательности символов).

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

    Термин "символьный набор" был первоначально введен для описания прямых схем преобразования, таких, как ASCII и ISO-8859-1, для которых характерна однозначная связь символов и кодовых октетов. Многооктетные кодированные символьные наборы и методики переключения несколько осложнили ситуацию.

    Термин "сообщение" обозначает сообщение типа RFC 822, передаваемое по сети, либо сообщение, инкапсулированное в тело типа "message/rfc822" или "message/partial".

    Термин "объект" (entity) относится к полям заголовка MIME и содержимому сообщения или его части в случае, если оно составное. Спецификация таких объектов определяется исключительно MIME. Так как содержимое объекта часто называется "тело", имеет смысл говорить о теле объекта. Любой вид поля может быть представлен в заголовке объекта, но только поля, имена которых начинаются с "content-", имеют значение, связанное с протоколом MIME.

    Выражение "7-битовые данные" относится к данным, которые образуют относительно короткие строки с длиной менее 998 октетов, завершающиеся последовательностью CRLF [RFC-821]. Октеты с кодом больше чем 127 или равные нулю недопустимы. Октеты CR (десятичный код 13) и LF (десятичный код 10) могут встречаться только в виде последовательности, отмечающей конец строки.

    Выражение "8-битовые данные" относится к данным, которые образуют относительно короткие строки с длиной менее 998 октетов, завершающиеся последовательностью CRLF [RFC-821]. Но здесь разрешены октеты с десятичными значениями кодов, превышающими 127 (нулевые коды не допускаются).

    Строки в данном контексте представляют собой последовательности октетов, завершающиеся CRLF. Это согласуется с документами RFC 821 и RFC 822.

    MIME определяет ряд новых полей заголовков по сравнению с RFC 822. Они описывают содержимое MIME-объекта. Эти поля заголовков используются в двух контекстах:

  • в качестве части стандартного заголовка RFC 822;
  • в MIME-заголовке в рамках составной конструкции сообщения.
  • Ниже представлено формальное описание этих полей заголовка.

    entity-headers := [ content CRLF ] [ encoding CRLF ] [ id CRLF ] [ description CRLF ]
    *( MIME-extension-field CRLF )
    MIME-message-headers := entity-headers fields version CRLF

    Порядок полей заголовка, представленный в данном BNF-определении, не имеет никакого значения.

    MIME-part-headers := entity-headers [ fields ]

    Любое поле, не начинающееся с "content-", не может иметь какого-либо значения и может игнорироваться.

    Порядок полей заголовка, представленный в данном BNF-определении, не имеет никакого значения.

    Так как документ RFC 822 был опубликован в 1982 году, там имелся только один формат для сообщений, передаваемых по каналам Интернет, и по этой причине не было необходимости декларировать тип такого стандарта. MIME является независимым дополнением документа RFC 822. Хотя протокол MIME строился так, чтобы обеспечить совместимость с RFC 822, бывают обстоятельства, когда почтовому агенту желательно выяснить, составлено ли сообщение с учетом нового стандарта. Поле заголовка "MIME-Version" служит как раз для того, чтобы можно было определить, какому стандарту соответствует тело сообщения. Сообщения, соответствующие MIME обязаны содержать такое поле заголовка со следующим текстом:

    MIME-Version: 1.0

    Присутствие этого поля заголовка означает, что сообщение подготовлено согласно требованиям MIME. Так как существует возможность того, что в будущем формат документов может быть изменен, формальное BNF-представление поля MIME-Version следует записать следующим образом:

    version := "MIME-Version" ":" 1*DIGIT "." 1*DIGIT

    Таким образом, будущие спецификаторы формата, которые могут заменить версию 1.0, ограничены двумя цифровыми полями, разделенными точкой. Если сообщение получено со значением поля MIME-version, отличным от "1.0", оно может не соответствовать данному описанию.

    Заметим, что поле заголовка MIME-Version должно располагаться в самом начале сообщения. При составном сообщении не требуется, чтобы каждая из частей начиналась с поля версии. Это необходимо лишь в случае, когда заголовки встроенных сообщений типа "message/rfc822" или "message/partial" объявляют о совместимости со стандартом MIME.

    Для некоторых приложений согласование версий должно проводиться независимо. Некоторые форматы (такие, как application/postscript) имеют внутреннюю систему нумерации версий для каждого типа среды. Там, где выполняется такое соглашение, MIME не предпринимает попыток подменить эту систему. Там, где такого соглашения нет, тип среды MIME может использовать параметр version в поле типа содержимого. При проверке значений MIME-Version любые строки комментария RFC 822 должны игнорироваться. В частности, следующие четыре записи поля

    MIME-Version эквивалентны.
    MIME-Version: 1.0
    MIME-Version: 1.0 (produced by MetaSend Vx.x)
    MIME-Version: (produced by MetaSend Vx.x) 1.0
    MIME-Version: 1.(produced by MetaSend Vx.x)0

    В отсутствии поля MIME-Version, принимающий почтовый агент (следующий стандарту MIME или нет) может опционно интерпретировать сообщения согласно локальным соглашениям.

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

    Поле заголовка Content-Type

    Задачей поля Content-Type является описание информации, содержащейся в теле сообщения. Этого описания должно быть достаточно, чтобы принимающий агент пользователя был способен воспринять и отобразить полученные данные. Значение этого поля называется типом среды.

    Введение поля тип среды (Content-Type) решило не только проблемы почты, оно открыло возможности мультимедийного отображения в HTTP и других приложениях.

    Поле заголовка Content-Type было первым определенным в документе RFC-1049. В RFC-1049 использовался более простой и менее мощный синтаксис, который, впрочем, вполне согласуется с регламентациями MIME.

    Поле заголовка Content-Type специфицирует природу данных в теле объекта, сообщая тип среды и идентификаторы субтипа, а также предоставляя вспомогательную информацию, которая может требоваться для определенного типа среды. После типа среды и имен субтипов может следовать набор параметров, который описывается в нотации атрибут = значение. Порядок параметров не имеет значения. Тип среды верхнего уровня используется для декларирования общего типа данных, в то время как субтип определяет специфический формат информации. Таким образом, типа среды image/xyz достаточно, чтобы сообщить агенту пользователя, что данные представляют собой изображение, даже если агент пользователя не имеет представления о формате изображения xyz. Такая информация может применяться, например, для того, чтобы решить, следует ли показывать пользователю исходные данные нераспознанного субтипа. Такая операция разумна для нераспознанного субтипа текста, но бессмысленна для изображения или звука. По этой причине зарегистрированные субтипы текста, изображения, аудио и видео не должны содержать вложенной информации другого типа. Такой составной формат должен быть представлен с использованием multipart или application типов.

    Параметры являются модификаторами субтипа среды и по этой причине не могут существенно влиять на природу содержимого. Набор значимых параметров зависит от типа и субтипа среды. Большинство параметров связано с одним специфическим субтипом. Однако тип среды верхнего уровня может определить параметры, которые применимы к любому субтипу данного типа. Параметры могут быть необходимы для определенных типов и субтипов, могут они быть и опционными. Реализации MIME должны игнорировать любые параметры, если их имена не распознаны.

    Например, параметр charset применим к любому субтипу текста, в то время как параметр boundary необходим для любого субтипа типа среды multipart. Не существует параметров, применимых для всех типов среды.

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

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

    В нотации BNF значение поля заголовка Content-Type определяется следующим образом:

    content := "Content-Type" ":" type "/" subtype *(";" parameter) Распознавание типа и субтипа среды всегда не зависит от регистра, в котором они напечатаны.
    type := discrete-type / composite-type
    discrete-type := "text" / "image" / "audio" / "video" / "application" / extension-token
    composite-type := "message" / "multipart" / extension-token
    extension-token := ietf-token / x-token
    ietf-token := <Лексема расширения, определенная стандартом RFC и зарегистрированная IANA.>
    x-token := <Два символа "X-" или "x-", за которыми следует без пробела лексема (token)>
    subtype := extension-token / iana-token
    iana-token := <Общедоступная лексема расширения. Лексемы этой формы должны быть зарегистрированы IANA, как это указано в RFC 2048.>
    parameter := attribute "=" value
    attribute := token Распознавание атрибутов не зависит от регистра, в котором они напечатаны.
    value := token / quoted-string
    token := 1*
    tspecials := "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / "\" / <"> "/" / "[" / "]" / "?" / "="

    Заметим, что определение tspecials совпадает с определением specials в RFC 822 с добавлением трех символов "/", "?" и "=" и удалением "." (точка).

    Заметим также, что спецификация субтипа является обязательной (MANDATORY) — она не может быть удалена из поля заголовка Content-Type. Не существует субтипов по умолчанию. Тип, субтип и имена параметров не зависят от регистра, в которых они напечатаны. Например, TEXT, Text и TeXt являются эквивалентными типами среды верхнего уровня. Значения же параметров в норме чувствительны к регистру, в котором они напечатаны, но иногда интерпретируются без учета регистра — в зависимости от приложения. (Например, границы типа multipart являются чувствительными к регистру, а параметр access-type для сообщения message/External-body не чувствителен).

    Обратите внимание, что значение строки в кавычках не включает в себя сами кавычки. В полях заголовка в соответствии с RFC 822 допускаются комментарии. Таким образом, две приведенные ниже формы являются эквивалентными.

    Content-type: text/plain; charset=us-ascii (Plain text)
    Content-type: text/plain; charset="us-ascii".

    Предполагается, что имена субтипов при их применении не вызовут конфликтов. Так, недопустимо, чтобы в различных приложениях "Content-Type: application/foobar" означало различные вещи. Существует два приемлемых механизма определения новых субтипов среды.

  • Частные значения (начинающиеся с X-) могут быть определены для двух взаимодействующих агентов без официальной регистрации или стандартизации.
  • Новые стандартные значения должны регистрироваться IANA, как это описано в RFC 2048.
  • Сообщения по умолчанию без MIME-заголовка Content-Type, согласно протоколу, должны содержать простой текст с символьным набором ASCII, который может быть специфицирован явно.

    Content-type: text/plain; charset=us-ascii

    Это значение подразумевается, если не специфицировано поле заголовка Content-Type. Рекомендуется, чтобы это значение по умолчанию использовалось в случае, когда встретилась нераспознанное значение поля заголовка Content-Type. В присутствии поля заголовка MIME-Version и отсутствии поля Content-Type, принимающий агент пользователя может также предположить, что отправитель предлагает простой текст в ASCII-кодировке. Простой ASCII-текст может предполагаться в отсутствии MIME-Version или в присутствии синтаксически некорректного поля заголовка Content-Type, хотя это может и не совпадать с намерениями отправителя.

    Многие типы среды, которые могут передаваться посредством электронной почты, представляются в своем естественном формате, таком, как 8-битовые символы или двоичные данные. Такие данные не могут быть переданы посредством некоторых транспортных протоколов. Например, RFC 821 ( SMTP ) ограничивает почтовые сообщения 7-битовым символьным набором ASCII со строками, короче 1000 символов, включая строчные разделители CRLF.

    Таким образом, необходимо определить стандартный механизм кодировки таких данных в 7-битный формат с короткими строками. В MIME для этой цели используется поле заголовка "Content-Transfer-Encoding".

    Значения полей Content-Transfer-Encoding представляют собой лексему, характеризующую тип кодирования, как это описано ниже.

    Encoding := "Content-Transfer-Encoding" ":" mechanism
    mechanism := "7bit" / "8bit" / "binary" / "quoted-printable" / " base64 " / ietf-token / x-token

    Эти значения не чувствительны к регистру, в котором напечатаны. Записи Base64, BASE64 и bAsE64 эквивалентны. Тип кодировки 7BIT требует, чтобы тело уже имело 7-битовое представление, пригодное для передачи. Это значение по умолчанию означает, что в отсутствии поля Transfer-Encoding предполагается "Content-Transfer-Encoding: 7BIT".

    Лексема Content-Transfer-Encoding предоставляет два вида информации. Она специфицирует, какому виду кодового преобразования подвергнуто тело сообщения и, следовательно, какая процедура декодирования должна использоваться при восстановлении исходного вида сообщения.

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

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

    Значения Content-Transfer-Encoding 7bit, 8bit и binary означают, что никакого преобразования не произведено. Они указывают на тип тела сообщения, и позволяют предполагать, какое кодирование может потребоваться при передаче данных.

    Кодирование в последовательность печатных символов или в кодовую последовательность base64 предполагает преобразование из произвольного исходного формата в представление 7bit, что позволяет передачу через любые транспортные среды.

    Всегда должна использоваться корректная метка Content-Transfer-Encoding. Пометка данных, преобразованных программой UUENCODE и содержащих 8-битовые символы, как 7bit не допустима — такие данные должны помечаться только как binary.

    При прочих равных условиях предпочтительным представлением является последовательность печатных символов или кодов base64.

    Передача почтовых сообщений, закодированных программой uuencode, описана в документе RFC 1652. Но следует иметь в виду, что ни при каких обстоятельствах Content-Transfer-Encoding binary нельзя считать приемлемым для e-mail. Однако когда используется MIME, двоичное тело сообщения может быть помечено как таковое.

    Программисты могут, если необходимо, определить частные значения Content-Transfer-Encoding. При этом должны использоваться x-лексемы, которые представляют собой имена с префиксом X-, что указывает на нестандартный статус, например, "Content-Transfer-Encoding: x-my-newencoding". Дополнительные стандартизованные значения Content-Transfer-Encoding должны быть специфицированы в официальных документах RFC.

    В отличие от типов среды и субтипов, формирование новых значений Content-Transfer-Encoding категорически не рекомендуется, так как может привести к полному выходу из строя системы.

    Если поле заголовка Content-Transfer-Encoding появляется как часть заголовка сообщения, оно относится ко всему телу сообщения. Если поле заголовка Content-Transfer-Encoding появляется в качестве части заголовка объекта, то зоной его действия будет тело этого объекта. Если объект имеет тип multipart, то Content-Transfer-Encoding не может иметь значение 7bit, 8bit или binary. Следует заметить, что большинство типов среды определены в терминах октетов, а не бит, поэтому описываемые механизмы относятся к кодировке произвольных потоков октетов, а не бит. Если необходимо закодировать битовую последовательность, она должна быть преобразована в последовательность октетов с сетевой последовательностью бит (big-endian), в которой более ранние биты становятся старшими битами октетов. Битовые потоки, длина которых не кратна 8, должны быть дополнены нулями.

    Механизмы кодировки, определенные здесь, осуществляют преобразование любых данных в ASCII. Таким образом, предположим, например, что объект имеет следующие поля заголовка:

    Content-Type: text/plain; charset=ISO-8859-1
    Content-transfer-encoding: base64

    Это должно интерпретироваться так, что тело имеет кодировку base64, а исходные данные имели представление в ISO-8859-1.

    Определенные значения Content-Transfer-Encoding могут использоваться только с определенными типами среды. В частности, категорически запрещено применять любую кодировку отличную от 7bit, 8bit или binary с любым составным типом среды, т.e. включающим и другие поля Content-Type. В настоящее время разрешены составные типы среды multipart и message. Все кодировки, допустимые для тел типа multipart или message должны использоваться на самом внутреннем уровне.

    Следует также заметить, что по определению, если составной объект имеет значение transfer-encoding равное 7bit, но один из составляющих объектов имеет менее регламентирующее значение, например, 8bit, тогда либо внешняя метка 7bit является ошибкой, либо внутренняя метка 8bit устанавливает слишком высокое требование к транспортной системе (следовало проставить 7bit).

    Хотя запрет использования content-transfer-encodings для составного тела может показаться чрезмерно регламентирующим, следует избегать вложенных кодирований, в которых данные подвергаются последовательно обработке несколькими алгоритмами. Вложенные кодирования заметно повышают сложность агентов пользователя. Помимо очевидных проблем эффективности при множественном кодировании, они могут затемнить базовую структуру сообщения. В частности, они могут подразумевать, что необходимо несколько операций декодирования, чтобы определить, какие типы тел содержит сообщение. Запрет вложенных кодировок может осложнить работу некоторых почтовых шлюзов, но это представляется меньшей бедой, чем осложнение жизни агентов пользователя при вложенном кодировании.

    Любой объект с нераспознанным значением Content-Transfer-Encoding должен рассматриваться, как если бы он имел код Content-type "application/octet-stream", вне зависимости от того, что утверждается полем заголовка Content-Type.

    Может показаться, что Content-Transfer-Encoding может быть выяснено из характеристик среды, для которой нужно осуществить кодирование, или, по крайней мере, что определенное Content-Transfer-Encodings может быть предназначено для использования с определенными типами среды. Есть несколько причин, почему это не так. Во-первых, существуют различные типы транспорта, используемые для почты, некоторые кодирования могут подходить для определенных комбинаций типов среды и транспорта, но быть непригодными для других. Например, при 8-битовой передаче, при определенном символьном наборе для текста не потребуется никакого кодирования, в то время как такое кодирование очевидно необходимо для 7-битового SMTP.

    Во-вторых, определенные типы среды могут требовать различного транспортного кодирования при разных обстоятельствах. Например, многие PostScript-тела могут целиком состоять из коротких строк 7-битовых кодов и, следовательно, совсем не требуют кодирования. Другие тела PostScript (в особенности те, что используют механизм двоичного кодирования уровня 2 PostScript) могут быть представлены с использованием двоичного транспортного кодирования. Наконец, так как поле Content-Type ориентировано на то, чтобы предоставлять открытые механизмы спецификации, строгие ассоциации типов среды и кодирования эффективно соединяют спецификацию прикладного протокола с определенным транспортом нижнего уровня. Это нежелательно, так как разработчики типа среды не должны заботиться обо всех видах транспорта и их особенностях.

    Кодирование с использованием закавыченных строк печатных символов и кодов base64 устроено так, чтобы позволить взаимные преобразования. Единственная проблема, которая здесь возникает, — это обработка принудительных разрывов строк для закавыченных последовательностей печатных символов. При преобразовании закавыченных строк в коды base64 принудительные разрывы строк отображаются последовательностями CRLF. Аналогично, последовательность CRLF в канонической форме данных, полученной после декодирования из base64, должна преобразоваться в принудительный разрыв строки в случае представления текста в виде закавыченной строки печатных символов. Каноническая модель кодирования представлена в документе RFC 2049.

    Кодирование Quoted-Printable имеет целью представление данных, состоящих по большей части из октетов, которые соответствуют печатным символам ASCII-набора. Оно преобразует данные таким образом, что результирующие октеты не будут видоизменены при транспортировке почты. Если преобразуемые данные представляют собой ASCII-текст, то после кодирования они сохранят читабельность. Тело, которое целиком состоит из ASCII-кодов, может быть также представлено в виде закавыченной строки печатных символов. При этом сохраняется целостность текста в процессе прохождении через шлюз, который осуществляет трансляцию символов и/или обработку разрывов строк. При таком кодировании октеты должны определяться согласно изложенным ниже правилам.

  • 8-битовое представление. Любой октет (за исключением CR или LF, которые являются частью последовательности разрыва строки CRLF) канонического (стандартного) формата данных может быть представлен с помощью символа "=", за которым следуют две шестнадцатеричные цифры, характеризующие значение октета. Для этих целей используются цифры шестнадцатеричного алфавита "0123456789ABCDEF". Должны применяться прописные буквы; использование строчных букв недопустимо. Так, например, десятичное значение 12 (ASCII FF) может быть представлено как "=0C", а десятичное значение 61 (ASCII символ знака равенства) представляется с помощью "=3D". Это правило должно выполняться всегда за исключением случаев, когда правила допускают альтернативное кодирование
  • Литеральное представление. Октеты с десятичными кодами в интервале 33 - 60 включительно и 62 - 126, включительно могут представляться ASCII-символами, которые соответствуют этим октетам (с "!" до "<" и с ">" до "~" соответственно)
  • Пробелы. Октеты со значениями кодов 9 и 32 могут отображаться с помощью ASCII-символов TAB (HT) и пробел, соответственно, но не должны использоваться в конце строки. За любым символом TAB (HT) или пробел в кодируемой строке должен следовать печатный символ. В частности, символ "=" в конце каждой кодируемой строки, обозначающий "мягкий" разрыв строки (смотри правило #5), может следовать за одним или более символами TAB(HT) или SP. Отсюда следует, что октет, равный 9 или 32, появляющийся в конце кодируемой строки должен быть представлен в форме, указанной правилом #1. Это правило необходимо, так как некоторые MTA (Message Transport Agents, программы, которые передают сообщения от одного пользователя другому) дополняют строки пробелами, а другие удаляют пробелы ( HT или SP ) в конце строки. Следовательно, при декодировании тела, представленного в форме закавыченных печатных последовательностей, любые HT или SP должны быть удалены
  • Разрывы строк. Разрыв строки в теле текста, представленный последовательностью CRLF в канонической форме, для закавыченной печатной строки отмечается CRLF. Последовательности типа "=0D", "=0A", "=0A=0D" и "=0D=0A" появляются в нетекстовых данных, представленных в виде закавыченных строк печатных символов. Заметим, что многие реализации могут выбрать для кодирования непосредственно локальное представление различных типов содержимого, а не преобразование в каноническую форму, кодирование и только затем преобразование в локальное представление. В частности, такая техника может быть применена к простому тексту в системах, которые используют для межстрочных разрывов последовательности, отличные от CRLF. Такая оптимизация конкретной программной реализации вполне допустима, но только когда комбинированный шаг канонизация-кодирование эквивалентен выполнению всех трех шагов отдельно
  • Мягкие разрывы строки. Кодирование с помощью закавыченных строк печатных символов требует, чтобы строки содержали не более 76 символов. Если нужно закодировать более длинные строки, вводятся мягкие разрывы строк. Символ равенства в конце строки как раз и обозначает такой разрыв
  • Пусть имеется следующий текст, который надо преобразовать:

    Now’s the time for all folk to come to the aid of their country.

    Он может быть представлен следующим образом с помощью закавыченных строк печатных символов:

    Now’s the time =
    for all folk to come=
    to the aid of their country.

    Это предоставляет механизм, с помощью которого длинные строки преобразуются таким образом, как они должны быть запомнены агентом пользователя. Ограничение в 76 символов не учитывает завершающие строку CRLF, но содержит все прочие символы, включая знаки равенства. Так как символ дефис ("-") может отображаться в закавыченных строках самим собой, нужно следить за тем, чтобы при инкапсуляции закодированного фрагмента в одном или более составных объектов пограничные разделители не появились в закодированном теле. Хорошей стратегией является выбор в качестве границы последовательности символов "=_", которая не может встретиться в закавыченной строке печатных символов.

    Преобразование в закавыченные строки печатных символов представляет собой компромисс между читабельностью и надежностью при транспортировке. Тела, закодированные с помощью закавыченных строк печатных символов, пропускаются без проблем большинством почтовых шлюзов. Проблемы могут возникать только со шлюзами, осуществляющими трансляцию в коды EBCDIC. Кодирование с помощью base64 обеспечивает более высокий уровень надежности. Методом получения разумно высокой надежности транспортировки через шлюзы EBCDIC является представление символов !"#$@[\]^'{|}~ согласно правилу #1.

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

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

  • Символ "=", за которым следует две шестнадцатеричные цифры, одна или обе из которых являются строчными символами (abcdef), является нелегальным. Надежные реализации могут распознавать их как прописные буквы
  • Символ "=", за которым следует символ, не являющийся ни шестнадцатеричной цифрой (включая abcdef), ни CR из комбинации CRLF, является нелегальным. Это не может стать частью ASCII-текста, включенного в сообщение, без преобразования в закавыченную последовательность печатных кодов. Разумным решением для надежной реализации может быть: включить символ "=" и следующие за ним коды в декодированную последовательность без какого-либо преобразования и, если возможно, дать сигнал агенту пользователя, что декодирование в этом месте оказалось невозможным
  • Символ "=" не может быть последним или предпоследним символом в кодируемом объекте. Решением проблемы можно считать способ, предложенный в пункте (2)
  • Управляющие символы, отличные от TAB или CR и LF (в качестве части CRLF), не должны присутствовать. То же справедливо для октетов с десятичными значениями больше, чем 126. Если такие коды обнаруживаются в приходящих закавыченных последовательностях печатных символов, корректная реализация может исключить их из декодированных данных и предупредить пользователя о том, что обнаружен нелегальный символ
  • Закодированные строки не должны быть длиннее 76 символов, не считая завершающие CRLF. Если во входном потоке обнаружены более длинные строки, надежная реализация может их декодировать, но должна предупредить пользователя об ошибке
  • Если двоичные данные закодированы в виде закавыченных последовательностей печатных символов, следует позаботиться о том, чтобы символы CR и LF были представлены в виде "=0D" и "=0A", соответственно. В частности, последовательность CRLF в двоичных данных должна кодироваться как "=0D=0A". В противном случае, если CRLF была бы представлена как жесткий разрыв строки, она может декодироваться некорректно на платформах с различными способами обработки разрывов строки. С формальной точки зрения, закавыченные последовательности печатных символов подчиняются следующей грамматике.

    quoted-printable := qp-line *(CRLF qp-line)
    qp-line := *(qp-segment transportpadding CRLF) qp-part transport-padding
    qp-part := qp-section ; Максимальна длина 76 символов
    qp-segment := qp-section *(SPACE / TAB) "=" ; Максимальна длина 76 символов
    qp-section := [*(ptext / SPACE / TAB) ptext]
    ptext := hex-octet / safe-char
    safe-char := <любой октет с десятичным кодом от 33 до 60 включительно, и от 62 до 126> ; Символы, не включенные в список "mail-safe" RFC 2049, не рекомендуются к применению
    hex-octet := "=" 2(DIGIT / "A" / "B" / "C" / "D" / "E" / "F") ; Октет должен использоваться для символов с кодами > 127, =, SP или TAB в конце строк, и рекомендуется для любого символа не указанного в списке "mailsafe" документа RFC 2049
    transport-padding := *LWSP-char ; Составители не должны генерировать заполнители ненулевой длины, но получатели должны быть способны обрабатывать заполнители, добавленные при транспортировке

    Добавление LWSP между элементами, показанное в данном BNF-представлении, не допустимо, так как данное BNF не специфицирует структурированных полей заголовка.

    Транспортное кодирование на основе Base64 создано для представления произвольной последовательности октетов в форме, которая не обязательно должна быть приемлемой для прочтения человеком. Алгоритмы кодирования и декодирования просты. Это кодирование сходно с тем, что используется в почтовом приложении PEM (Privacy Enhanced Mail), как это определено в RFC-1421.

    Здесь используется 65-символьный субнабор ASCII, для каждого печатного символа выделено по 6 бит. Дополнительный 65-ый символ "=", используется для обозначения специальных функций обработки.

    Этот субнабор имеет важное свойство, которое заключается в том, что он представляется идентично во всех версиях ISO 646, включая US-ASCII, и все символы субнабора имеют аналоги во всех версиях EBCDIC. Другие популярные кодировки, такие, как применяемые утилитой uuencode, Macintosh binhex 4.0 [RFC-1741] и base85, специфицированная как часть уровня 2 PostScript, имеют отличающиеся свойства и, следовательно, не выполняют условий переносимости, которым должно удовлетворять двоичное транспортное кодирование электронной почты.

    При кодировании входные 24-битовые группы преобразуются в 4 символа. Входная группа формируется из трех 8-битовых кодов и обрабатывается слева направо. Эти 24 бита рассматриваются в дальнейшем как 4 6-битовые группы, каждая из которых транслируется в одно число из алфавита base64. Когда кодируется битовый поток с использованием base64, предполагается, что старший бит передается первым. То есть, первый бит потока станет старшим битом первого 8-битового байта, а 8-ой бит станет его последним битом.

    Каждая 6-битовая группа используется как индекс массива из 64 печатных символов. Символ, на который указывает индекс, берется из массива и помещается в выходной поток. Эти символы представлены в таблице 1.10, из их перечня исключены коды, имеющие особое значение для протокола SMTP (например, ".", CR, LF), а также разграничитель секций составного сообщения "-" (RFC-2046).

    Коды Base64
    Код символа (6 бит) ASCII символ Код символа (6 бит) ASCII символ Код символа (6 бит) ASCII символ Код символа (6 бит) ASCII символ
    0 A 10 Q 20 g 30 W
    1 B 11 R 21 h 31 X
    2 C 12 S 22 i 32 Y
    3 D 13 T 23 j 33 Z
    4 E 14 U 24 k 34 0
    5 F 15 V 25 l 35 1
    6 G 16 W 26 m 36 2
    7 H 17 X 27 n 37 3
    8 I 18 Y 28 o 38 4
    9 J 19 Z 29 p 39 5
    A K 1A a 2A q 3A 6
    B L 1B b 2B r 3B 7
    C M 1C c 2C s 3C 8
    D N 1D d 2D t 3D 9
    E O 1E e 2E u 3E +
    F P 1F f 2F v 3F /

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

    Если число бит в группе меньше 24, используется специальная обработка. Неполная битовая группа дополняется нулями справа до 24. Заполнение в конце информационной группы осуществляется с использованием символа "=". Так как последовательность кодов base64 представляет собой поток октетов, возможны следующие случаи:

  • последний блок кодируемых данных кратен 24 битам; здесь, завершающий выходной блок будет содержать в себе 4 символа и никакого заполнителя;
  • завершающий блок кодируемых данных содержит ровно 8 бит; здесь, оконечный выходной блок будет содержать два символа, за которыми будут следовать два символа заполнителя; или
  • последний блок кодируемой информации содержит ровно 16 бит; здесь, оконечный блок на выходе будет иметь три символа плюс один символ заполнителя "=".
  • Так как "=" используется для дополнения, его наличие указывает на то, что мы достигли конца массива данных. Такая уверенность невозможна, когда число переданных октетов кратно трем и нет ни одного символа "=". Любые символы, не входящие в алфавит base64, должны игнорироваться.

    Следует позаботиться о том, чтобы использовались корректные октеты в качестве разделителей строк при работе с base64. В частности, разрывы строк должны быть преобразованы в последовательности CRLF до выполнения кодирования base64.

    При создании агента пользователя высокого уровня, может быть желательно, разрешить одному телу сообщения ссылаться на другое. Тела могут быть помечены с помощью поля заголовка "Content-ID", которое синтаксически идентично полю "Message-ID":

    id := "Content-ID" ":" msg-id

    Подобно значениям Message-ID, значения Content-ID должны генерироваться уникальными.

    Значение Content-ID может использоваться для идентификации MIME-объектов в нескольких контекстах, в частности, для кэширования данных с доступом через механизм message/external-body. Хотя заголовок Content-ID является обычно опционным, его применение является обязательным в приложениях, которые генерируют данные опционного типа среды MIME message/external-body. По этой причине каждый объект message/external-body должен иметь поле Content-ID, чтобы разрешить кэширование таких данных.

    Часто оказывается желательным установить соответствие между описательной информацией и данным телом. Например, может быть полезным пометить тело типа image как изображение старта космического корабля. Такой текст может быть помещен в поле заголовка Content-Description. Это поле всегда является опционным.

    description := "Content-Description" ":" *text

    Предполагается, что описание дается с использованием символьного набора US-ASCII, хотя механизм, специфицированный в RFC 2047, может быть использован и для значений Content-Description, не соответствующих стандарту US-ASCII.

    Будущие документы могут содержать дополнительные поля заголовков MIME для различных целей. Любое новое поле заголовка, которое описывает содержимое сообщения, должно начинаться со строки "Content-", чтобы такие поля можно было с гарантией отличить от обычных полей заголовков сообщения, следующих стандарту RFC-822. MIME-extension-field := <Любое поле заголовка RFC-822, которое начинается со строки "Content-">

    Используя поля заголовка MIME-Version, Content-Type и Content-Transfer-Encoding, можно подключить стандартным образом произвольные типы данных и добиться совместимости с требованиями документа RFC-822. Никакие ограничения, введенные документами RFC-821 или RFC-822, не нарушаются, — были приняты меры, чтобы исключить проблемы, связанные с дополнительными ограничениями из-за свойств некоторых механизмов пересылки почты по Интернет (см. RFC-2049).

    Типы среды

    Поле Content-Type используется для спецификации природы информации в теле MIME-объекта путем присвоения идентификаторов типа и субтипа среды и предоставления дополнительной информации, которая может быть необходима для данной разновидности среды. За именами типа и субтипа среды в поле следует набор параметров, заданных в нотации атрибут/значение. Порядок следования параметров не существенен.

    Тип среды верхнего уровня используется для декларации общего типа данных, в то время как субтип определяет специфический формат данного типа информации. Таким образом, тип среды "image/xyz" говорит агенту пользователя, что данные характеризуют изображение и имеют формат xyz. Такая информация может применяться для того, чтобы решить, отображать ли пользователю исходные данные нераспознанного субтипа. Эти действия могут быть разумными для нераспознанного фрагмента субтипа text, но не для субтипов image или audio. По этой причине зарегистрированные субтипы text, image, audio и video не должны содержать встроенных фрагментов другого типа. Такие составные форматы должны использовать типы multipart или application.

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

    Поле заголовка Content-Type и механизм типа среды спроектированы так, чтобы сохранить масштабируемость, обеспечивая постепенный рост со временем числа пар тип/субтип и сопряженных с ними параметров. Транспортное кодирование MIME, а также типы доступа message/externalbody со временем могут обрести новые значения. Чтобы гарантировать, что такие значения разработаны и специфицированы корректно, в MIME предусмотрен процесс регистрации, который использует IANA (Internet Assigned Numbers Authority) в качестве главного органа, контролирующего данный процесс (см. RFC 2048). В данном разделе описаны семь стандартизованных типов среды верхнего уровня.

    Составляющие определения типа среды верхнего уровня

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

  • text — текстовая информация. Субтип plain, в частности, указывает, что текст не содержит команд форматирования или каких-либо директив. Такой текст нужно отображать как он есть. Не нужно никакого специального программного обеспечения для восприятия такого текста, помимо поддержки указанного символьного набора. Другие субтипы должны использоваться для форматированного текста ( enriched ) в форме, где прикладное программное обеспечение может улучшить представление текста. Но такая программа не нужна для общей обработки содержимого. Возможные субтипы text включают в себя любые форматы, которые могут быть прочитаны без обращения к программе, которая понимает этот формат. В частности, форматы, которые используют встроенное двоичное форматирование, не считаются непосредственно читаемыми. Очень простой и портативный субтип, richtext, был определен в документе RFC 1341, и позднее пересмотрен в RFC 1896 под именем enriched.
  • image — графические данные. Image требует устройства отображения (такого, как графический дисплей, графический принтер или факс) для того, чтобы просмотреть информацию. Первичный субтип определен для широко используемого формата изображения JPEG. Субтипы определены для двух широко используемых форматов изображения — jpeg и gif
  • audio — звуковые данные. Audio требует выходного устройства (такого, как громкоговоритель или телефон) для воспроизведения содержимого
  • video — видеоданные. Vidео требует выходного устройства, способного воспроизвести движущееся изображение. В данном документе определен первичный субтип mpeg
  • application — некоторые другие типы данных, обычно не интерпретированные двоичные данные или информация, которая должна быть обработана приложением. Субтип octet-stream следует использовать в случае не интерпретируемых двоичных данных, здесь простейшей рекомендацией может служить передача этой информации в файл пользователя. Субтип PostScript определен для транспортировки PostScript текстов
  • Существует два составных типа среды высшего уровня.

  • multipart — данные, состоящие из нескольких объектов с различными типами данных. Определены четыре первичных субтипов, включая: базовый субтип mixed, специфицирующий смешанный набор частей; alternative — для представления одних и тех же данных в различных форматах; parallel — для частей, которые должны представляться одновременно, и digest — для составных объектов, в которых каждая часть имеет тип по умолчанию "message/rfc822"
  • message — инкапсулированное сообщение. Тело типа среды message составляет часть или весь объект сообщения некоторого типа. Такие объекты могут содержать в свою очередь другие объекты. Субтип rfc822 используется, когда инкапсулированное содержимое само является сообщением RFC 822. Субтип partial определен для частичных сообщений вида RFC 822, чтобы разрешить по-фрагментную передачу слишком длинных тел сообщения. Другой субтип external-body определен для спецификации протяженных тел с помощью ссылок на внешние источники информации
  • Пять из семи базовых значений типа среды относятся к дискретным телам. Содержимое этих типов должно обрабатываться с использование механизмов за пределами MIME, они непрозрачны для MIME-процессоров.

    Тип среды Text

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

    Помимо чистого текста существует много форматов, называемых "форматированный" текст (rich text). Интересной характеристикой многих таких представлений является то, что они читабельны даже без программы, которая его интерпретирует. Полезно затем отличать их на верхнем уровне от таких нечитабельных данных, как изображения, звук или текст, представленный в нечитаемом виде. В отсутствии подходящей интерпретирующей программы разумно показать субтипы text пользователю, в то время как это неразумно для большей части нетекстовых данных. Такие форматированные текстовые данные должны представляться с помощью субтипов text.

    Каноническая форма любого субтипа MIME text должна всегда оформлять разрыв строки с помощью последовательности CRLF. Аналогично, любое появление CRLF в тексте MIME должно означать разрыв строки. Использование CR и LF по отдельности вне обозначения разрыва строки запрещено. Это правило работает вне зависимости от используемого символьного набора.

    Правильная интерпретация разрывов строк при отображении текста зависит от типа среды. Следует учитывать, что одно и то же оформление разрывов строк при отображении text/plain может восприниматься корректно, в то время как для других субтипов text, например, text/enriched [RFC-1896], аналогичные разрывы строк будут восприниматься как неверные. Нет необходимости в добавлении каких-либо разрывов строк при отображении text/plain, в то время как отображение text/enriched требует введения соответствующего оформления разрывов строк.

    Некоторые протоколы определяют максимальную длину строки. Например, SMTP [RFC-821] допускает максимум 998 октетов перед последовательностью CRLF. Для того, чтобы реализовать транспортировку посредством такого протокола, данные, содержащие слишком длинные сегменты без CRLF, должны быть закодированы с применением соответствующего content-transfer-encoding.

    Критическим параметром, который может быть специфицирован в поле Content-Type для данных text/plain, является символьный набор. Он специфицируется параметром charset, например, как:

    Content-type: text/plain; charset=iso-8859-1

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

    Для других субтипов text семантика параметра charset должна быть определена аналогично параметрам, заданным для text/plain, т.e., тело состоит полностью из символов данного набора. В частности, авторы будущих определений субтипов text должны уделить особое внимание мультиоктетным символьным наборам. Параметр charset для субтипов text дает имя символьному набору, как это определено в RFC 2045.

    Заметим, что специфицированный символьный набор включает в себя 8-битовые коды и эти символы используются в теле и в поле заголовка Content-Transfer-Encoding, а для передачи данных с помощью транспортных протоколов (например, SMTP ) необходима соответствующая кодировка, такая, как [RFC-821].

    Значение символьного набора по умолчанию, равное US-ASCII, являлось причиной многих неурядиц в прошлом. Чтобы исключить какие-либо неопределенности в будущем, настоятельно рекомендуется новым агентам пользователя задавать символьный набор в явном виде в качестве параметра типа среды в поле заголовка Content-Type. US-ASCII не указывает на произвольный 7-битовый символьный набор, а говорит о том, что все октеты в теле должны интерпретироваться как символы US-ASCII. Национальные и ориентированные на приложения версии ISO 646 [ISO-646] обычно не идентичны US-ASCII, и их непосредственное применение в электронной почте может вызвать проблемы. Имя символьного набора US-ASCII относится к кодам, заданным в документе ANSI X3.4-1986 [US-ASCII].

    Полный набор символов US-ASCII представлен в ANSI X3.4-1986. Заметим, что управляющие символы, включая DEL (0-31, 127), не имеют определенного значения, исключение составляет комбинация CRLF (US-ASCII значения 13 и 10), обозначающая разрыв строки. Два символа имеют широко используемые функции: это FF (12) — продолжить последующий текст с начала новой страницы, и TAB или HT (9), часто (хотя и не всегда) означющий "переместить курсор в следующую колонку". Колонки нумеруются, начиная с нуля, и их позиции кратны 8. Помимо этих случаев, любые управляющие символы или DEL в теле объекта могут появиться при следующих условиях.

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

  • US-ASCII — как это определено в ANSI X3.4-1986 [US-ASCII].
  • ISO-8859-X — где "X" следует замещать, как это требуется для частей ISO-8859 [ISO-8859]. Допустимыми подменами "X" являются цифры от 1 до 10.
  • Символы с кодами в диапазоне 128-159 не имеют стандартизованных значений в рамках ISO-8859-X. Символы с кодами меньше 128 в ISO-8859-X имеют те же значения, что и в US-ASCII.

    Значения символьных наборов ISO-8859-6 и ISO-8859-8 специфицируют применение визуального метода [RFC-1556].

    Все эти символьные наборы применяются как чисто 7-битовые или 8-битовые без модификаций, связанных c <shift> или <escape>.

    Никакие символьные наборы, отличные от определенных выше, не могут использоваться в электронной почте без публикации и формальной регистрации в IANA. Допустимы частные соглашения, в этом случае имя символьного набора должно начинаться с X-.

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

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

    Простейшим и наиболее важным субтипом text является plain. Он указывает, что текст не содержит форматирующих команд или директив. Чистый текст может отображаться непосредственно без какой-либо обработки. По умолчанию для электронной почты предполагается тип среды text/plain; charset=us-ascii.

    Не распознанные субтипы text должны обрабатываться как чистый текст (plain), поскольку реализация MIME знает, как работать с данным символьным набором. Не распознанные субтипы, которые также специфицируют нераспознаваемый символьный набор, должны обрабатываться как application/octet- stream.

    Тип среды Image

    Тип среды image указывает, что тело содержит изображение. Субтип называет имя специфического формата изображения. Эти имена не чувствительны к регистру. Исходным субтипом является jpeg, который использует кодировку JFIF для формата JPEG [JPEG]. Не распознанные субтипы image должны обрабатываться как application/octet-stream.

    Тип среды Audio

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

    Содержимое субтипа audio/basic представляет собой моноканальное звуковое кодирование, использующее 8-битный ISDN-стандарт с $$\mu$$ -функцией преобразования [PCM] с частотой стробирования 8000 Гц. Не распознанные субтипы audio должны обрабатываться как application/octet-stream.

    Тип среды Video

    Тип среды video указывает, что тело содержит движущееся изображение, возможно, цветное и в сопровождении звука. Термин video используется в самом общем значении и не подразумевает какого-то конкретного формата. Субтип mpeg относится к видео, закодированному согласно стандарту MPEG [MPEG]. Не распознанные субтипы video должны обрабатываться как application/octet-stream.

    (1) В список опасных операций языка PostScript входят deletefile, renamefile, filenameforall и file. File является единственной опасной процедурой, которая применяется для входных/выходных потоков нестандартных данных. Конкретные реализации могут определить нестандартные файловые операторы, которые могут также представлять угрозу безопасности. Filenameforall, — оператор поиска файлов, может показаться на первый взгляд безобидным. Заметим, что этот оператор может раскрыть информацию о том, к каким файлам имеет доступ пользователь, а эти данные могут облегчить задачу хакеру. Отправители сообщений должны избегать использования потенциально опасных файловых операторов, так как такие операторы, скорее всего, недоступны в PostScript приложениях, где приняты меры по обеспечению безопасности. Программное обеспечение, которое используется для приема и отображения, должно блокировать потенциально опасные файловые операторы или принять меры по ограничению их возможностей
    (2) Язык PostScript предоставляет возможность для выхода из цикла интерпретатора или сервера. Операторы, сопряженные с выходом интерпретатора из цикла, могут интерферировать с процедурами последующей обработки документов. Операторы PostScript, которые выводят интерпретатор из цикла, включают в себя серверы выхода и начала задания. Программе отправки сообщения не следует генерировать PostScript, который зависит от функционирования выхода интерпретатора из цикла, так как такая процедура может отсутствовать в реализациях с повышенной безопасностью. Программа приема сообщений должна полностью блокировать работу операторов startjob и exitserver, а также какие-либо изменения в среде PostScript на постоянной основе. Если эти операции не могут быть полностью исключены, для их выполнения должен быть организован контролируемый доступ с необходимостью ввода пароля
    (3) PostScript предоставляет операторы для установки системных параметров и специфических параметров внешних устройств. Эти установки параметров могут влиять неблагоприятным образом на работу интерпретатора. Процедуры PostScript, которые устанавливают системные параметры, могут включать в себя операторы setsystemparams и setdevparams. Программа отправки не должна генерировать PostScript-сообщений, которые зависят от установки системных параметров. Программа приема и отображения сообщений должна блокировать изменение системных параметров. Если блокировка по каким-либо причинам невозможна, процедура установки параметров должна требовать специфического пароля
    (4) Некоторые реализации PostScript предоставляют нестандартные возможности для прямой загрузки и исполнения машинных кодов. Такие возможности чреваты злоупотреблениями. Программа отправки сообщений не должна использовать такие возможности. Программа приема и отображения сообщений не должна позволять применение таких операторов, если они имеются
    (5) PostScript является расширяемым языком, и многое, если не большинство, его реализаций предоставляют большое число расширений. Программа отправки сообщений не должна использовать нестандартные расширения. Программа приема и отображения сообщений должна быть уверена, что эти нестандартные расширения не представляют угрозы
    (6) Имеется возможность написания такой PostScript-программы, которая потребует огромных системных ресурсов. Можно также написать PostScript-фрагмент, который реализует бесконечный цикл. Оба варианта представляют угрозу для ничего не подозревающего получателя. Программа отправки сообщений должна избегать создания и распространения таких кодов. Программа приема и отображения сообщений должна предоставлять подходящий механизм для блокировки исполнения и удаления таких программ по истечении некоторого заданного времени
    (7) Существует возможность включения двоичной информации в PostScript-текст. Это не рекомендуется в электронной почте, так как это не поддерживается всеми PostScript-интерпретаторами, потому что сильно усложняет использование транспортного кодирования MIME.
    (8) Наконец, в некоторых интерпретаторах PostScript вполне возможны ошибки, которые могут использоваться для получения не авторизованного доступа к системе получателя

    Тип среды Application

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

    Такие приложения могут быть определены как субтипы типа среды application. В данном документе определены два субтипа: octet-stream и PostScript.

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

  • TYPE — общий тип или категория двоичных данных. Это параметр предназначен для оператора-получателя, а не для программы обработки
  • PADDING — число бит заполнителя, который добавлен к потоку бит, представляющему действительное содержимое, для того чтобы получить байт-ориентированный поток. Используется, когда число бит в теле не кратно 8
  • Оба эти параметра являются опционными.

    Тип среды application/postscript указывает на программу PostScript. В настоящее время допускается два варианта языка PostScript. Исходный вариант уровня 1 описан в [POSTSCRIPT], а более новый вариант уровня 2 рассмотрен в [POSTSCRIPT2].

    Описания языка PostScript предоставляет возможности внутренней пометки специфических возможностей данного приложения. Эта пометка, называемая DSC (document structuring conventions) PostScript, предоставляет существенно больше информации, чем уровень языка. Использование DSC рекомендуется даже тогда, когда это непосредственно не требуется, так как обеспечивает более широкую совместимость. Документы, которые недостаточно структурированы, не могут быть проверены с целью выяснения того, могут ли они работать в данной среде.

    Работа универсальных интерпретаторов PostScript представляет серьезную угрозу безопасности, разработчикам не рекомендуется просто посылать тела PostScript имеющимся ("off-the-shelf") интерпретаторам. В то время как посылка PostScript-файла на принтер обычно безопасна, программисты должны рассмотреть все возможные последствия, прежде чем ввести интерактивное отображение тел типа PostScript на их читающих средствах MIME.

    Оставшиеся два из семи исходных значений Content-Type относятся к составным объектам. Составные объекты обрабатываются с использованием механизмов MIME — процессор MIME обрабатывает тело объекта непосредственно.

    Тип среды Multipart

    В случае составных объектов, когда один или более различных наборов данных объединяется в одном теле, в заголовке объекта должно присутствовать поле типа среды multipart. Тело должно тогда содержать одну или более частей, каждая из которых начинается с разделительной строки. За разделительной строкой следует заголовок, пустая строка и тело объекта. Таким образом, часть тела по своему синтаксису аналогична сообщению в RFC-822, но имеет другое назначение.

    Часть тела является объектом и, следовательно, не должна интерпретироваться как сообщение RFC-822. Начнем с того, что части тела должны иметь заголовки. Допустимы части тела, которые начинаются с пустой строки. В таком случае отсутствие заголовка Content-Type обычно указывает, что соответствующее тело имеет тип содержимого text/plain;charset=US-ASCII.

    Единственные поля заголовка, которые определяют назначение частей тела, имеют имена, начинающиеся с Content-. Все другие поля в заголовке части тела могут игнорироваться. Для экспериментальных или частных назначений могут создаваться поля с именами, начинающимися с X-. Информация, содержащаяся в этих полях, может теряться в некоторых шлюзах.

    Различие между сообщением RFC-822 и частью тела не велико, но существенно. Шлюз между Интернет и почтовым сервером X.400, например, должен быть способен различать части тела, содержащие изображение, и инкапсулированное сообщение, тело которого представляет собой JPEG-образ. Для того, чтобы представить последнее, часть тела должна иметь Content-Type: message/rfc822, и ее тело после пустой строки должно представлять собой инкапсулированное сообщение со своим собственным полем заголовка Content-Type: image/jpeg. Применение подобного синтаксиса способствует преобразованию сообщений в части тела и обратно.

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

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

    Как задано в определении поля Content-Transfer-Encoding [RFC-2045], никакие кодировки кроме 7bit, 8bit или binary не разрешены для объектов типа multipart. Граничные разделители и поля заголовков multipart всегда представляются как 7-битовые коды US-ASCII, а данные внутри частей тела могут быть закодированы по-разному и иметь свои поля Content-Transfer-Encoding для каждой из частей.

    Поле Content-Type для составных объектов требует одного параметра — boundary. Строка-разделитель определяется как строка, содержащая два символа дефис ("-", десятичный код 45), за которыми следует значение пограничного параметра из поля заголовка Content-Type, опционный строчный пробел и заключительные CRLF.

    Символы дефис служат для некоторой совместимости с ранним методом (RFC-934) инкапсуляции сообщений и для облегчения поиска границ для некоторых приложений. Однако следует заметить, что составные сообщения не вполне совместимы с инкапсуляцией, описанной в RFC-934. В частности, они не подчиняются RFC-934 регламентации использования кавычек для вложенных строк, которые начинаются с дефиса. Этот механизм был выбран помимо RFC-934, потому что при данной схеме происходит удлинение строк для каждого уровня закавычивания. Возрастание длины строк, а также то, что некоторые реализации SMTP осуществляют разрыв строк, делают механизм RFC-934 неприменимым для составных сообщений при большой глубине вложений.

    Грамматика для параметров поля Content-type такова, что в строке Content-type часто приходится помещать пограничный параметр в кавычки. Это необходимо не всегда, но никогда не повредит. Программисты должны тщательно изучить грамматику, чтобы избежать генерации некорректных полей Content-type. Таким образом, типичное поле заголовка multipart Content-Type может выглядеть как:

    Content-Type: multipart/mixed; boundary=gc0p4Jq0M2Yt08j34c0p

    Но следующая запись некорректна: Content-Type: multipart/mixed; boundary=gc0pJq0M:08jU534c0p (из-за двоеточия) и должна вместо этого выглядеть как:

    Content-Type: multipart/mixed; boundary="gc0pJq0M:08jU534c0p"

    Это значение Content-Type указывает, что содержимое состоит из одной или более частей со структурой, которая синтаксически идентична сообщению RFC-822, за исключением того, что область заголовка может быть совершенно пустой, а каждая из частей начинается со строки

    --gc0pJq0M:08jU534c0p

    Пограничный разделитель должен размещаться в начале строки, т.e., следовать за CRLF, а начальный CRLF рассматривается объединенным со строкой пограничного разделителя, а не частью предшествующей секции. За границей может следовать нуль или более символов строчного пробела (HT, SP). Далее следует еще один CRLF и поля заголовка следующей части или два CRLF, что означает отсутствие полей заголовка следующей части. Если поле Content-Type отсутствует, предполагается объект типа message/rfc822 в сообщении multipart/digest, в противном случае text/plain.

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

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

    --gc0pJq0M:08jU534c0p--

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

    Имеется место для дополнительной информации перед пограничным разделителем и после оконечного разграничителя. Эти области следует в нормальной ситуации оставлять пустыми, а программные реализации должны игнорировать размещенную там информацию. Некоторые реализации используют эти ниши для пересылки сообщений принимающим программам.

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

    Ниже представлен простой пример составного сообщения, имеющего две части, каждая из которых содержит чистый текст, введенный явно и неявно:

    From: Nathaniel Borenstein
    To: Ned Freed
    Date: Sun, 21 Mar 1993 23:56:48 -0800 (PST)
    Subject: Sample message
    MIME-Version: 1.0
    Content-type: multipart/mixed; boundary="simple boundary"

    Это преамбула. Она будет проигнорирована, но, тем не менее, это удобное место, чтобы отправитель мог поместить сообщение для принимающей стороны, которая не поддерживает MIME.

    --simple boundary Это неявно введенный чистый US-ASCII-текст. Он не завершается на данной строке
    --simple boundary Content-type: text/plain; charset=us-ascii. Это явно введенный чистый US-ASCII-текст. Он завершается на данной строке
    --simple boundary Это эпилог. Он также игнорируется

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

    Практика показала, что тип multipart с единственной составной частью полезен для посылки сообщений с нетекстовым типом среды. Он имеет возможность формирования преамбулы как места, где можно поместить инструкции по декодированию. Кроме того, многие шлюзы SMTP перемещают или удаляют заголовки MIME, и хороший MIME-декодер таким путем может получить необходимую информацию даже в отсутствие заголовка Content-Type и корректно декодировать сообщение.

    Единственным обязательным глобальным параметром для типа среды multipart является граничный параметр, состоящий из 1 - 70 кодов символьного набора, который надежен по отношению преобразований, осуществляемых почтовыми шлюзами. Значение параметра не должно завершаться пробелом. Формально это записывается в BNF-представлении следующим образом.

    boundary := 0*69 bcharsnospace
    bchars := bcharsnospace / " "
    bcharsnospace := DIGIT / ALPHA / "’" / "(" / ")" / "+" / "_" /
       "," / "-" / "." / "/" / ":" / "=" / "?"

    Вообще тело объекта multipart может быть специфицировано как:

    dash-boundary := "--" boundary
    ; boundary берется из значения граничного параметра поля Content-Type.
    multipart-body := [preamble CRLF]
    dash-boundary transport-padding
    CRLF
    body-part *encapsulation
    close-delimiter transport-padding
    [CRLF epilogue]
    transport-padding := *LWSP-char ; Отправители не должны генерировать
    ; транспортные заполнители ненулевой
    ; длины, но получатели должны уметь
    ; обрабатывать заполнители, введенные
    ; при транспортировке.
    encapsulation := delimiter transport-padding CRLF body-part
    delimiter := CRLF dash-boundary
    close-delimiter := delimiter "--"
    epilogue := discard-text
    ; Строки части тела не должны начинаться с дефис-границы, а разделитель
    ; не должен появляться где-либо в теле секции. Заметим, что семантика части
    ; тела отличается от семантики сообщения, как это описано в тексте.
    OCTET := <любое значение октета 0-255 >

    Введение пробелов (HT, SP) и комментариев RFC 822 между элементами, показанными выше, недопустимо, так как эти BNF не специфицируют структурированное поле заголовка.

    В определенных транспортных зонах регламентации RFC 822, такие, как ограничение применения каких-либо символов, помимо печатных кодов US-ASCII, могут не действовать. Ослабление этих ограничений может рассматриваться как локальное расширение определения тел, например, чтобы включить октеты вне набора US-ASCII, так как эти расширения поддерживаются системой передачи и соответствующим образом документированы в поле заголовка Content-Transfer-Encoding. Однако заголовки ни в коем случае не могут содержать чего-либо помимо кодов US-ASCII.

    Субтип message/rfc822 не имеет других условий завершения, кроме окончания массива данных. Аналогично, некорректно укороченный составной объект не может иметь завершающего разделителя, что может вызвать нарушение работы почтовой системы.

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

    Субтип mixed типа multipart предназначен для использования в условиях, когда части тела независимы и должны объединяться в определенном порядке. Любые субтипы multipart, которые не распознаны программой, должны восприниматься как субтип mixed.

    Тип multipart/alternative синтаксически идентичен multipart/mixed, но имеет иную семантику. В частности, каждая часть тела является альтернативой одной и той же информации.

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

    Multipart/alternative может использоваться, например, для посылки сообщения в любом формате таким образом, чтобы его было легко отобразить:

    From: Nathaniel Borenstein
    To: Ned Freed
    Date: Mon, 22 Mar 1993 09:41:09 -0800 (PST)
    Subject: Formatted text mail
    MIME-Version: 1.0
    Content-Type: multipart/alternative; boundary=boundary42
    --boundary42
    Content-Type: text/plain; charset=us-ascii
    ... здесь следует версия сообщения в виде чистого текста ...
    --boundary42
    Content-Type: text/enriched
    ... здесь следует версия сообщения RFC 1896 в виде форматированного текста
    (text/enriched) ...
    --boundary42
    Content-Type: application/x-whatever
    ... здесь следует наиболее причудливая версия сообщения ...
    --boundary42--

    В этом примере пользователи, чья почтовая система может работать с форматом application/x-whatever, увидят только причудливую версию сообщения, в то время как другие пользователи увидят версию с форматированным или чистым текстом, в зависимости от возможностей их системы.

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

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

    Каждая часть объекта multipart/alternative представляет одну и ту же информацию, версии не обязательно тождественны. Например, информация теряется, когда осуществляется трансляция ODA в PostScript или в чистый текст. Рекомендуется, чтобы каждая часть имела свое значение Content-ID в тех случаях, когда содержимое частей неэквивалентно. Например, там, где несколько частей типа message/external-body специфицируют способы доступа к идентичной информации, следует использовать одни и те же значения поля Content-ID. Возможен вариант, когда одно значение Content-ID может относиться к объекту multipart/alternative, в то время как одно или более других значений Content-ID будут относиться к частям внутри объекта.

    Этот документ определяет субтип digest типа содержимого multipart. Этот тип синтаксически идентичен multipart/mixed, но их семантика различна. В частности, в дайджесте значение по умолчанию Content-Type для части тела меняется с text/plain на message/rfc822. Это сделано, чтобы допустить более читаемый формат дайджеста, совместимый с RFC-934.

    Хотя можно специфицировать значение Content-Type для части тела в дайджесте, который отличается от message/rfc822, такая часть, как text/plain, содержащая описание материала в дайджесте, делает это нежелательным. Тип содержимого multipart/digest предназначен для использования при посылке группы сообщений. Если необходима часть text/plain, она должна быть включена как отдельная компонента сообщения multipart/mixed. Дайджест в этом формате может выглядеть как:

    From: Moderator-Address
    To: Recipient-List
    Date: Mon, 22 Mar 1994 13:34:51 +0000
    Subject: Internet Digest, volume 42
    MIME-Version: 1.0
    Content-Type: multipart/mixed;
    boundary="---- main boundary ----"
    ------ main boundary ----
    ...Вводный текст или содержимое таблицы...
    ------ main boundary ----
    Content-Type: multipart/digest;
    boundary="---- next message ----"
    ------ next message ----
    From: someone-else
    Date: Fri, 26 Mar 1993 11:13:32 +0200
    Subject: my opinion
    ... здесь размещается тело...
    ------ next message ----
    From: someone-else-again
    Date: Fri, 26 Mar 1993 10:07:13 -0500
    Subject: my different opinion
    ... здесь размещается следующее тело ...
    ------ next message ------
    ------ main boundary ------

    Этот документ определяет субтип parallel типа содержимого multipart. Этот тип синтаксически идентичен multipart/mixed, но их семантика различна. В частности, в параллельном объекте порядок частей тела не играет роли.

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

    Тип среды Message

    Часто желательно при посылке почты вложить туда какое-то другое сообщение. Для решения этой задачи определен специальный тип среды message. В частности, для вложения в сообщения RFC-822 служит субтип rfc822.

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

    Тип среды message/rfc822 указывает, что тело содержит инкапсулированное сообщение. Однако в отличие от сообщений верхнего уровня RFC-822, ограничение, связанное с обязательным присутствием в теле message/rfc822 заголовков From, Date, и, по крайней мере, одного адреса места назначения, здесь удалено. Необходимо лишь присутствие одного из заголовков From, Subject или Date. Следует заметить, что, несмотря на использование чисел 822, объект message/rfc822 не должен абсолютно следовать регламентациям RFC-822. Более того, сообщение message/rfc822 может быть статьей новостей или сообщением MIME.

    В теле объекта message/rfc822 не разрешены никакие кодировки помимо 7bit, 8bit или binary. Поля заголовка сообщения содержат только US-ASCII в любом регистре, а информация в теле может быть закодирована. Не-US-ASCII-текст в заголовках инкапсулированного сообщения может быть специфицирован с использованием механизма, описанного в документе RFC-2047.

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

    Так как данные типа message могут не быть закодированы в виде base64 или закавыченной строки печатных символов, может возникнуть проблема, если объекты message/partial созданы в среде, которая поддерживает двоичный или 8-битовый обмен. Проблема возникает из-за того, что двоичные данные надо будет разбить на несколько сообщений message/partial, каждое из которых требует двоичного транспорта. Если такие сообщения встретят по пути шлюз с 7-битовой передачей, не будет никакой возможности перекодировать эти фрагменты для 7-битовой среды. Можно, конечно, дождаться прихода всех составных частей, собрать исходный объект, закодировать его с помощью, например, base64, после чего начать все с начала. Но даже такой сложный сценарий может оказаться неосуществимым из-за того, что фрагменты могут транспортироваться разными путями. По этой причине было специфицировано, что объекты типа message/partial должны всегда иметь транспортное кодирование 7bit (по умолчанию). В частности, даже для сред, которые поддерживают двоичный или 8-битовый обмен, использование транспортного кодирования 8bit или binary для MIME-объектов типа message/partial запрещено. Это, в свою очередь, предполагает, что внутреннее сообщение не должно использовать кодирование 8bit или binary. Так как некоторые агенты пересылки сообщений могут выбрать автоматическую фрагментацию длинных сообщений, а также из-за того, что эти агенты могут использовать разные пороги фрагментации, может так получиться, что фрагменты после сборки в свою очередь окажутся частями сообщения. Это вполне допустимо.

    В поле Content-Type типа message/partial необходимо специфицировать три параметра. id — уникальный идентификатор, который должен использоваться для привязки фрагментов друг к другу. number — целое число, которое является номером фрагмента. total — целое число, характеризующее полное число фрагментов. Число фрагментов является опционным и обязательно присутствует только в последнем фрагменте. Заметим также, что эти параметры могут быть заданы в любом порядке. Таким образом, второй сегмент 3-фрагментного сообщения может иметь поля заголовка одного из следующих видов.

    Content-Type: Message/Partial; number=2; total=3;
    Id="oc=jpbe0M2Yt4s@thumper.bellcore.com"
    Content-Type: Message/Partial;
    Id="oc=jpbe0M2Yt4s@thumper.bellcore.com";
    number=2

    Но в третьем сегменте должно быть специфицировано полное число фрагментов.

    Content-Type: Message/Partial; number=3; total=3;
    Id="oc=jpbe0M2Yt4s@thumper.bellcore.com"

    Заметьте, что нумерация фрагментов начинается с 1, а не c 0.

    Когда фрагменты объекта, разорванные таким способом, складываются вместе, результатом всегда будет исходный MIME-объект, который может иметь свое собственное поле заголовка Content-Type и, следовательно, иметь любой другой тип данных.

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

  • Фрагментирующие агенты должны разделять сообщения только по границам строк. Это ограничение вводится из-за того, что при несоблюдении данного правила возникнет транспортная проблема сохранения семантики сообщения, не заканчивающегося последовательностью CRLF. Многие виды транспорта не способны решить такую задачу
  • Все поля заголовка исходного вложенного сообщения, за исключением тех, чьи имена начинаются с "Content-", и специфических полей заголовка Subject, Message-ID, Encrypted и MIMEVersion, должны копироваться в новое сообщение
  • Поля заголовка вложенного сообщения, начинающиеся с "Content-", плюс поля Subject, Message-ID, Encrypted и MIMEVersion, должны быть добавлены к полям нового сообщения. Любые поля заголовка, которые не начинаются с "Content-" (за исключением полей Subject, Message-ID, Encrypted и MIMEVersion) будут проигнорированы и отброшены
  • Все поля заголовка второго и любых последующих вложенных сообщений отбрасываются принимающей программой в процессе сборки
  • Если аудио-сообщение разделено на два фрагмента, первая часть может выглядеть как:

    X-Weird-Header-1: Foo
    From: Bill@host.com
    Date: Fri, 26 Mar 1993 12:59:38 -0500 (EST)
    Subject: Audio mail (part 1 of 2)
    Message-ID:
    MIME-Version: 1.0
    Content-type: message/partial; id="ABC@host.com";
    number=1; total=2
    X-Weird-Header-1: Bar
    X-Weird-Header-2: Hello
    Message-ID:
    Subject: Audio mail
    Content-type: audio/basic
    Content-transfer-encoding: base64
    ... здесь помещается первая половина закодированных аудиоданных ...

    а вторая часть может выглядеть следующим образом:

    From: Bill@host.com
    To: joe@otherhost.com
    Date: Fri, 26 Mar 1993 12:59:38 -0500 (EST)
    Subject: Audio mail (part 2 of 2)
    MIME-Version: 1.0
    Message-ID:
    Content-type: message/partial;
    id="ABC@host.com"; number=2; total=2
    ... здесь помещается вторая половина закодированных аудиоданных ...

    Затем, когда фрагментируемое сообщение оказывается собрано, результат, отображаемый для пользователя, должен выглядеть как:

    X-Weird-Header-1: Foo
    From: Bill@host.com
    To: joe@otherhost.com
    Date: Fri, 26 Mar 1993 12:59:38 -0500 (EST)
    Subject: Audio mail
    Message-ID:
    MIME-Version: 1.0
    Content-type: audio/basic
    Content-transfer-encoding: base64
    ... здесь помещается первая половина закодированных аудиоданных ...
    ... здесь помещается вторая половина закодированных аудиоданных ...

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

    Наконец, следует заметить, что поле Encrypted заголовка является устаревшим из-за внедрения конфиденциальной почты PEM (Privacy Enhanced Messaging; RFC-1421, RFC-1422, RFC-1423, RFC-1424), но правила, описанные выше, несмотря ни на что, описывают правильный путь его обработки, если оно встретится в контексте прямого и обратного преобразования фрагментов message/partial.

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

    Когда объект MIME имеет тип message/external-body, он состоит из заголовка, двух последовательностей CRLF и заголовка для инкапсулированного сообщения. Если появится еще одна пара последовательностей CRLF, это завершит заголовок инкапсулированного сообщения. Однако, так как тело инкапсулированного сообщения само является внешним, оно не появится вслед за заголовком. Например, рассмотрим следующее сообщение:

    Content-type: message/external-body;
    access-type=local-file;
    name="/u/nsb/Me.jpeg"
    Content-type: image/jpeg
    Content-ID:
    Content-Transfer-Encoding: binary
    Это в действительности не тело!

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

    Инкапсулированные заголовки во всех объектах message/externalbody должны включать в себя поле заголовка Content-ID, чтобы предоставить уникальный идентификатор, который служит для ссылки на данные. Этот идентификатор может быть использован в процессе кэширования и для распознавания входных данных, когда типом доступа является mailserver.

    Заметим, что, как это специфицировано здесь, лексемы, которые описывают данные внешнего тела, такие, как имена файлов и команды почтового сервера, должны быть записаны с использованием символьного набора US-ASCII.

    Как с message/partial, объекты MIME типа message/external-body имеют транспортное кодирование 7-бит (по умолчанию). В частности, даже в среде, которая поддерживает 8-битовую транспортировку, использование транспортного кодирования 8bit или binary категорически запрещено для объектов типа message/external-body.

    Типы доступа ftp и tftp

    Тип доступа FTP или TFTP указывают, что тело сообщения доступно в виде файла с помощью протоколов FTP [RFC-959] или TFTP [RFC-783], соответственно. Для этих типов доступа необходимы следующие параметры.

  • NAME (имя). Имя файла, который содержит тело данных
  • SITE (узел). ЭВМ, с которой может быть получен файл с помощью данного протокола. Это должно быть официально зарегистрированное имя, а не псевдоним
  • Прежде чем какие-либо данные будут извлечены с помощью FTP, пользователь должен выполнить процедуру аутентификации (ввести имя и пароль) на машине, указанной в параметре SITE. По соображениям безопасности имя и пароль не специфицируются параметрами типа доступа, они должны быть получены непосредственно от пользователя
  • Кроме того, следующие параметры являются опционными:

  • DIRECTORY (каталог). Каталог, из которого должен быть взят файл с именем, заданным параметром NAME
  • MODE (режим). Строка символов, не зависящая от регистра ввода и указывающая на режим, который должен использоваться при извлечении информации. Допустимыми значениями параметра типа доступа TFTP являются NETASCII, OCTET и MAIL, как это определено для протокола TFTP [RFC- 783]. Допустимыми значениями параметра для типа доступа FTP являются ASCII, EBCDIC, IMAGE и LOCALn, где "n" — целое число, обычно 8. Они соответствуют типам представления "A" "E" "I" и "L n", как это задано протоколом FTP [RFC-959]. Заметим, что BINARY и TENEX не являются корректными значениями для MODE и что вместо этого следует использовать OCTET, IMAGE или LOCAL8. Если параметр MODE не задан, значением по умолчанию является NETASCII для TFTP и ASCII во всех прочих случаях
  • Тип доступа local-file

    Тип доступа local-file указывает, что тело данных доступно в виде файла на локальной ЭВМ. Для этого типа доступа определены два дополнительные параметра.

  • NAME (имя). Имя файла, который содержит тело данных. Этот параметр является обязательным для типа доступа local-file
  • SITE (узел). Спецификатор домена для данной ЭВМ или набора машин, которые имеют доступ к данному информационному файлу. Этот опционный параметр используется для описания локального указателя на данные, т.е., узел или группу узлов, откуда данный файл доступен. В качестве символов подмены в имени домена могут использоваться звездочки, как, например, в "*.bellcore.com", чтобы указать на группу ЭВМ, откуда данные доступны непосредственно
  • Тип доступа mail-server

    Тип доступа mail-server указывает, что тело данных доступно на почтовом сервере. Для этого типа доступа определены два дополнительные параметра.

  • SERVER (сервер). Спецификация адреса почтового сервера, с которого могут быть получены данные. Этот параметр является обязательным для типа доступа mail-server
  • SUBJECT (тема сообщения). Тема сообщения (subject), которая используется в почтовом сообщении с целью получения данных. Этот параметр является опционным
  • Так как почтовые серверы воспринимают разнообразные синтаксисы, некоторые из которых являются многострочными, полная команда, которая должна быть послана почтовому серверу, не включается в качестве параметра с полем заголовка content-type. Вместо этого она заносится как тело-фантом, когда тип среды соответствует message/external-body, а типом доступа — mail-server.

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

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

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