Любой способ угадать MIME-тип на Delphi XE2? - PullRequest
10 голосов
/ 25 марта 2012

Мне нужно угадать тип mime с целью заполнения заголовка «Content-Type» для некоторых загрузок файлов.

Мне не удалось найти решение для этого.

Я хочувызвать что-то вроде: GetMimeType('C:File.jpg') и получить обратно image/jpg.

Лучше всего, если есть мультиплатформа (для win / osx), но будет достаточно, если только для Windows.

Ответы [ 4 ]

9 голосов
/ 25 марта 2012

Попробуйте использовать функцию FindMimeFromData .

FindMimeFromData содержит жестко закодированные тесты для (в настоящее время 26) отдельных Типы MIME (см. Известные типы MIME ). Это означает, что если данный буфер содержит данные в формате одного из этих типов MIME, существует тест в FindMimeFromData, который разработан (путем сканирования через буфер содержание) для распознавания соответствующего типа MIME.

от urlmon.pas

function FindMimeFromData(
    pBC: IBindCtx;                      // bind context - can be nil
    pwzUrl: LPCWSTR;                    // url - can be nil
    pBuffer: Pointer;                   // buffer with data to sniff - can be nil (pwzUrl must be valid)
    cbSize: DWORD;                      // size of buffer
    pwzMimeProposed: LPCWSTR;           // proposed mime if - can be nil
    dwMimeFlags: DWORD;                 // will be defined
    out ppwzMimeOut: LPWSTR;            // the suggested mime
    dwReserved: DWORD                   // must be 0
  ): HResult; stdcall;

Также эта статья, чтобы увидеть, как это работает MIME Type Detection in Internet Explorer

7 голосов
/ 25 марта 2012

IE использует GetClassFileOrMime и FindMimeFromData API для обнаружения mime-типа данных / файлов (UrlMon единица в Delphi).

Обнаружение MIME-типа в Internet Explorer

CLSID, возвращенный из GetClassFileOrMime, может находиться в реестре в HKEY_CLASSES_ROOT\CLSID\<clsid>\MimeTypes.(также FileExtensions, FriendlyName).

Реестр также содержит базу данных MIME в: HKEY_CLASSES_ROOT\MIME\Database\Content Type.

Но так как список известных типов MIME относительно небольшой, вы можете хранить его как ресурс XML (или любой другой) и просто извлекать его оттуда.Это будет поддерживать как Windows, так и OSX.


Для операции загрузки файлов вы всегда можете просто использовать application/octet-stream.
Indy имеет класс TIdMimeTable (IdGlobal), и он использует фиксированный список плюс проверка реестра HKEY_CLASSES_ROOT (см FillMimeTable).Если совпадение не найдено, application/octet-stream используется.
Возможно, вы захотите проверить файл content на стороне сервера после загрузки файла, и не полагаться на заголовки, поскольку ContentTypeможет быть подделан на стороне клиента, а также не совпадает с реестром на стороне сервера.

6 голосов
/ 25 марта 2012

Internet Direct (Indy) содержит класс для этого:

class TIdThreadSafeMimeTable

в единице IdCustomHTTPServer

Пример кода в приложении сервера HTTP:

Response.ContentType :=
  Response.HTTPServer.MIMETable.GetFileMIMEType(FileName);
5 голосов
/ 25 марта 2012

О каких типах файлов вы говорите?Может быть, вы можете просто создать список типов, которые вы хотите поддерживать.

Я могу представить, что эти списки также доступны в Интернете, например:

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

...