2016-03-21

О MIME

Есть такой милый стандарт MIME. Если верить Википедии, произносится это как «майм». Но я почему-то всегда произносил это неправильно как «миме». Это — Multipurpose Internet Mail Extensions. Не путать с мимами — странными молчаливыми ребятами с чрезвычайно бледными лицами.
И вы постоянно сталкиваетесь с этими MIME сообщениями. Ибо это обычная электропочта, то самое, что посылается через SMTP, принимается через IMAP и ещё кучу протоколов и, в конце концов, отображается в вашей любимой почтовой программе. А ещё может быть сохранено в виде .eml или .msg файлов. Но на самом деле MIME встречается ещё чаще, ибо в HTTP что запрос, что ответ, по сути (за исключением первой строки с типом запроса и статусом ответа) являются MIME сообщениями.
MIME
MIME сообщения восходят ещё к тем временам, когда не было XML и JSON, и в Интернете правили текстовые протоколы. В MIME сообщении имеются заголовки, где название заголовка отделяется от значения двоеточием, пустая строка-разделитель, и тело сообщения.
Самым важным заголовком MIME является Content-Type.
Content-Type: text/plain
Значение этого заголовка — это тип содержимого сообщения. И здесь мы встречаемся с величайшим вкладом этого стандарта в Порядок во Вселенной: MIME type или MIME тип.
MIME тип состоит из двух слов, разделённых слэшем. Первое слово — тип содержимого. Текст — text. Изображение — image. Музыка — audio. Видосик — video. Это содержимое предназначено для обработки конкретной программой — application. Содержимое состоит из нескольких частей — multipart.
Второе слово — подтип содержимого. Просто текст без форматирования — text/plain, текст в HTML разметке — text/html. Изображение в JPEGimage/jpeg, в PNGimage/png. Аудио в MP3audio/mp3, в Ogg Vorbis, или Opus, или Speex — audio/ogg. Видео в MP4video/mp4, в Matroskavideo/x-matroska. Текст в формате OpenDocument, подразумевается, что открываться должен в соответствующих программах, — application/vnd.oasis.opendocument.text. PDF документ, должен открываться в программах для просмотра PDF, — application/pdf.
Типы MIME, по-хорошему, положено регистрировать в IANA. Часто при этом, если за данным форматом данных стоит конкретная организация, подтип начинается с vnd., например: application/vnd.ms-excel. Но, по устаревшим спецификациям, можно было не регистрировать подтипы, начинающиеся с x-. Они вроде как были экспериментальными, но некоторые так здорово прижились, что мы до сих пор имеем дело с ужастиками вроде application/x-www-form-urlencoded. Этот тип, кстати, обозначает один из способов отправки данных из HTML формы.
MIME types
Вообще, когда у нас есть какой-то кусок байт, хорошо, если файл, то мы можем определить его содержимое несколькими способами. Можно попытаться открыть это во всех имеющихся программах, авось какая-то и переварит. Очевидно, это не очень эффективно. Если у нас есть имя файла, то значит у этого имени есть расширение (по факту — буквы после последней точки), а расширение часто даёт понять, что это за файл. Так до сих пор поступают нынешние ОС, у них записано, файлы с каким расширением в какой программе открывать. Но здесь нужно имя файла, а его может не быть, если байты пришли по Сети или вообще хранятся где-то в базе данных.
Если же у нас есть MIME тип, то мы прекрасно знаем, что это за данные. А современные ОС ещё и знают, какой программой данный MIME тип открывать. Получается, что ОС хранят соответствие между программой и расширениями имени файлов, а также между программой и связанными с нею MIME типами.
MIME type associations
В серверостроении возникает немного другая проблема. У нас есть файл, и его надо передать по Сети (по HTTP). Чтобы сделать это правильно, нам нужно выдать MIME тип пересылаемых данных. К сожалению, ОС, как правило, не предоставляет механизма узнать MIME тип конкретного файла. Это банально нигде не хранится. Поэтому серверам приходится выводить тип из расширения имени файла, для этого есть даже специальные файлики-БД. Либо применять специальную магию. Очень часто тип файла можно узнать по нескольким первым байтам самого файла. Например, все изображения PNG начинаются с байт 89 50 4E 47, последние три байта — это буквы PNG в ASCII. Вот MIME тип и определяется по началу файла.
Мораль такова. MIME тип всегда передаётся по сети. MIME тип однозначно даёт знать, что это за данные, и что с ними можно сделать. А значит, если вы сохраняете байтики в базу данных, или ещё куда-нибудь, не потеряйте MIME тип, сохраните его рядышком. Потом это может очень пригодится.
А если вы создаёте свой формат данных, который может быть полезен за пределами данного запроса-ответа, который может быть стоит куда-то сохранить, придумайте для него свой MIME тип.
Trust Me
Особняком стоит тип multipart. С его помощью можно засовывать в одно сообщение несколько различных содержимых. Именно так создаются письма с вложениями.
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=part

