2015-02-12 20 views
0

我使用django驗證器和python-magic來檢查上傳文件的MIME類型並只接受pdf,zip和rar文件。用django表格檢查文件類型:'application/octet-stream'問題

接受的mime類型是: '應用/ PDF', '應用程序/壓縮', '多部分/ X-ZIP', '應用程序/ x-ZIP壓縮的', '應用程序/ x壓縮', '應用/ RAR', '應用程序/ x-RAR' '應用程序/ x-RAR壓縮的', '壓縮/ RAR',

的問題是,有時PDF文件似乎有「應用程序/八位字節流'爲啞劇式。 'application/octet-stream'表示通用的二進制文件,所以我不能簡單地將該MIME類型添加到接受文件列表中,因爲在這種情況下,其他文件(如EXCEL文件)也會被接受,而且我不希望這種事情發生。

在這種情況下我該怎麼辦?

在此先感謝。

回答

0

您不應該依賴提供的MIME類型,而應該依賴從文件本身的前幾個字節中發現的MIME類型。

這將有助於消除通用MIME類型問題。

這種方法的問題是,它通常會依靠一些第三方工具(例如在Linux系統中常見的file命令是偉大的;與-b --mime -使用它,並通過在文件的前幾個字節有它給你的MIME類型)。

您擁有的其他選項是接受該文件,並嘗試通過打開庫來驗證該文件。

所以,如果pypdf無法打開文件,並內置zip模塊無法打開該文件,rarfile無法打開文件 - 其最有可能的東西,你不想接受。

+0

我不依賴於所提供的MIME類型。 我已經閱讀了前幾個字節來發現它,用python-magic: mime = magic.from_buffer(value.read(1024),mime = True) 但是這種方法有時會給出「application/octet-stream」 – sabrina 2015-02-12 10:12:53

+0

去第二個選項。 – 2015-02-12 10:14:16

0

通過在文件頭中讀取其元數據來窺探文件內容,最愚蠢的方式是告知。

在大多數文件中,這個文件頭通常存儲在文件的開頭,儘管在一些文件中它可能位於其他位置。

python-magicpython-magic幫助你做到這一點,但訣竅是在試圖猜測它的MIME類型之前總是重置指針在文件的開頭,否則你有時會得到appliation/octet-stream MIME類型,如果閱讀器的指針已經超過文件頭位置前進到其他只包含任意字節流的位置。

例如,如果你有嘗試驗證上傳的文件MIME類型Django的驗證功能:

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')