Python 请求请求.exceptions.SSLError:[Errno 8] _ssl.c:504:违反协议发生 EOF

2025-03-05 09:15:00
admin
原创
81
摘要:问题描述:我在 Ubuntu 12.10 上安装了 OpenSSL 1.0.1c、python 2.7.3、Requests 1.0.3 和 1.0.4(都试过了),并尝试使用以下代码连接到 url 变量中的网站。def SendInitialRequest(xmlmessage, redirecturl):...

问题描述:

我在 Ubuntu 12.10 上安装了 OpenSSL 1.0.1c、python 2.7.3、Requests 1.0.3 和 1.0.4(都试过了),并尝试使用以下代码连接到 url 变量中的网站。

def SendInitialRequest(xmlmessage, redirecturl):
    url = 'https://centineltest.cardinalcommerce.com/maps/txns.asp'

    payload = 'cmpi_msg=' + ET.tostring(xmlmessage)
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
    }
    r = requests.post(url, data=payload, headers=headers, verify=None)
    print r.text

它引发以下错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "clams/libs/centinel/thinclient.py", line 134, in SendInitialRequest
    r = requests.post(url, data=payload, headers=headers, verify=None)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/api.py", line 87, in post
    return request('post', url, data=data, **kwargs)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/sessions.py", line 269, in request
    resp = self.send(prep, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/sessions.py", line 364, in send
    r = adapter.send(request, **kwargs)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/adapters.py", line 163, in send
    raise SSLError(e)
requests.exceptions.SSLError: [Errno 8] _ssl.c:504: EOF occurred in violation of protocol

尝试使用 openssl 连接返回以下内容:

$ openssl s_client -connect centineltest.cardinalcommerce.com:443
CONNECTED(00000003)
140019346777760:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 226 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---

如果我强制它使用 tls1,它就会起作用(输出被截断):

$ openssl s_client -tls1 -connect centineltest.cardinalcommerce.com:443
CONNECTED(00000003)
depth=2 C = US, O = "thawte, Inc.", OU = Certification Services Division, OU
verify error:num=20:unable to get local issuer certificate
verify return:0
---

我已经看到过很多关于此问题的错误报告;但是,我还没有找到使用 Python 请求库来解决这个问题的方法。如能得到任何帮助,我将不胜感激。


解决方案 1:

从请求问题页面将此内容转发给其他人:

在版本 1 之前,Requests 不支持这样做。在版本 1 之后,您需要对 HTTPAdapter 进行子类化,如下所示:

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
import ssl

class MyAdapter(HTTPAdapter):
    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = PoolManager(num_pools=connections,
                                       maxsize=maxsize,
                                       block=block,
                                       ssl_version=ssl.PROTOCOL_TLSv1)

完成上述操作后,您可以执行以下操作:

import requests
s = requests.Session()
s.mount('https://', MyAdapter())

通过该会话对象的任何请求都将使用 TLSv1。

解决方案 2:

设置 verify=False 只会跳过验证服务器证书,但无助于解决 SSL 协议错误。

此问题可能是由于 Web 服务器上禁用了 SSLv2,但 Python 2.x 默认尝试与 PROTOCOL_SSLv23 建立连接。这种情况发生在https://github.com/python/cpython/blob/360aa60b2a36f5f6e9e20325efd8d472f7559b1e/Lib/ssl.py#L1057

您可以通过覆盖 ssl_version 关键字参数来对 ssl 模块中的 ssl.wrap_socket() 进行 monkey-patch。以下代码可按原样使用。在发出任何请求之前,将其放在程序的开头。

import ssl
from functools import wraps
def sslwrap(func):
    @wraps(func)
    def bar(*args, **kw):
        kw['ssl_version'] = ssl.PROTOCOL_TLSv1
        return func(*args, **kw)
    return bar

ssl.wrap_socket = sslwrap(ssl.wrap_socket)

解决方案 3:

安装“安全”软件包附加功能requests为我解决了以下问题:

sudo apt-get install libffi-dev
sudo pip install -U requests[security]

解决方案 4:

这是一个已知的错误,你可以用 hack 来解决它:

打开site-packages/requests/packages/urllib3/connectionpool.py(或者在您自己的项目内部制作请求的本地副本),然后更改以下内容:

def connect(self):
    # Add certificate verification
    sock = socket.create_connection((self.host, self.port), self.timeout)

    # Wrap socket using verification with the root certs in
    # trusted_root_certs
    self.sock = ssl_wrap_socket(sock, self.key_file, self.cert_file,
                                cert_reqs=self.cert_reqs,
                                ca_certs=self.ca_certs,
                                server_hostname=self.host,
                                ssl_version=self.ssl_version)

到:

def connect(self):
    # Add certificate verification
    sock = socket.create_connection((self.host, self.port), self.timeout)

    # Wrap socket using verification with the root certs in
    # trusted_root_certs
    self.sock = ssl_wrap_socket(sock, self.key_file, self.cert_file,
                                cert_reqs=self.cert_reqs,
                                ca_certs=self.ca_certs,
                                server_hostname=self.host,
                                ssl_version=ssl.PROTOCOL_TLSv1)

否则,我想在某个地方存在一个不那么黑客的覆盖,但我看了好几眼也没找到。

注意:附注:requestsMacOS 上的 PIP (1.0.4) 仅适用于您提供的 URL。

解决方案 5:

我遇到了这个错误,修复方法是关闭 SNI,因为 Python 2.7 不支持它:

http://bugs.python.org/issue5639

Google App Engine 上的 python 2.7 上的 urllib3 SNI 错误

解决方案 6:

我遇到了同样的问题:

引发 SSLError(e)

request.exceptions.SSLError: [Errno 8] _ssl.c:504: 违反协议发生 EOF

我运行了 Fiddler,然后停止了 Fiddler 捕获,没有看到此错误。可能是因为 Fiddler。

解决方案 7:

对于那些无法修复上述问题的人们来说。

必须更改文件 ssl.py 才能修复此问题。查找函数 create_default_context 并更改行:

context = SSLContext(PROTOCOL_SSLv23)

context = SSLContext(PROTOCOL_TLSv1)

也许有人可以在不编辑 ssl.py 的情况下创建更简单的解决方案?

解决方案 8:

我遇到过类似的问题,我认为如果我们直接忽略ssl验证,效果会很好,就像我遇到的情况一样。因此,使用https方案连接到服务器,但指示他们不要验证证书。

使用requests。只需提及verify=False而不是None

    requests.post(url, data=payload, headers=headers, verify=False)

希望这对有需要的人有用:)。

