【发布时间】:2020-10-14 13:42:54
【问题描述】:
我有一个 Flask 应用程序,它应该提供一个端点来下载一个大文件。但是,必须先通过 HTTP 从另一台服务器下载此文件,而不是从文件系统提供或即时生成文件。
当然,我可以先向外部服务器执行 GET 请求,完全下载文件并将其存储在文件系统或内存中,然后作为第二步提供原始请求的结果。例如,这看起来像这样(还包括基本身份验证,以表明为什么较低层上的简单代理是不够的):
#!flask/bin/python
from flask import Flask, jsonify
import os
import requests
from requests.auth import HTTPBasicAuth
app = Flask(__name__)
@app.route('/download')
def download():
auth = HTTPBasicAuth("some_user", "some_password")
session = requests.Session()
session.auth = auth
response = session.get("http://example.com")
return response.content
if __name__ == '__main__':
app.run(host='0.0.0.0', port=1234, debug=True)
但是,这会增加应用程序的延迟和存储需求。而且,即使接收方只需要执行文件的部分下载(即执行 HTTP 范围请求),也必须首先从外部服务器完全获取。
有没有更优雅的选择来解决这个问题,即支持直接转发到外部服务器的 HTTP 范围请求?
【问题讨论】:
-
你看过StringIO吗?
-
@koalo PATCH 可用于恢复带有内容范围标头的上传。
-
@IMCoins 是的,我知道 StringIO,但我承认我不知道如何将这些部分组合在一起。我可以在 Flask 中只返回一个 StringIO 对象,然后它会自动支持部分下载吗?
-
@ShakaFlex PATCH 不是用于部分修改(客户端到服务器)而不是部分下载(服务器到客户端)吗?
-
@koalo 另一种可能更容易实现的方式是将中间服务器转换为 HTTP 代理。让客户端浏览器和端服务器完成剩下的工作。中介的唯一资源成本主要是网络。