Windows 上的请求和请求工具带抛出 UnicodeDecodeError
Requests and Requests-toolbelt on Windows throws UnicodeDecodeError
此代码在 unix 服务器之间运行良好,但当客户端为 Windows 时,服务器始终抛出 UnicodeDecodeError,如下面的堆栈跟踪所示。我无法弄清楚为什么 requests 试图解码文件对象。 Windows 客户端上的 temp_file
似乎采用不同的形式,因此当请求到达服务器时编码不同。任何线索都会很棒。
# client-side (Windows) - some code omitted for brevity
temp_file = TemporaryFile()
temp_file.write(file.read(chunk_size))
temp_file.seek(0)
payload = MultipartEncoder(
{'uploadedFile': (path, temp_file, 'application/octet-stream'),
'position': str(position), 'chunk_size': str(chunk_size),
'chunk_number': str(chunk_number)})
r = requests.post(url, data=payload, headers={'Content-Type': payload.content_type})
temp_file.close()
# server-side (Unix)
@view_config(route_name='remote.agent_upload', renderer='json')
def remote_agent_upload(request):
r = request.response
uploadedFile = request.POST['uploadedFile'] # ERROR HERE
chunk_size = request.POST['chunk_size']
chunk_number = request.POST['chunk_number']
position = request.POST['position']
fs = uploadedFile.file
filename = uploadedFile.filename
fs.seek(0)
path = os.path.join(agent.root, os.path.basename(filename))
# remove the file if it exists
if chunk_number == '0' and os.path.isfile(path):
os.remove(path)
f = open(path, 'a+b')
f.seek(int(position))
f.write(fs.read())
fs.close()
f.close()
return r
# relevant section of traceback
Traceback (most recent call last):
File "/Volumes/Extra/Repos/env/lib/python2.7/site-packages/pyramid/config/views.py", line 501, in _requestonly_view
response = view(request)
File "/Volumes/Extra/Repos/bang/bang/remote_api.py", line 393, in remote_agent_upload
uploadedFile = request.POST['uploadedFile']
File "/Volumes/Extra/Repos/env/lib/python2.7/site-packages/webob/request.py", line 807, in POST
vars = MultiDict.from_fieldstorage(fs)
File "/Volumes/Extra/Repos/env/lib/python2.7/site-packages/webob/multidict.py", line 92, in from_fieldstorage
obj.add(field.name, decode(value))
File "/Volumes/Extra/Repos/env/lib/python2.7/site-packages/webob/multidict.py", line 78, in <lambda>
decode = lambda b: b.decode(charset)
File "/Volumes/Extra/Repos/env/lib/python2.7/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xba in position 3: invalid start byte
Pyramid 试图将您的字段视为常规非文件 POST 字段,这意味着它想要解码字段值。它这样处理是因为没有文件名,或者文件名是空的。
三次检查您上传的 path
变量。确保它是一个基本名称(不允许目录名称),并且不为空:
payload = MultipartEncoder(
{'uploadedFile': (os.path.basename(path), temp_file, 'application/octet-stream'),
'position': str(position), 'chunk_size': str(chunk_size),
'chunk_number': str(chunk_number)})
此代码在 unix 服务器之间运行良好,但当客户端为 Windows 时,服务器始终抛出 UnicodeDecodeError,如下面的堆栈跟踪所示。我无法弄清楚为什么 requests 试图解码文件对象。 Windows 客户端上的 temp_file
似乎采用不同的形式,因此当请求到达服务器时编码不同。任何线索都会很棒。
# client-side (Windows) - some code omitted for brevity
temp_file = TemporaryFile()
temp_file.write(file.read(chunk_size))
temp_file.seek(0)
payload = MultipartEncoder(
{'uploadedFile': (path, temp_file, 'application/octet-stream'),
'position': str(position), 'chunk_size': str(chunk_size),
'chunk_number': str(chunk_number)})
r = requests.post(url, data=payload, headers={'Content-Type': payload.content_type})
temp_file.close()
# server-side (Unix)
@view_config(route_name='remote.agent_upload', renderer='json')
def remote_agent_upload(request):
r = request.response
uploadedFile = request.POST['uploadedFile'] # ERROR HERE
chunk_size = request.POST['chunk_size']
chunk_number = request.POST['chunk_number']
position = request.POST['position']
fs = uploadedFile.file
filename = uploadedFile.filename
fs.seek(0)
path = os.path.join(agent.root, os.path.basename(filename))
# remove the file if it exists
if chunk_number == '0' and os.path.isfile(path):
os.remove(path)
f = open(path, 'a+b')
f.seek(int(position))
f.write(fs.read())
fs.close()
f.close()
return r
# relevant section of traceback
Traceback (most recent call last):
File "/Volumes/Extra/Repos/env/lib/python2.7/site-packages/pyramid/config/views.py", line 501, in _requestonly_view
response = view(request)
File "/Volumes/Extra/Repos/bang/bang/remote_api.py", line 393, in remote_agent_upload
uploadedFile = request.POST['uploadedFile']
File "/Volumes/Extra/Repos/env/lib/python2.7/site-packages/webob/request.py", line 807, in POST
vars = MultiDict.from_fieldstorage(fs)
File "/Volumes/Extra/Repos/env/lib/python2.7/site-packages/webob/multidict.py", line 92, in from_fieldstorage
obj.add(field.name, decode(value))
File "/Volumes/Extra/Repos/env/lib/python2.7/site-packages/webob/multidict.py", line 78, in <lambda>
decode = lambda b: b.decode(charset)
File "/Volumes/Extra/Repos/env/lib/python2.7/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xba in position 3: invalid start byte
Pyramid 试图将您的字段视为常规非文件 POST 字段,这意味着它想要解码字段值。它这样处理是因为没有文件名,或者文件名是空的。
三次检查您上传的 path
变量。确保它是一个基本名称(不允许目录名称),并且不为空:
payload = MultipartEncoder(
{'uploadedFile': (os.path.basename(path), temp_file, 'application/octet-stream'),
'position': str(position), 'chunk_size': str(chunk_size),
'chunk_number': str(chunk_number)})