--part
Content-Type: text/plain

This is a text message with PNG attachment.
--part
Content-Type: image/png
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=stackoverflow.png

iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABCElEQVQ4y7XRLUtEQRjF8Z/ulgG9
BrNpqy/NZhKDi/gFBIMoaJFpCmLSYvIWQQ0WNRj9CgbDCqIGwWw3TLlBRMsNC3tXr4gHhgnPM4f/
OUMNpRjG+s0G1dNlimH1LwZr2E8xtGobpBhWUwzzkOXFC/ZKkkZdgmecpBgOUgyNLC+O8Iad7qWB
H8obxTmGsIR3PGAxy4sONCsetbCL0ywvbtFOMWzhDsvYwAI6lQQphhGslMV94BgXmMQl5spOakWY
wTrauMZhlheP3TtVEW7wiqfybGOzxO9RVYSpEnccE+U9jPssL2b74p6dX31+9xsphumqvaoIn9/U
0kPcY5DlxYBfqFk3xr/pC6p9USZurgviAAAAAElFTkSuQmCC
--part--
Распаковать это безобразие можно, например, с помощью программы munpack.
Для типа multipart обязательно задаётся ещё и параметр boundary — разделитель частей сообщения. Заголовок Content-Transfer-Encoding указывает на то, как закодировано содержимое. Бинарные файлы в электропочте как правило кодируются в Base64, чтобы ограничиться при передаче исключительно ASCII символами. Что приводит к распуханию бинарных файлов в письме на треть. А вот в HTTP принято пересылать бинарные данные как есть.
Заголовок Content-Disposition указывает, как поступить с содержимым. Если attachment, значит, это отдельный файл, имя которого может быть задано тут же. В случае HTTP attachment означает, что браузер должен скачать файл, а не отобразить его в своём окне.
multipart сообщения (с разными boundary) могут быть вложены друг в друга. Получается целое дерево вложенных документов. Таким образом можно даже закодировать целый HTML со всеми сопутствующими картинками и стилями.
MIME multipart
Помните о MIME. Даже стандарты, которым уже больше тридцати лет, вполне себе существуют и работают где-то рядом. А MIME тип — это вообще штука, которая встречается на каждом шагу.

2016-03-05

О кружках

