В архиве .gz неправильно определен тип содержимого?

Я работаю над API, который работает с загруженными изображениями. Изображения могут быть как в виде файлов .jpg, так и в виде архивов .gz.

url = 'http://example.com/upload'
file_path = 'path/to/my/file.gz'
files = {'file': open(file_path, 'rb')}
response = requests.post(url, files=files)

Как правильно определить, является ли файл jpg или gz архивом?

def post(self, request):  
    for _, file_data in request.FILES.items():
        print(file_data.content_type)
        if file_data.content_type == 'application/gzip':
            # do something
        elif file_data.content_type.startswith('image/'):
            # do something

Проблема с этим кодом в том, что после печати он отображает 'application/octet-stream', и я не понимаю, почему.

Таблица .content_type [Django-doc] не является MIME-типом, проверяемым Django/Python, это то, что говорит браузер. Если он на самом деле не знает, или ему все равно, или его подделывают, то он отличается, как указано в документации:

Заголовок типа содержимого загружаемого вместе с файлом (например, text/plain или application/pdf). Как и в случае с любыми данными, предоставленными пользователем, вы не должны доверять тому, что загруженный файл действительно относится к этому типу. Вам все равно придется проверить, что файл содержит содержимое, о котором заявляет заголовок content-type - "доверяй, но проверяй"

.

Мы можем попытаться угадать mimetype на основе содержимого файла с помощью python-magic [pypi.org]:

import magic

mime = magic.Magic(mime=True)
result = mime.from_descriptor(file_data.open())

Обратите внимание, что эта функция читает загружаемый файл, поэтому потоковая загрузка может "съесть" часть потока, что может помешать использовать файл после определения его типа.

Вернуться на верх