В архиве .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())
Обратите внимание, что эта функция читает загружаемый файл, поэтому потоковая загрузка может "съесть" часть потока, что может помешать использовать файл после определения его типа.