Multipart: общий синтаксис
Поле Content-Type многочастного письма требует одного параметра, "boundary", который определяет границы вложения. Границей является строка, состоящая из двух символов "-" (десятичный код 45) и значения параметра 'boundary' из поля заголовка Content-Type.
ЗАМЕЧАНИЕ: Два символа "-" используются для совместимости с более ранним методом вложения писем, описанным в RFC 934 и для облегчения поиска границ. Однако, многочастные письма MIME не полностью совместимы с RFC 934; в частности, они не подчиняются соглашению RFC 934 по экранированию строк символом "-", так как с каждым новым уровнем экранирования длина строк увеличивается. А поскольку SMTP-транспорты часто обрезают длинные строки, этот механизм становится неприменимым в случае многоуровневой структуры письма типа 'multipart'.
ВНИМАНИЮ ПРОИЗВОДИТЕЛЕЙ ПО: синтаксис параметров поля Content-Type таков, что зачастую необходимо значения границ в параметре 'boundary' заключать в кавычки. Это не всегда требуется, но никогда не повредит. Программистам следует изучить синтаксис внимательно, чтобы не допустить ошибок в поле Content-Type. Типичное поле Content-Type для типа 'multipart' может выглядеть следующим образом:
Content-Type: multipart/mixed; boundary=gc0p4Jq0M2Yt08jU534c0p
Но в следующем примере содержится ошибка:
Content-Type: multipart/mixed; boundary=gc0p4Jq0M:2Yt08jU534c0p
(из-за двоеточия), которая может быть исправлена следующим образом:
Content-Type: multipart/mixed; boundary="gc0p4Jq0M:2Yt08jU534c0p"
Это означает, что тело письма состоит из нескольких частей, каждая из которых соответствует синтаксису письма RFC 822, за исключением того. что область заголовка может быть абсолютно пустой и начальная граница каждой части отмечена последовательностью:
--gc0p4Jq0M:2Yt08jU534c0p
Нужно обратить внимание, что метка границы части письма должна располагаться в начале строки, то есть, сразу же после признака конца строки CRLF. Причем, последовательность CRLF полагается элементом метки границы, а не последним элементом тела предыдущей части (так как тело предыдущей части может неоканчиваться концом строки, что принципиально важно в случае бинарных данных.
Если же тело предыдущей части оканчивается концом строки, то метке границы соответственно должны предшествовать два конца строки). Сразу за меткой границы должен следовать конец строки (CRLF), или при отсутствии заголовка следующей части письма, два конца строки.
Метка границы не должна иметь длину более 70 символов, не считая два начальных дефиса.
Метка границы, следующая за последней частью письма, должна отличаться от предыдущих меток, чтобы показать, что далее не последует другой части письма. Отличие последней метки состоит в добавлении двух дефисов в конец:
--gc0p4Jq0M2Yt08jU534c0p--
Обычно оставляется пространство для дополнительной информации перед первой меткой границы и после последней. Обычно его следует оставлять пустым, и обработчики почты должны игнорировать все, что в этом пространстве содержится.
ЗАМЕЧАНИЕ: Эти области приамбулы и эпилога обычно не используются из-за отсутствия точной семантики для обработки этих областей почтовыми шлюзами, однако, многие программные MIME-продукты считают удобным помещать туда пояснительную информацию для получателей, которые пользуются до-MIME'овским ПО. По этой причине, MIME-совместимые программы должны игнорировать эти области.
ЗАМЕЧАНИЕ: Поскольку метки границы не должны появляться внутри тел частей письма, почтовая программа, создающая письмо, должна иметь алгоритм, позволяющий автоматически подобрать уникальную последовательность, не встречающуюся в теле ни одной из частей, либо имеющую минимальную вероятность появления, если данные предварительно не сканируются на наличие таковой.
В качестве простого примера предлагается двухчастное письмо, вторая часть которого оканчивается признаком конца строки, а первая нет:
From: Nathaniel Borenstein
To: Ned Freed
Subject: Sample message MIME-Version: 1.0 Content-type: multipart/mixed; boundary="simple boundary" Это приамбула. Должна быть игнорирована --simple boundary Это простой ASCII-текст. Он НЕ оканчивается признаком конца строки. --simple boundary Content-type: text/plain; charset=us-ascii Это простой ASCII-текст.
Он оканчивается признаком конца строки. --simple boundary-- Это эпилог. Тоже должен игнорироваться MIME-программами.
Часть письма, в свою очередь, также может иметь тип 'multipart', то есть. быть многочастным телом, но при этом метки границ, использующиеся во внешнем и во внутреннем multipart-телах, должны отличаться друг от друга.
Использование типа 'multipart' в одночастном письме может быть полезно в некоторых контекстах и не запрещено.
Единственным обязательным параметром для типа 'multipart' является параметр 'boundary', состоящий из 1-70 символов без хвостовых пробелов (которые могут быть удалены в процессе пересылки, и тогда почтовая программа получателя не сможет разделить вложенные части).
граница := 0*69<символов границы> символ_границы_кроме_пробела символ границы := символ_границы_кроме_пробела / " " символ_границы_кроме_пробела := ЦИФРА / БУКВА ЛАТИНСКОГО АЛФАВИТА / "'" / "(" / ")" / "+" /"_" / "," / "-" / "." / "/" / ":" / "=" / "?"
Общий вид многочастного тела - следующий:
многочастное тело := приамбула вложения признак_конца эпилог вложение := разделитель часть_тела CRLF разделитель := "--" метка_границы CRLF ; метка границы должна браться из поля Content-Type. ; Не должно быть пробелов между "--" и меткой границы. признак конца := "--" метка_границы "--" CRLF ; Опять, без пробела перед "--", приамбула := игнорируемый текст эпилог := игнорируемый текст игнорируемый текст := *(*текст CRLF) часть_тела := <письмо RFC 822, со всеми необязательными полями заголовка>
ЗАМЕЧАННИЕ: В некоторых транспортах такие ограничения RFC 822, как использование тольеко печатных символов в теле, могут не действовать. Ослабления таких ограничений должны быть истолкованы как локальные расширения определения тела письма настолько, насколько они поддерживаются почтовым транспортом и адекватно документированы в поле заголовка Content-Transfer-Encoding.Однако, ни при каких обстоятельствах в заголовках как письма, так и его частей, не должно содержаться каких-либо символов, кроме US-ASCII.