2

我正在用python在google应用程序引擎上构建一个webapp,我有以下代码,允许用户上传图像,但如果有人上传的东西不是图像代码分解因为我试图从数据中创建一个图像url,它当然不接受任何不是图像文件的东西。基本上我想知道是否有一种简单的方法来防止不上载图像文件的文件。如何防止非图像上传

class RecordPage(BlogHandler): 
    def get(self, keyid, title): 
     record = individual_record_cache(keyid) 
     upload_url = blobstore.create_upload_url('/upload/%s' % (keyid)) 
     photos = [] 
     for blobRef in record.blobRefs: 
      photos.append(images.get_serving_url(blobRef, size=None, crop=False, secure_url=None)) 

     global visits 
     user = users.get_current_user() 
     logout = users.create_logout_url(self.request.uri)  
     self.render("recordpermalink.html", user=user, logout=logout, record=record, visits=visits, photos=photos, upload_url=upload_url, keyid=keyid) 

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler): 
    def post(self, record_id): 
     upload_files = self.get_uploads('file') 
     blob_info = upload_files[0] 
     blobRef = blob_info.key() 
     record = Record.get_by_id(int(record_id)) 
     record.blobRefs.append(blobRef) 
     record.put() 
     individual_record_cache(record_id, True) 
     record_cache(True) 
     profile_record_cache(True) 
     self.redirect('/record/%s/%s' % (record_id, record.title)) 
+1

你可以添加特定的细节,以“地狱破错误代码松动”? –

回答

0

您可以尝试使用ImageMagick来识别文件。只要让上传完成,然后使用他们的命令行工具identify来查看它是否实际上是一个图像。

Here是链接到identify命令行文档。但是,我不建议你使用这样的命令。你应该使用像PythonMagick这样的包装器。

编辑:在再次查看您的问题后,您正在使用GAE。我只有GAE的Java方面的经验,但我认为由于Java GAE并没有真正的图像处理API,所以Python方面也不会。我能想到的最好的解决办法就是将这项工作从农场转移到像EC2这样的VPS。

+0

在GAE上运行的原生图像处理库允许动态识别和操纵图像。无需使用外部服务。 – mjibson

2

在上传图片或至少上传它的前几个字节之前,无法知道图片是什么。

如果要信任的文件名的文件扩展名,你可以做这样的事情:

import mimetypes 
blob_mimetype = mimetypes.guess_type(blob_info.filename)[0] 
# or just: blob_mimetype = blob_info.content_type 
if not blob_mimetype.startswith('image/'): 
    self.error(400) 

无论“打破”的代码是干什么的,如果有人想这可能不会保护你上传无效图像,或者在上传之前重命名文件以使其具有不同的文件扩展名。只有当你试图让最诚信的用户看到错误时,它才会有所帮助。理想情况下,如果“代码分解”意味着从处理程序代码中获取异常,则可以将其包装在try/except中并进行适当处理。这是更pythonic的方法,不做额外的前期计算或尝试比它更聪明。

2

您应该使用两种形式的检查(但上传完成后)。首先,MIME类型:确保它以“image/*”开头。其次,尽量用图像处理程序读取图像:

from PIL import Image 
class UploadHandler(BaseUploadHandler): 
    def post(self): 
    try: 
     upload = self.get_uploads()[0] 
     # also check mime type here 
     i = Image.open(upload.open()) # open it with PIL 
     w, h = i.size # make sure you can read its size 
    except: 
     # error stuff here, probably means it's not an image 
3
  1. 如果你安装了一个上传处理程序,那么你不能防止被上传的斑点,因为你的处理程序只调用后斑点已在Blob存储区。但是,您可以检查blob并将其删除。

  2. BLOB后上传你可以检查它是否是使用ImageService图像:

    Image image = ImagesServiceFactory.makeImageFromBlob(blobKey); 
    try { 
        image.getFormat(); 
    } catch (IllegalArgumentException e) { 
        // wrong image data - blob uploaded was not an image -> delete it 
    } 
    
+0

我想这与Python中的Images API相同?我看到如何检查格式,但我如何使用python从blobkey创建图像?我似乎无法在文档中找到它。 – clifgray