使用瓶子(或烧瓶或类似物)上传文件

Tom*_*šek 11 python rest file-upload bottle

我有一个使用Python/Bottle编写的REST前端来处理文件上传,通常是大文件上传.API以这样一种方式得到:

客户端将PUT作为有效负载发送给文件.除其他外,它发送日期和授权标头.这是针对重播攻击的安全措施 - 请求使用临时密钥,使用目标网址,日期和其他一些内容进行烧录

现在问题.如果提供的日期在15分钟的给定日期时间窗口中,则服务器接受请求.如果上传需要足够长的时间,则会比允许的时间增量更长.现在,使用装饰器瓶视图方法完成请求授权处理.但是,除非上传完成,否则瓶子不会启动调度过程,因此验证会在较长的上载时失败.

我的问题是:有没有办法解释瓶子或WSGI立即处理请求并流式传输上传?由于其他原因,这对我也很有用.或任何其他解决方案?在我写这篇文章时,我想到了WSGI中间件,但我仍然喜欢外部洞察力.

我愿意切换到Flask,甚至其他Python框架,因为REST前端非常轻量级.

谢谢

pet*_*urg 19

我建议将传入的文件拆分为前端的较小大小的块.我这样做是为了在Flask应用程序中实现大文件上传的暂停/恢复功能.

使用Sebastian Tschan的jquery插件,您可以通过指定maxChunkSize初始化插件时实现分块,如下所示:

$('#file-select').fileupload({
    url: '/uploads/',
    sequentialUploads: true,
    done: function (e, data) {
        console.log("uploaded: " + data.files[0].name)
    },
    maxChunkSize: 1000000 // 1 MB
});
Run Code Online (Sandbox Code Playgroud)

现在,客户端将在上传大文件时发送多个请求.并且您的服务器端代码可以使用Content-Range标头将原始大文件一起修补.对于Flask应用程序,视图可能类似于:

# Upload files
@app.route('/uploads/', methods=['POST'])
def results():

    files = request.files

    # assuming only one file is passed in the request
    key = files.keys()[0]
    value = files[key] # this is a Werkzeug FileStorage object
    filename = value.filename

    if 'Content-Range' in request.headers:
        # extract starting byte from Content-Range header string
        range_str = request.headers['Content-Range']
        start_bytes = int(range_str.split(' ')[1].split('-')[0])

        # append chunk to the file on disk, or create new
        with open(filename, 'a') as f:
            f.seek(start_bytes)
            f.write(value.stream.read())

    else:
        # this is not a chunked request, so just save the whole file
        value.save(filename)

    # send response with appropriate mime type header
    return jsonify({"name": value.filename,
                    "size": os.path.getsize(filename),
                    "url": 'uploads/' + value.filename,
                    "thumbnail_url": None,
                    "delete_url": None,
                    "delete_type": None,})
Run Code Online (Sandbox Code Playgroud)

对于您的特定应用程序,您只需确保每个请求仍然发送正确的auth标头.

希望这可以帮助!我有一段时间在这个问题上苦苦挣扎;)