Кратко
- MIME присвоил сущности тела
Content-IDс синтаксисом Message-ID, чтобы другая часть могла сослаться на неё независимо от порядка и внешнего адреса. multipart/relatedвыбирал по Content-ID корень составного объекта, аcid:и длинная формаmid:превращали ту же метку в ссылку.- Требование всемирной уникальности относилось к генерации значения. Оно не создавало хеш содержимого, доказательство авторства или глобальную доступность; выбор оставался за контейнером и принимающим приложением.
Адрес, направленный внутрь
В привычной модели Веба ссылка выводит клиента за пределы документа: программа получает адрес и запрашивает другой ресурс. Составное MIME-сообщение допускало обратную логику. HTML и изображение приходили в одном пакете, а разрешение ссылки означало поиск уже полученной части в локальном дереве.
Одного имени файла или номера позиции для этого было мало. Шлюз мог переставить части, архив — извлечь вложения, а рекурсивная структура multipart — содержать несколько самостоятельных составных объектов. Ссылка на «третью часть» меняла смысл после вполне допустимой реорганизации.
В 1992 году RFC 1341 расширил плоское тело Internet mail до типизированных, вложенных MIME-сущностей и ввёл необязательные поля Content-ID и Content-Description. Второе могло описывать объект для человека, первое обозначало сущность, на которую ссылается другая часть. Content-Type объяснял интерпретацию декодированных байтов, Content-Transfer-Encoding — их транспортное представление, boundary — границы сериализации. Content-ID отвечал на отдельный вопрос: какой объект имеется в виду.
RFC 2045 в 1996 году уточнил, что значение использует синтаксис Message-ID и должно генерироваться всемирно уникальным. Общая грамматика не означала общей роли. Message-ID именует всё сообщение, Content-ID — одну MIME-сущность, в том числе глубоко вложенную.
Стандарт приводил в пример кеширование. Тип message/external-body описывает данные, доступные внешним способом, и при создании такой сущности Content-ID обязателен. Кеш мог распознать одно содержимое за разными инструкциями доступа. Но идентификатор не вычислялся из октетов. Совпавшие значения выражали утверждение составителя, а не криптографическое доказательство тождества. Всемирная уникальность также не создавала публичного индекса, записи DNS или HTTP-сервера, обязанного вернуть данные.
Ограниченное дублирование раскрывало уровень идентичности
Если принять Content-ID за первичный ключ сериализованных узлов, каждое повторение следует считать ошибкой. RFC 2046 показывает, почему это неверно, на примере multipart/alternative. Такой контейнер хранит одну информацию в нескольких форматах; получатель обычно выбирает последнюю форму, которую способен обработать.
Если преобразование теряет сведения, варианты должны иметь разные Content-ID. Однако несколько частей message/external-body, предлагающих разные способы получить идентичные данные, могут делить одно значение. Кеш видит один объект, а правило внешнего multipart выбирает представление.
Следовательно, Content-ID свидетельствует о предполагаемой идентичности содержимого в контексте структуры, а не гарантирует отдельный ключ для каждого блока между boundary. Безусловный запрет дублей ломает допустимые альтернативы. Безусловное разрешение создаёт неоднозначность и возможность подмены. Родительский контейнер необходим для толкования метки.
Составному объекту требовался корень
HTML-страница с изображениями — не просто набор вложений. Один компонент организует остальные, и независимый показ частей теряет замысел. RFC 2110 в 1997 году стандартизировал раннюю MHTML-упаковку составных документов, связав Content-ID, CID URL и Content-Location.
В 1998 году RFC 2387 определил общий контейнер multipart/related. Параметр type объявляет медиатип корня. Необязательный start указывает через Content-ID часть, которую приложение должно обработать первой. Без start корнем становится первая часть тела.
Порядок давал значение по умолчанию, а явный идентификатор мог его заменить. Если шлюз переносил корень и не сохранял или не переписывал связь start, смысл пакета менялся при сохранности всех байтов. С другой стороны, start не позволял искать объект за пределами правильного related-контейнера. Если type расходился с фактическим Content-Type корня, RFC 2387 оставлял поведение пользовательского агента неопределённым.
Правила составного объекта могли также иметь приоритет над обычным способом показа вложения. Имя файла помогает сохранить изображение, но не определяет, самостоятельный ли это файл или необходимый компонент документа. Сохранить части без их отношений — значит сохранить материал, но не собранное произведение.
cid: переводил заголовок в синтаксис ссылки
RFC 2392 задал URL-формы для Message-ID и Content-ID. CID URL состоит из cid: и закодированного для URL addr-spec. Реализация удаляет префикс, декодирует процентные последовательности и восстанавливает угловые скобки, после чего результат можно напрямую сравнить с полями Content-ID в MIME-дереве.
URL-форма не предписывала сетевой транспорт. Схема описывала процедуру поиска по заголовкам MIME. Многие хранилища индексировали целые сообщения, но не все внутренние части. Поэтому RFC 2392 определил длинную форму mid:message-id/content-id и потребовал её поддержки. Первый идентификатор находит сообщение, второй — сущность внутри него.
Короткая ссылка cid: обычно ограничена тем же сообщением. Хранилище может расширить поиск, опираясь на соглашение об уникальности, но это функция реализации, а не всемирный сервис. Документ также сохранил ограниченные случаи нескольких частей с одним Content-ID: правила охватывающей сущности решают, какой кандидат обозначен ссылкой.
Местоположение оставалось другим утверждением
RFC 2557 заменил RFC 2110 в 1999 году и разделил Content-ID, Content-Location и Message-ID. В Content-Location мог находиться абсолютный или относительный URI, который не обязан быть доступным получателю. Он мог работать только в закрытой среде или вообще быть условным адресом для разрешения ссылок внутри пакета.
Поле при этом сохраняло смысл. Оно сопоставляло ссылку исходного документа с приложенной частью и могло указывать концептуальное происхождение представления. Но оно не служило квитанцией об успешном внешнем получении.
RFC 2557 также различал URI агрегата MHTML и URI его корня. Запрос агрегата возвращает пакет. Запрос корня может вернуть только страницу, после чего клиент отдельно получает зависимости. Если операции происходят в разное время, результатом могут стать разные снимки состояния.
Content-ID оказался центральным именно благодаря ограниченности обещаний. Он удерживал внутреннюю связь, пока порядок, местоположение и момент получения менялись. После нахождения части получателю всё ещё предстояло установить контекст сообщения, разобрать контейнер, выбрать допустимую альтернативу, декодировать данные, применить правила безопасности и решить, что показывать.
Обзор для участников
Подробный контекст профиля
Войдите с подходящим уровнем подписки, чтобы открыть полный обзор и примечания к источникам.
Только для Стратегического сообщества
Стратегическое сообщество
Открыто всем читателям. Вступите и войдите, чтобы открыть обзоры профилей.
Вступить в Стратегическое сообществоТолько для Альянса лидеров
Альянс лидеров
Для проверенных владельцев IP-активов и руководителей. Войдите, чтобы открыть обзоры Альянса.
Вступить в Альянс лидеров