解决方案 9:

不幸的是,接受的答案对我不起作用。作为临时解决方法,您也可以verify=False在连接到安全网站时使用它。

从Python 请求引发 SSLError

requests.get('https://example.com', verify=True)

解决方案 10:

通过 TLS 连接到 RabbitMQ MQTT 服务器时,我遇到了此错误。我很确定服务器坏了,但无论如何它可以与 OpenSSL 1.0.1 配合使用,但不能与OpenSSL 1.0.2 配合使用。

你可以使用以下命令检查 Python 中的版本:

import ssl
ssl.OPENSSL_VERSION

除了使用旧版本的 Python 之外,我不确定如何在 Python 中降级 OpenSSL(至少在 Windows 上它似乎是静态链接的)。

解决方案 11:

因此,我尝试了很多解决方案,但都不起作用。这听起来很愚蠢,但是...

我在 URL 中输入了“https”,而它应该是“http”。我只需删除“s”,请求就可以无缝运行。

希望这对其他人有帮助。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2796  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1710  
  PLM系统在企业项目管理中扮演着至关重要的角色,尤其是在项目采购管理方面,能够通过一系列策略提升采购效率、降低成本并保障质量。通过深入解析相关策略,企业可以更好地利用PLM系统优化采购流程,实现项目的顺利推进与整体目标的达成。需求精准定义策略在项目采购中,明确需求是首要任务。PLM系统可助力企业精准定义采购需求。首先,...
plm是什么意思   8  
  在企业的运营过程中,跨部门数据共享一直是一个关键且颇具挑战的问题。不同部门之间由于业务差异、系统不兼容等多种因素,常常形成信息孤岛,导致数据无法顺畅流通,影响企业整体的决策效率和协同效果。而 PLM 系统作为一种先进的管理工具,为解决这一难题提供了有效的途径。通过其一系列强大的核心功能,能够打破部门之间的数据壁垒,实现...
plm系统   7  
  PLM(产品生命周期管理)项目涉及产品从概念设计到退役的全流程管理,其复杂性和长期性要求高效的项目进度管理工具。甘特图作为一种直观且实用的项目进度可视化工具,在PLM项目中发挥着关键作用。通过甘特图,项目团队成员能够清晰地了解项目任务的时间安排、进度状态以及各项任务之间的关系,从而更好地协调工作、分配资源,确保项目按计...
plm流程是什么   6  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用