Http/Smtp MIME составной. Почему граница?

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


person Michael    schedule 05.01.2014    source источник


Ответы (2)


Используя длину, синтаксический анализ будет [быть] проще

Здесь вы ошибаетесь. Авторы составного MIME имели в виду случаи, когда нельзя было заранее определить длину части сообщения. Подумайте о кодировках контента, которые изменяют длину сообщений, таких как base64, UUencode и другие. Есть также сжатие, шифрование и еще много чего. Также: Content-Length — это заголовок объекта. Это означает, что если вы достигли его, вы уже начали анализировать часть сообщения. Он не имеет буквально никаких преимуществ перед пограничным маркером.

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

Итог: составная граница позволяет использовать некоторые интересные приложения с содержимым сообщений непредсказуемого размера. Ярким примером является передача HTTP-сервера.

person DaSourcerer    schedule 05.01.2014
comment
Но это зависит от того, как вы определяете длину содержимого. Вы всегда можете использовать его как количество байтов, фактически отправленных в текущей части (после кодирования и/или сжатия). В этом случае вы всегда знаете, когда деталь будет закончена, просто считая вместо сопоставления с образцом. Я что-то упускаю? - person Michael; 05.01.2014
comment
Да. Вы не можете сделать это, если, например. вы создаете содержимое сообщения динамически или если вы ограничены в ресурсах способом, который не позволяет обрабатывать часть сообщения целиком. Чтобы оставаться в современных стандартах, представьте себе сообщения размером в несколько гигабайт. Кстати: заголовок Content-Length определен именно так, как вы написали здесь. - person DaSourcerer; 05.01.2014
comment
Да, с префиксом длины каждого фрагмента данных и последующей специальной маркировкой последнего фрагмента данных вы можете передавать данные, не зная заранее общий размер. Его намного проще анализировать, чем составной MIME. Это делается с помощью кодирования передачи по частям HTTP. - person Steffen Ullrich; 05.01.2014
comment
Спасибо, Десорсер. Я согласен, что для генерации сообщений на лету это не сработает. Но единственный практический пример, который я вижу, — это стриминг. В то время как для отправки огромных файлов вы все еще можете использовать размер файла вместо границы, не так ли? Вам не нужны дополнительные ресурсы, чтобы получить размер файла перед генерацией http-сообщения. - person Michael; 05.01.2014
comment
Стефен, спасибо! Фрагментированная передача по HTTP очень полезна для объяснения проблемы. - person Michael; 05.01.2014
comment
@Майкл мыслит более общими словами. Также не всегда возможно определить размер файлов. Например, подумайте об удаленных ресурсах. Сказав это, имейте в виду, что составной MIME — это вещь общего назначения. Я думаю, что граница на самом деле является достойным решением для этого. - person DaSourcerer; 05.01.2014
comment
Если содержимое заранее неизвестно, как отправитель может убедиться, что граница не встречается в полезной нагрузке? - person xmjx; 04.11.2015
comment
@xmjx На самом деле этого никогда не должно происходить. Однако учтите, что граница не сама по себе; он окружен синтаксически значимыми разрывами строк: \r\n--{$boundary}\r\n. Это по-прежнему не гарантирует, что допустимая граница не будет частью тела сообщения. Но по крайней мере это маловероятно. - person DaSourcerer; 21.01.2016

Потому что в старые добрые времена стандарт MIME определялся таким образом. Одна из причин, вероятно, заключалась в том, что длина содержимого имеет проблему с текстовыми/обычными данными, где новая строка может быть либо CR (старый Mac), LF (unix), либо CR LF (windows, dos). Другой может заключаться в том, что человеку легче читать, что, ИМХО, является плохим аргументом, но часто случается, когда предпочтение отдается текстовым представлениям, таким как HTTP, XML или SOAP, вместо более эффективных двоичных способов, таких как ASN.1 или SUN RPC.

Вы также можете рассматривать это как успешную попытку отрасли продавать более мощные серверы, вводя бесполезные накладные расходы в протоколы :)

