使用Flask-Uploads拒绝大于特定大小的文件?

7
Flask推荐使用Flask-Uploads模块来处理上传。我想拒绝任何超过一定大小的文件。有一些解决方案在流传: 从文档中可以看到:
此外,您还可以使用patch_request_class来修补应用程序的request_class,以设置上传的最大大小。
patch_request_class(app, 32 * 1024 * 1024)

来自这篇SO文章:

MAX_CONTENT_LENGTH是拒绝上传文件超过您所需大小的正确方法。

app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024

# save to disk first, then check filesize
request.files['file'].save('/tmp/foo')
size = os.stat('/tmp/foo').st_size

-或-

# save to memory, then check filesize
blob = request.files['file'].read()
size = len(blob)

我没有在官方文档中看到提到MAX_CONTENT_LENGTH,也没有像SO帖子一样手动检查文件大小。这两种方法最终是相同的,还是存在(大/微妙的)差别?此外,patch_request_class会首先将文件保存到磁盘以确定总上传大小,还是保存到内存?

你已经接受了!对于检查大小限制,不要浪费带宽。https://dev59.com/0nI-5IYBdhLWcg3w8dUQ - dsgdfg
2个回答

11

MAX_CONTENT_LENGTH是Flask本身的配置项,从0.6版本开始引入。请参考http://flask.pocoo.org/docs/0.10/patterns/fileuploads/#improving-uploads了解如何改善文件上传。

By default Flask will happily accept file uploads to an unlimited amount of memory, but you can limit that by setting the MAX_CONTENT_LENGTH config key:

from flask import Flask, Request

app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024

The code above will limited the maximum allowed payload to 16 megabytes. If a larger file is transmitted, Flask will raise an RequestEntityTooLarge exception.

This feature was added in Flask 0.6 but can be achieved in older versions as well by subclassing the request object. For more information on that consult the Werkzeug documentation on file handling.

以下是来自Flask-Uploads源代码:

https://bitbucket.org/leafstorm/flask-uploads/src/440e06b851d24811d20f8e06a8eaf5c5bf58c241/flaskext/uploads.py?at=default
def patch_request_class(app, size=64 * 1024 * 1024):
    """
    By default, Flask will accept uploads to an arbitrary size. While Werkzeug
    switches uploads from memory to a temporary file when they hit 500 KiB,
    it's still possible for someone to overload your disk space with a
    gigantic file.

    This patches the app's request class's
    `~werkzeug.BaseRequest.max_content_length` attribute so that any upload
    larger than the given size is rejected with an HTTP error.

    .. note::

       In Flask 0.6, you can do this by setting the `MAX_CONTENT_LENGTH`
       setting, without patching the request class. To emulate this behavior,
       you can pass `None` as the size (you must pass it explicitly). That is
       the best way to call this function, as it won't break the Flask 0.6
       functionality if it exists.

    .. versionchanged:: 0.1.1

    :param app: The app to patch the request class of.
    :param size: The maximum size to accept, in bytes. The default is 64 MiB.
                 If it is `None`, the app's `MAX_CONTENT_LENGTH` configuration
                 setting will be used to patch.
    """
    if size is None:
        if isinstance(app.request_class.__dict__['max_content_length'],
                      property):
            return
        size = app.config.get('MAX_CONTENT_LENGTH')
    reqclass = app.request_class
    patched = type(reqclass.__name__, (reqclass,),
                   {'max_content_length': size})
    app.request_class = patched

我建议选择:

app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024

patch_request_class 只是为了向后兼容性而存在的吗? - rublex

3

patch_request_class只是为了向后兼容而存在。

从Flask 0.6开始,您应该使用app.config['MAX_CONTENT_LENGTH']

我最近接手了Flask-Uploads项目的维护工作,我所做的第一件事就是在此提交中删除了patch_request_class,因为它只会给新项目增加困惑。任何依赖它的旧项目都应该在其requirements.txt文件中固定Flask-Uploads==0.1.3


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接