Интегрированные сети ISDN

         

Поле заголовка Content-Transfer-Encoding


5. Поле заголовка Content-Transfer-Encoding



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

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

5.1. Синтаксис 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".

5.2. Семантика Content-Transfer-Encodings



Лексема 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, двоичное тело сообщение может быть помечено как таковое.



5.3. Новое значение Content-Transfer-Encodings



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



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



4. Реализация и применение



Если поле заголовка 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 ориентировано на то, чтобы предоставлять открытые механизмы спецификации, строгие ассоциации типов среды и кодирования эффективно соединяют спецификацию прикладного протокола с определенным транспортом нижнего уровня. Это нежелательно, так как разработчики типа среды не должны заботиться обо всех видах транспорта и их особенностях.



5.5. Транслирующее кодирование



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



5.6. Транспортное кодирование содержимого Quoted-Printable



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


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

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

Заметим, что многие реализации могут выбрать для кодирования непосредственно локальное представление различных типов содержимого, а не преобразование в каноническую форму, кодирование и только затем преобразование в локальное представление. В частности, такая техника может быть применена к простому тексту в системах, которые используют для межстрочных разрывов последовательности, отличные от CRLF. Такая оптимизация конкретной программной реализации вполне допустима, но только когда комбинированный шаг канонизация-кодирование эквивалентен выполнению всех трех шагов отдельно.
(5) Мягкие разрывы строки. Кодирование с помощью закавыченных строк печатных символов требует, чтобы строки содержали не более 76 символов. Если нужно закодировать более длинные строки вводятся “мягкие” разрывы строк. Символ равенства в конце строки как раз и обозначает такой разрыв.
<


/p> Так пусть имеется следующий текст, который надо преобразовать:

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

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

Now's the time =

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

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

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

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



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


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

quoted-printable := qp-line *(CRLF qp-line)  
qp-line := *(qp-segment transport-padding 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 := ; Символы, не включенные в список "mail-safe" RFC 2049, не рекомендуются к применению.
hex-octet := "=" 2(DIGIT / "A" / "B" / "C" / "D" / "E" / "F") ; Октет должен использоваться для символов с кодами > 127, =, SP или TAB в конце строк, и рекомендуются для любого символа не указанного в списке "mail-safe" документа RFC 2049.
transport-padding := *LWSP-char ; Составители не должны генерировать заполнители ненулевой длины, но получатели должны быть способны обрабатывать заполнители, добавленные при транспортировке.
Добавление LWSP между элементами, показанное в данном BNF-представлении, не допустимо, так как данное BNF не специфицирует структурированных полей заголовка.



5.7. Транспортное кодирование Base64 (Content-Transfer-Encoding)



Транспортное кодирование на основе 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., из их перечня исключены коды, имеющие особое значение для протокола SMTP (например, ".", CR, LF), а также разграничитель секций составного сообщения "-" (RFC-2046).


Содержание раздела