person Steffen Ullrich    schedule 05.01.2014
comment
Большое спасибо Стефан! Просто вопрос вдогонку. Вы упоминаете возможную проблему с символом конца строки. Но почему? Content-length будет просто подсчитывать фактические символы (cr или cr+lf). Почему это может создать проблему при разборе? - person Michael; 05.01.2014
comment
потому что MTA (агенты пересылки почты) и MUA (почтовые пользовательские агенты, например, почтовый клиент) могут изменять сообщение до тех пор, пока его содержимое не изменится. Например, если MTA не понимает двоичный код Content-Transfer-Encoding, отправляющий MUA/MTA преобразует его в base64. Кроме того, текстовые/простые данные, присоединенные к платформе Windows (строка, заканчивающаяся CR LF), будут автоматически преобразованы в строку, заканчивающуюся LF, при чтении/сохранении на платформе unix. Хотя в теории это может показаться хорошей идеей, в действительности это создает множество проблем, потому что многие MUA устанавливают тип содержимого text/plain даже для двоичного содержимого :( - person Steffen Ullrich; 05.01.2014
comment
Но как я понял, длина контента это количество байт и от кодировки не зависит. Таким образом, если MTA/MUA изменит сообщение, оно также обновит поле длины содержимого. Нет? - person Michael; 05.01.2014
comment
Для MIME не определен заголовок длины содержимого, даже если его добавляют некоторые MUA (но обычно только MUA конечного получателя для облегчения синтаксического анализа сохраненных сообщений). В MIME длина каждой части определяется исключительно границами. Это отличается от HTTP, который использует множество идей из MIME. Здесь Content-Length используется для описания общей длины тела. Перекодирование контента обычно не выполняется (HTTP рассматривает контент как двоичный для передачи, тогда как старый SMTP рассматривает контент как текст), и если веб-прокси изменяет контент, он должен настроить длину контента. - person Steffen Ullrich; 05.01.2014
comment
Да, в запросе HTTP Post мы используем длину содержимого для всего тела сообщения и границы для отдельных частей. Таким образом, концептуально мы могли бы без проблем использовать дизайн, в котором мы не используем границы, а используем длину содержимого, измеряемую в байтах, для каждой части составного сообщения. Верный? - person Michael; 05.01.2014
comment
в запросе HTTP Post мы используем длину содержимого для всего размера тела сообщения. На самом деле это лучшая практика и ни в коем случае не обязательная. Если вы изучите RFC 2616, вы обнаружите, что все стороны должны понимать кодирование по частям. Таким образом, технически вы можете отправить фрагмент POST-запроса, закодированный без размера сообщения. Однако поддержка этого сервером незначительна, поэтому отправка размера сообщения является предпочтительным методом. - person DaSourcerer; 05.01.2014
comment
Теоретически вы можете отправить в запросе POST или PUT все, что хотите, если длина контента известна серверу, установив либо заголовок длины контента, либо используя кодировку передачи по частям. Если у вас есть несколько частей в одном и том же POST, вы можете упаковать их так, как хотите, например. как составной MIME, json, ZIP, XML ..., пока сервер это понимает. HTML-формы будут передаваться браузером как составные MIME, но с вашими собственными вызовами ajax вы можете использовать все, что захотите. - person Steffen Ullrich; 05.01.2014
comment
Хм, позволю себе не согласиться. Ответственность сервера заканчивается, когда кодировка передачи удалена и тело сообщения передано веб-приложению. ИМХО, разбор тела сообщения уже является обязанностью веб-приложения. Кстати: составные сообщения имеют значение только в HTML-формах, если они несут какие-либо файлы. Все остальное должно быть отправлено как application/x-www-form-urlencoded, что является более компактным форматом;) - person DaSourcerer; 05.01.2014
comment
Я согласен. Тем не менее были бы более простые для анализа и более эффективные способы отделения частей в теле сообщения друг от друга (и я не имею в виду XML, что еще хуже). - person Steffen Ullrich; 05.01.2014