gpt4 book ai didi

Python - 如果服务器在 PUT 完成之前回答,则 HTTP 模块无法解析响应

转载 作者:行者123 更新时间:2023-12-03 16:27:41 25 4
gpt4 key购买 nike

我正在使用 requests (使用 urllib3 和底层的 Python http 模块)库从 Python 脚本上传文件。
我的后端首先检查请求的 header ,如果它不符合所需的先决条件,它会立即停止请求并以有效的 400 响应进行响应。
这种行为在 Postman 或 Curl 中运行良好;即客户端能够解析 400 响应,即使它还没有完成上传并且服务器过早地回答。
但是,在 Python 中使用 requests 执行此操作时/urllib3 ,库无法处理后端响应:

Traceback (most recent call last):
File "C:\Users\Neumann\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\urllib3\connectionpool.py", line 670, in urlopen
httplib_response = self._make_request(
File "C:\Users\Neumann\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\urllib3\connectionpool.py", line 392, in _make_request
conn.request(method, url, **httplib_request_kw)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.1776.0_x64__qbz5n2kfra8p0\lib\http\client.py", line 1255, in request
self._send_request(method, url, body, headers, encode_chunked)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.1776.0_x64__qbz5n2kfra8p0\lib\http\client.py", line 1301, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.1776.0_x64__qbz5n2kfra8p0\lib\http\client.py", line 1250, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.1776.0_x64__qbz5n2kfra8p0\lib\http\client.py", line 1049, in _send_output
self.send(chunk)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.1776.0_x64__qbz5n2kfra8p0\lib\http\client.py", line 971, in send
self.sock.sendall(data)
ConnectionResetError: [WinError 10054] Une connexion existante a dû être fermée par l’hôte distant
因为服务器在传输完成之前应答,所以它错误地认为连接已经中止,即使服务器确实返回了有效的响应。
有没有办法避免这种情况并解析响应?
重现问题的步骤:
  • 下载minIO:https://min.io/download#/
  • 运行 minIO:
  • export MINIO_ACCESS_KEY=<access_key>
    export MINIO_SECRET_KEY=<secret_key>
    .\minio.exe server <data folder>
  • 运行以下脚本:
  • import os
    import sys
    import requests
    from requests_toolbelt.multipart.encoder import MultipartEncoder

    def fatal(msg):
    print(msg)
    sys.exit(1)

    def upload_file():
    mp_encoder = MultipartEncoder(fields={'file': (open('E:/Downloads/kek.mp3', 'rb'))})
    headers = { "Authorization": "invalid" }

    print('Uploading file with headers : ' + str(headers))

    upload_endpoint = 'http://localhost:9000/mybucket/myobject'
    try:
    r = requests.put(upload_endpoint, headers=headers, data=mp_encoder, verify=False)
    except requests.exceptions.ConnectionError as e:
    print(e.status)
    for property, value in vars(e).items():
    print(property, ":", value)
    fatal(str(e))

    if r.status_code != 201:
    for property, value in vars(r).items():
    print(property, ":", value)
    fatal('Error while uploading file. Status ' + str(r.status_code))
    print('Upload successfully completed')

    if __name__ == "__main__":
    upload_file()

    如果您使用此更改请求行,它将起作用(即服务器返回 400 并且客户端能够解析它):
    r = requests.put(upload_endpoint, headers=headers, data='a string', verify=False)
    编辑 :我更新了回溯并更改了问题标题以反射(reflect)它既不是 requests 的事实。或 urllib3错误,但是他们俩都使用了Python http模块。

    最佳答案

    这个问题应该在 urllib3 v1.26.0 中修复.你运行的是什么版本?
    问题是服务器在响应 400 后关闭了连接,因此当 urllib3 尝试继续向其发送数据时,套接字将关闭。因此,实际上并没有错误地认为连接已关闭,它只是错误地处理了这种情况。
    您的示例代码在我的 urllib3==1.26.0 机器上运行良好。但是我注意到您在 Windows 机器上遇到了一个不同的异常,因此该修复程序可能不起作用。在这种情况下,我会捕获异常并向 urllib3 的维护者提交错误报告。

    关于Python - 如果服务器在 PUT 完成之前回答,则 HTTP 模块无法解析响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65491229/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com