【发布时间】:2016-02-25 19:32:54
【问题描述】:
总结:我正在使用 Blobstore 让用户上传要提供的图像。我想阻止用户上传无效图像或尺寸过大的文件。我正在使用 App Engine 的图像服务来获取相关的元数据。但是,为了从图像服务获取有关图像类型或尺寸的任何信息,您必须首先执行转换,将转换后的图像提取到 App Engine 服务器。我让它进行无操作裁剪并编码为质量非常低的 JPEG 图像,但它仍在获取实际图像,我想要的只是尺寸和文件类型。这是我能做的最好的吗?图片数据的内部传输(从 Blobstore 到 App Engine 服务器)会花费我吗?
详情:
Blobstore 似乎经过精心设计,可以有效地提供来自 App Engine 的图像。另一方面,某些操作似乎会让你跳过低效的圈子。我希望有人能告诉我有更有效的方法,或者让我相信我正在做的事情并没有我想象的那么浪费。
我让用户上传图片以作为其他用户生成内容的一部分。 Blobstore 使上传和服务变得非常容易。不幸的是,它允许用户上传他们想要的任何文件,我想施加限制。
(旁注:Blobstore 确实允许您限制上传的文件大小,但此功能的文档很少。事实证明,如果用户尝试超过限制,Blobstore 将返回 413“实体太大”,并且根本不调用 App Engine 处理程序。)
我只想允许有效的 JPEG、GIF 和 PNG 文件,并且我想限制尺寸。这样做的方法似乎是在上传后检查文件,如果不允许则将其删除。这是我得到的:
class ImageUploadHandler(blobstore_handlers.BlobstoreUploadHandler):
def post(self):
try:
# TODO: Check that user is logged in and has quota; xsrfToken.
uploads = self.get_uploads()
if len(uploads) != 1:
logging.error('{} files uploaded'.format(len(uploads)))
raise ServerError('Must be exactly 1 image per upload')
image = images.Image(blob_key=uploads[0].key())
# Do a no-op transformation; otherwise execute_transforms()
# doesn't work and you can't get any image metadata.
image.crop(0.0, 0.0, 1.0, 1.0)
image.execute_transforms(output_encoding=images.JPEG, quality=1)
if image.width > 640 or image.height > 640:
raise ServerError('Image must be 640x640 or smaller')
resultUrl = images.get_serving_url(uploads[0].key())
self.response.headers['Content-Type'] = 'application/json'
self.response.body = jsonEncode({'status': 0, 'imageUrl': resultUrl})
except Exception as e:
for upload in uploads:
blobstore.delete(upload.key()) # TODO: delete in parallel with delete_async
self.response.headers['Content-Type'] = 'text/plain'
self.response.status = 403
self.response.body = e.args[0]
代码中的注释突出了问题。
我知道图片可以在投放时动态调整大小(使用 get_serving_url),但我宁愿强制用户首先上传较小的图片,以避免耗尽存储空间。后来,我可能不想限制原始图像的尺寸,而是让它在上传时自动缩小,但我仍然需要在缩小之前找出它的尺寸和类型。
我错过了更简单或更有效的方法吗?
【问题讨论】:
-
你见过get_serving_url吗? cloud.google.com/appengine/docs/python/refdocs/… 可能会解决一些调整大小等问题。
-
@PaulCollingwood 是的,如果你仔细看的话,我在上面的代码中使用了 get_serving_url。它不能解决我要问的问题。
-
原来如此。太多而无法详细查看,删除与问题无关的所有内容?您是否考虑过在客户端执行此操作?你信任你的用户吗?我不确定你真正在问什么。如果你想检查某个东西是否真的是一个图像,你必须做类似的事情。您还可以检查数据的前几个字节以查看它是否可能是图像:docs.python.org/2/library/imghdr.html
-
我相信这几乎都是相关的,但你说得对,这个问题需要消化很多。我将重新组织以突出中心点。
-
@PaulCollingwood,我将最重要的内容移到顶部并删除了 3 行错误的代码,以及一些问题文本。用户通常不受信任。我不相信客户端检查会提供我想要的安全级别。
标签: image google-app-engine blobstore