В далёком советском детстве как-то не принято было целый день сидеть за телевизором, потому что показывали лишь два государственных телеканала, целый день играть в компьютерные игры, потому что компьютеров ещё не было, целый день шляться по улице, потому что были кружки, с ударением на последний слог. Как-то даже у нас в классе возникло распоряжение, чтобы все записались хоть в какой-нибудь кружок.
Целиноград. Дворец целинников
Жили мы в маленьком посёлке, что-то около двух тысяч жителей, специально построенном для работников аэропорта. В одну сторону, километра через три-четыре, — аэропорт. В другую сторону, километров через пятнадцать-двадцать, — городишко. А вокруг — степь, абсолютно ровный горизонт. Так что все друг друга знали и бежать особо было некуда.
Целиноград. Площадь имени В. И. Ленина
А кружки, один дворовый клуб на весь посёлок, находились в общаге. Все самые интересные пацанские кружки конечно же базировались в подвале.
Спускаешься в подвал с торца дома и первыми встречаешь картингистов. У них было несколько настоящих картов. И они на них даже иногда устраивали соревнования. Но ещё у них была куча железяк, сварочный аппарат и другие крутые штуки. И изо всякого хлама они строили чудные машины. Какой-нибудь трёхколесный агрегат, на громадных колёсах. Эти агрегаты ездили очень редко, потому что постоянно перестраивались.
Дальше по подвалу был авиамодельный кружок. Ребята делали и запускали кордовые авиамодели. Но их мечтой было сделать свободнолетающую радиоуправляемую модель. Они её и делали, только я не помню, чтобы она летала. А ещё они делали ракеты. Маленькие такие, с твёрдотопливным двигателем. Взлетает на несколько десятков метров, а потом спускается на парашюте.
В конце подвала был фотокружок. Раньше фотография была вовсе не цифровая. Нужна была фотоплёнка. Она заправлялась в фотоаппарат. И ты бегал с фотоаппаратом, тщательно выискивая сюжеты. Ибо кадров лишь 36. Потом плёнку полагалось извлечь из фотоаппарата и проявить. Потом с плёнки печатались фотографии, с помощью фотоувеличителя, в темноте, в свете красных фонарей. А все эти проявители и фиксажи для фотоплёнки и фотобумаги смешивались тут же по рецепту из секретных химических реагентов. Романтика. По результатам работы фотокружка устраивались фотовыставки.
Целиноград
С другой стороны подвала был отдельный вход. Нас, малышню, туда не пускали. Там дислоцировалась местная музыкальная группа из парней-старшеклассников. С гитарами и всем прочим. Шифровались они страшно, так что их выступления были большой редкостью.
А на первом этаже общежития занимался танцевальный кружок. Мы умудрялись залезать на подоконники, что было довольно высоко, чтобы посмотреть, как девчонки тренируются.
Целиноград
Со стороны деятельность наших кружков была слабо заметна. Но как минимум раз в год, на День Защиты Детей, 1 июня, устраивался большущий концерт. Музыкальная группа играла музыку. Девчонки из танцевального кружка танцевали. Авиамоделисты пускали ракеты и самолёты. Картингисты гоняли на картах. А фотокружок всё это дело фотографировал.
А руководили этими кружками обычные мужики, коллеги моих родителей, тоже работающие в аэропорту.
Целиноград. Дворец молодежи
И вот, когда партия потребовала вступить в какой-нибудь кружок, я выбрал фотографию. Сначала фотал Сменой, потом папа раздобыл Зенит. Получалось вроде неплохо. Проблемой было найти достойные кадры. Бывало, месяцами плёнка в фотоаппарате тухла. Но вот запираться в конце подвала в тёмноте и творить магию, это было круто.
Целиноград
Потом наступили лихие девяностые и аэропорт, чтобы выжить, огранизовал рейсы в Дубаи, что в Объединённых Арабских Эмиратах. Лётчики, что туда летали, получали неплохие деньги. А ещё они возили бытовую технику: телевизоры, видеомагнитофоны и видеокамеры.
Так фотокружок обзавёлся своей видеокамерой. Мы даже выбирали её по буржуйским каталогам. И выбрали не какой-нибудь банальный VHS, а камеру крутого формата Video 8. Так фотокружок превратился в фотовидеокружок. И так случилось, что я был главным видеооператором. Ибо дослужился до старшего в кружке. Я снимал все эти мероприятия 1 июня. Я даже брал видеокамеру домой, чтобы изучить её возможности.
Целиноград
А потом кружки ушли куда-то из моей жизни. Наверное, стал старше. Интересно, жив ли ещё этот дворовый клуб? Мне почему-то кажется, что нет.