我正在使用Python开发一个API包装器,它可以与CPython 2.7和3一起使用。
当我从 IronPython 点击https服务器时,我得到了下面的追溯
IOError: System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
我分析了不同平台发送的软件包,并注意到唯一的区别是IronPython是唯一使用TSL 1.0协议的软件,CPython使用TSL 1.2(见下面的截图)
我使用下面的代码强制Cpython使用TSL 1.0并得到完全相同的错误,这证实了问题与TSL协议有关。 (该代码允许我一致地更改HTTP适配器协议)
我遇到的问题是,下面的代码似乎对IronPython没有影响,并且它继续在所有请求中使用TSL 1.0。
有什么想法吗?这可能是一个IronPython错误吗?
import sys
import platform
print(platform.python_implementation())
print(sys.version_info[0:2])
import ssl
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
if platform.python_implementation() == 'IronPython':
print('Setting TSL Protocol')
import System
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12
class ForceTLSV12Adapter(HTTPAdapter):
"""Require TLSv1 for the connection"""
def init_poolmanager(self, connections, maxsize, block=False):
# This method gets called when there's no proxy.
self.poolmanager = PoolManager(
num_pools=connections,
maxsize=maxsize,
block=block,
ssl_version=ssl.PROTOCOL_TLSv1_2,
# ssl_version=ssl.PROTOCOL_TLSv1,
)
def proxy_manager_for(self, proxy, **proxy_kwargs):
# This method is called when there is a proxy.
proxy_kwargs['ssl_version'] = ssl.PROTOCOL_TLSv1_2
return super(ForceTLSV1Adapter, self).proxy_manager_for(proxy, **proxy_kwargs)
s = requests.Session()
s.mount('https://api.unleashedsoftware.com', ForceTLSV12Adapter())
print(s.get("https://api.unleashedsoftware.com"))
PS:我也尝试过设置系统范围的默认协议,但它似乎没有任何影响: https://support.microsoft.com/en-us/help/3140245/update-to-enable-tls-1-1-and-tls-1-2-as-a-default-secure-protocols-in
答案 0 :(得分:0)
代码运行正常。问题是IronPython中的一个错误: https://github.com/IronLanguages/ironpython2/issues/227