使用奶瓶流文件上传(或瓶或类似)(Streaming file upload using bottl

2019-07-20 10:00发布

我有使用Python编写的REST前端/瓶用来处理文件上传,通常路数。 该API wirtten以这样的方式:

客户端发送PUT与该​​文件作为有效载荷。 除其他事项外,它发送日期和授权头。 这是针对重放攻击安全措施 - 请求被烧焦了临时密钥,使用目标URL,日期和其他几件事情

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

我的问题是:有没有办法来解释瓶或WSGI立即处理该请求,并为它去流上传? 这将为其他原因对我也有帮助。 或任何其他解决办法? 当我写这个,WSGI中间件想到了,不过,我想外界的见解。

我愿意转瓶,甚至是其他Python框架,因为REST前端是相当轻巧。

谢谢

Answer 1:

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

使用塞巴斯蒂安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
});

现在,上传大文件时,客户端将发送多个请求。 和你的服务器端代码可以使用的Content-Range头修补原来的大文件重新走到一起。 对于瓶的应用程序,视图可能看起来是这样的:

# 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,})

为了您的特定应用程序,你只需要确保正确的AUTH头仍与每个请求一起发送。

希望这可以帮助! 我被这个问题困扰了一边挣扎;)



Answer 2:

当使用plupload解决方案可能是像这样的:

$("#uploader").plupload({
    // General settings
    runtimes : 'html5,flash,silverlight,html4',
    url : "/uploads/",

    // Maximum file size
    max_file_size : '20mb',

    chunk_size: '128kb',

    // Specify what files to browse for
    filters : [
        {title : "Image files", extensions : "jpg,gif,png"},
    ],

    // Enable ability to drag'n'drop files onto the widget (currently only HTML5 supports that)
    dragdrop: true,

    // Views to activate
    views: {
        list: true,
        thumbs: true, // Show thumbs
        active: 'thumbs'
    },

    // Flash settings
    flash_swf_url : '/static/js/plupload-2.1.2/js/plupload/js/Moxie.swf',

    // Silverlight settings
    silverlight_xap_url : '/static/js/plupload-2.1.2/js/plupload/js/Moxie.xap'
});

在这种情况下,您的水壶,Python代码将类似于此:

from werkzeug import secure_filename

# Upload files
@app.route('/uploads/', methods=['POST'])
def results():
    content = request.files['file'].read()
    filename = secure_filename(request.values['name'])

    with open(filename, 'ab+') as fp:
        fp.write(content)

    # send response with appropriate mime type header
    return jsonify({
        "name": filename,
        "size": os.path.getsize(filename),
        "url": 'uploads/' + filename,})

Plupload总是发送块中完全相同的顺序,从第一个到最后,所以你不要有求之类的东西来打扰。



文章来源: Streaming file upload using bottle (or flask or similar)