6

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首先将文件保存到磁盘以确定总上传大小,还是保存到内存?

4

2 回答 2

8

MAX_CONTENT_LENGTH是 Flask 本身的一个配置项,在 0.6 版本中引入 http://flask.pocoo.org/docs/0.10/patterns/fileuploads/#improving-uploads

默认情况下,Flask 很乐意接受文件上传到无限量的内存,但您可以通过设置 MAX_CONTENT_LENGTH 配置键来限制它:

from flask import Flask, Request

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

上面的代码将允许的最大有效负载限制为 16 兆字节。如果传输更大的文件,Flask 将引发 RequestEntityTooLarge 异常。

此功能是在 Flask 0.6 中添加的,但也可以在旧版本中通过子类化请求对象来实现。有关这方面的更多信息,请参阅有关文件处理的 Werkzeug 文档。

And from the flask-uploads source: 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

So I'd say go with:

app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
于 2015-08-07T09:37:15.297 回答
3

patch_request_class was just for backwards compatibility.

From Flask 0.6 onwards you should use app.config['MAX_CONTENT_LENGTH'].

I recently took over as maintainer of the Flask-Uploads project, and one of the first things I did was remove the patch_request_class in this commit as it does nothing but add confusion for new projects. Any old projects that rely on it should just pin Flask-Uploads==0.1.3 in their requirements.txt file.

于 2015-12-15T10:12:22.147 回答