服务器未完全使用请求正文时连接重置
Connection reset when server doesn't fully consume request body
我现在从 another SO answer and from the uWSGI documentation 中了解了此问题的一般原因,其中指出:
If an HTTP request has a body (like a POST request generated by a
form), you have to read (consume) it in your application. If you do
not do this, the communication socket with your webserver may be
clobbered.
但是,我不明白在 TCP 级别到底发生了什么导致这个问题发生。不知道这个过程的细节,我假设服务器可以简单地丢弃流中剩余的内容,但显然不是这样。
如果我在我的应用程序中仅使用部分请求正文并最终 return 200 响应,网络浏览器将报告连接重置错误。谁重置了连接?网络服务器还是客户端?似乎客户端已经发送了所有数据,但应用程序还没有耗尽流。当应用程序中的流耗尽时,是否会发生某些情况,触发网络服务器指示它已完成读取?
我的应用程序是 Python/Flask,但我从多种语言和框架中看到了有关此问题的问题。例如,如果未在请求流上调用 exhaust()
,则会失败:
@app.route('/upload', methods=['POST'])
def handle-upload():
file = request.stream
pandas.read_csv(file, nrows=100)
response = # Do stuff
file.exhaust()
return jsonify(response)
虽然在整个链中有一些缓冲,但大文件传输要等到接收方使用完它们才会完成。缓冲区将填满,并且数据包将被丢弃,直到缓冲区被耗尽。最终,浏览器将放弃尝试发送文件并断开连接。
我现在从 another SO answer and from the uWSGI documentation 中了解了此问题的一般原因,其中指出:
If an HTTP request has a body (like a POST request generated by a form), you have to read (consume) it in your application. If you do not do this, the communication socket with your webserver may be clobbered.
但是,我不明白在 TCP 级别到底发生了什么导致这个问题发生。不知道这个过程的细节,我假设服务器可以简单地丢弃流中剩余的内容,但显然不是这样。
如果我在我的应用程序中仅使用部分请求正文并最终 return 200 响应,网络浏览器将报告连接重置错误。谁重置了连接?网络服务器还是客户端?似乎客户端已经发送了所有数据,但应用程序还没有耗尽流。当应用程序中的流耗尽时,是否会发生某些情况,触发网络服务器指示它已完成读取?
我的应用程序是 Python/Flask,但我从多种语言和框架中看到了有关此问题的问题。例如,如果未在请求流上调用 exhaust()
,则会失败:
@app.route('/upload', methods=['POST'])
def handle-upload():
file = request.stream
pandas.read_csv(file, nrows=100)
response = # Do stuff
file.exhaust()
return jsonify(response)
虽然在整个链中有一些缓冲,但大文件传输要等到接收方使用完它们才会完成。缓冲区将填满,并且数据包将被丢弃,直到缓冲区被耗尽。最终,浏览器将放弃尝试发送文件并断开连接。