如果网络服务器 returns 错误但仅在上传大文件时请求库引发 ConnectionError
Requests library raises ConnectionError if web-server returns error but only when uploading large file
我是 运行 一个基于 Bottle 框架的网络服务器。该框架公开了一个端点,您可以在其中上传文件。有时,如果磁盘已满,网络服务器应该 return 代码 429 而不是读取文件。出于某种原因,当我上传文件时,如果服务器尝试 return 429 状态代码,则会引发以下异常:
File "../hooks.py", line 325, in post_video_content
response = requests.post(url, data=fh)
File "/usr/local/lib/python2.7/site-packages/requests/api.py", line 110, in post
return request('post', url, data=data, json=json, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/api.py", line 56, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/sessions.py", line 488, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/sessions.py", line 609, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/adapters.py", line 473, in send
raise ConnectionError(err, request=request)
ConnectionError: ('Connection aborted.', error(32, 'Broken pipe'))
但是如果尝试完全相同的 post 但不是 post 文件我只是 post 一些少量的数据,我实际上从请求中得到了一个响应对象我可以检查状态代码。
重现:
webserver.py
from bottle import Bottle, route, run, request, response, get, post, put, abort
@post('/content')
@authenticate
def content():
response.status = 429
return "failed to write incoming movie to temp file (space might be full temporarily)"
run(host="127.0.0.1", port=8080, debug=True)
send_request.py
import requests
# this works and prints the status code
ret = requests.post("127.0.0.1:8080/content", data="sdfsdfsdfsdf")
print ret.status_code
# this part will throw an exception
try:
with open("~/some_large_video_file.mp4", 'rb') as fh:
ret = requests.post('127.0.0.1:8080/content', data=fh)
except:
print traceback.format_exc()
编辑 - 我发现这取决于数据量。如果您尝试 post 类似 10KB 的数据,我们会得到 429 return 代码。我试图弄清楚导致它开始引发异常的限制是什么。
EDIT2 - 所以看起来魔法文件大小介于 117K 和 131K 之间。如果我尝试前者,它会按预期工作,我会收到请求的响应并可以访问状态代码。如果我尝试前者,我会引发异常。
我的问题是:
- 为什么会这样?是瓶子里的虫子吗?请求中的错误?为什么我正在 posting 的 size/type 数据会改变响应?
- 有什么办法可以解决这个问题吗?我正在尝试将
ConnectionError
异常与服务器关闭相关联,并将 429 响应代码表示磁盘已满。如果我对两者都遇到相同的异常,我无法区分阻止我实施回退以等待磁盘 space 打开 的情况之间的区别
所以我将此交叉发布到请求 github 问题页面,看起来问题出在请求构建于其上的 httplib
模块中,所以这是一个 no -暂时修复。
我是 运行 一个基于 Bottle 框架的网络服务器。该框架公开了一个端点,您可以在其中上传文件。有时,如果磁盘已满,网络服务器应该 return 代码 429 而不是读取文件。出于某种原因,当我上传文件时,如果服务器尝试 return 429 状态代码,则会引发以下异常:
File "../hooks.py", line 325, in post_video_content
response = requests.post(url, data=fh)
File "/usr/local/lib/python2.7/site-packages/requests/api.py", line 110, in post
return request('post', url, data=data, json=json, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/api.py", line 56, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/sessions.py", line 488, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/sessions.py", line 609, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/adapters.py", line 473, in send
raise ConnectionError(err, request=request)
ConnectionError: ('Connection aborted.', error(32, 'Broken pipe'))
但是如果尝试完全相同的 post 但不是 post 文件我只是 post 一些少量的数据,我实际上从请求中得到了一个响应对象我可以检查状态代码。
重现:
webserver.py
from bottle import Bottle, route, run, request, response, get, post, put, abort
@post('/content')
@authenticate
def content():
response.status = 429
return "failed to write incoming movie to temp file (space might be full temporarily)"
run(host="127.0.0.1", port=8080, debug=True)
send_request.py
import requests
# this works and prints the status code
ret = requests.post("127.0.0.1:8080/content", data="sdfsdfsdfsdf")
print ret.status_code
# this part will throw an exception
try:
with open("~/some_large_video_file.mp4", 'rb') as fh:
ret = requests.post('127.0.0.1:8080/content', data=fh)
except:
print traceback.format_exc()
编辑 - 我发现这取决于数据量。如果您尝试 post 类似 10KB 的数据,我们会得到 429 return 代码。我试图弄清楚导致它开始引发异常的限制是什么。
EDIT2 - 所以看起来魔法文件大小介于 117K 和 131K 之间。如果我尝试前者,它会按预期工作,我会收到请求的响应并可以访问状态代码。如果我尝试前者,我会引发异常。
我的问题是:
- 为什么会这样?是瓶子里的虫子吗?请求中的错误?为什么我正在 posting 的 size/type 数据会改变响应?
- 有什么办法可以解决这个问题吗?我正在尝试将
ConnectionError
异常与服务器关闭相关联,并将 429 响应代码表示磁盘已满。如果我对两者都遇到相同的异常,我无法区分阻止我实施回退以等待磁盘 space 打开 的情况之间的区别
所以我将此交叉发布到请求 github 问题页面,看起来问题出在请求构建于其上的 httplib
模块中,所以这是一个 no -暂时修复。