<p>您应该查看<a href="http://docs.python-requests.org/en/latest/api/#requests.adapters.HTTPAdapter" rel="noreferrer">TransportAdapters</a>,包括源代码。关于它们的文档不是很好,但是它们提供了对<a href="http://tools.ietf.org/html/rfc2818" rel="noreferrer">RFC 2818</a>和<a href="https://tools.ietf.org/html/rfc6125#page-21" rel="noreferrer">RFC 6125</a>中描述的许多功能的低级访问。特别是,这些文件鼓励(要求?)客户端代码,用于支持特定于应用程序的DNS,以检查证书的CommonName和SubjectAltName。这些调用中需要的关键字参数是“assert_hostname”。以下是如何使用请求库设置它:</p>
<pre><code>from requests import Session, HTTPError
from requests.adapters import HTTPAdapter, DEFAULT_POOLSIZE, DEFAULT_RETRIES, DEFAULT_POOLBLOCK
class DNSResolverHTTPSAdapter(HTTPAdapter):
def __init__(self, common_name, host, pool_connections=DEFAULT_POOLSIZE, pool_maxsize=DEFAULT_POOLSIZE,
max_retries=DEFAULT_RETRIES, pool_block=DEFAULT_POOLBLOCK):
self.__common_name = common_name
self.__host = host
super(DNSResolverHTTPSAdapter, self).__init__(pool_connections=pool_connections, pool_maxsize=pool_maxsize,
max_retries=max_retries, pool_block=pool_block)
def get_connection(self, url, proxies=None):
redirected_url = url.replace(self.__common_name, self.__host)
return super(DNSResolverHTTPSAdapter, self).get_connection(redirected_url, proxies=proxies)
def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs):
pool_kwargs['assert_hostname'] = self.__common_name
super(DNSResolverHTTPSAdapter, self).init_poolmanager(connections, maxsize, block=block, **pool_kwargs)
common_name = 'SuperSecretSarahServer'
host = '192.168.33.51'
port = 666
base_url = 'https://{}:{}/api/'.format(common_name, port)
my_session = Session()
my_session.mount(self.base_url.lower(), DNSResolverHTTPSAdapter(common_name, host))
user_name = 'sarah'
url = '{}users/{}'.format(self.base_url, user_name)
default_response_kwargs = {
'auth': (NAME, PASSWORD),
'headers': {'Content-Type': 'application/json'},
'verify': SSL_OPTIONS['ca_certs'],
'cert': (SSL_OPTIONS['certfile'], SSL_OPTIONS['keyfile'])
}
response = my_session.get(url, **default_response_kwargs)
</code></pre>
<p>我使用<code>common_name</code>表示证书上预期的名称,以及代码将如何引用所需的计算机。我使用<code>host</code>作为外部世界识别的名称-FQDN、IP、DNS条目。。。当然,SSL_选项字典(在我的示例中)必须在您的计算机上列出适当的证书/密钥文件名。(另外,名称和密码应该解析为正确的字符串。)</p>