我正在使用django验证器和python-magic来检查上传文档的mime类型,并且只接受pdf,zip和rar文件。
接受的mime类型是: “应用程序/ PDF”, 'application / zip','multipart / x-zip','application / x-zip-compressed','application / x-compressed', 'application / rar','application / x-rar''application / x-rar-compressed','compressed / rar',
问题在于,有时pdf文件似乎将'application / octet-stream'作为mime-type。 'application / octet-stream'表示通用二进制文件,所以我不能简单地将mime类型添加到接受文件列表中,因为在这种情况下也会接受其他文件,例如es excel文件,我不想要那会发生。
在这种情况下我该怎么做?
提前致谢。
答案 0 :(得分:0)
您不应该依赖提供的MIME类型,而应该依赖于从文件本身的前几个字节中发现的MIME类型。
这有助于消除通用的MIME类型问题。
这种方法的问题在于它通常依赖于某些第三方工具(例如Linux系统中常见的file
命令很棒;与-b --mime -
一起使用并传入第一个你文件的几个字节让它给你mime类型。)
您拥有的另一个选择是接受该文件,并尝试通过使用库打开它来验证它。
因此,如果pypdf
无法打开文件,并且内置的zip
模块无法打开文件,并且rarfile
无法打开文件 - 最有可能是您不知道的事情# 39;我想接受。
答案 1 :(得分:0)
最简单的说法是通过在文件头中读取元数据来窥探文件内容。
在大多数文件中,此文件标题通常存储在文件的开头,但在某些文件中,它可能位于其他位置。
python-magic
可以帮助你做到这一点,但诀窍是在尝试猜测其mime类型之前始终将指针重置在文件的开头,否则你有时会得到appliation / octet-stream mime如果读者的指针已超过文件头位置,则输入到只包含任意字节流的其他位置。
例如,如果你有一个django验证器函数试图验证mime类型的上传文件:
import magic
from django.core.exceptions import ValidationError
def validate_file_type(upload):
allowed_filetypes = [
'application/pdf', 'image/jpeg', 'image/jpg', 'image/png',
'application/msword']
upload.seek(0)
file_type = magic.from_buffer(upload.read(1024), mime=True)
if file_type not in allowed_filetypes:
raise ValidationError(
'Unsupported file')
答案 2 :(得分:0)
作为对Liyosi答案的跟进,我还使用了python-magic
。 libmagic似乎存在一个错误,它仍然错误地将某些文件标识为application/octet-stream
在code
def _handle509Bug(self, e):
# libmagic 5.09 has a bug where it might fail to identify the
# mimetype of a file and returns null from magic_file (and
# likely _buffer), but also does not return an error message.
if e.message is None and (self.flags & MAGIC_MIME):
return "application/octet-stream"
else:
raise e
要解决此问题,我必须实例化一个魔术对象并使用uncompressed
和mime
属性。要完成Liyosi示例,请执行以下操作:
import magic
from django.core.exceptions import ValidationError
def validate_file_type(upload):
allowed_filetypes = [
'application/pdf', 'image/jpeg', 'image/jpg', 'image/png',
'application/msword']
validator = magic.Magic(uncompress=True, mime=True)
file_type = validator.from_buffer(upload.read(), mime=True)
if file_type not in allowed_filetypes:
raise ValidationError('Unsupported file')