- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用 python 的请求模块。我可以获得服务器的响应头和应用层数据:
import requests
r = requests.get('https://yahoo.com')
print(r.url)
我的问题:请求是否允许检索传输层数据(服务器的 TLS 选择版本、密码套件等?)。
最佳答案
这是一个有效的快速丑陋猴子补丁版本:
import requests
from requests.packages.urllib3.connection import VerifiedHTTPSConnection
SOCK = None
_orig_connect = requests.packages.urllib3.connection.VerifiedHTTPSConnection.connect
def _connect(self):
global SOCK
_orig_connect(self)
SOCK = self.sock
requests.packages.urllib3.connection.VerifiedHTTPSConnection.connect = _connect
requests.get('https://yahoo.com')
tlscon = SOCK.connection
print 'Cipher is %s/%s' % (tlscon.get_cipher_name(), tlscon.get_cipher_version())
print 'Remote certificates: %s' % (tlscon.get_peer_certificate())
print 'Protocol version: %s' % tlscon.get_protocol_version_name()
这会产生:
Cipher is ECDHE-RSA-AES128-GCM-SHA256/TLSv1.2
Remote certificates: <OpenSSL.crypto.X509 object at 0x10c60e310>
Protocol version: TLSv1.2
然而,这很糟糕,因为猴子修补并依赖于一个唯一的全局变量,这也意味着您无法检查在重定向步骤等处发生了什么。
也许可以通过一些可以变成传输适配器
的工作来获取底层连接作为请求的属性(可能是 session 或其他东西)。但这可能会造成泄漏,因为在当前的实现中,底层套接字会被尽快丢弃(参见 How to get the underlying socket when using Python requests )。
这是有效的,并且符合框架(没有全局变量,应该处理重定向等。虽然代理可能需要做一些事情,比如为 proxy_manager_for
添加覆盖),但是这是更多的代码。
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.connectionpool import HTTPSConnectionPool
from requests.packages.urllib3.poolmanager import PoolManager
class InspectedHTTPSConnectionPool(HTTPSConnectionPool):
@property
def inspector(self):
return self._inspector
@inspector.setter
def inspector(self, inspector):
self._inspector = inspector
def _validate_conn(self, conn):
r = super(InspectedHTTPSConnectionPool, self)._validate_conn(conn)
if self.inspector:
self.inspector(self.host, self.port, conn)
return r
class InspectedPoolManager(PoolManager):
@property
def inspector(self):
return self._inspector
@inspector.setter
def inspector(self, inspector):
self._inspector = inspector
def _new_pool(self, scheme, host, port):
if scheme != 'https':
return super(InspectedPoolManager, self)._new_pool(scheme, host, port)
kwargs = self.connection_pool_kw
if scheme == 'http':
kwargs = self.connection_pool_kw.copy()
for kw in SSL_KEYWORDS:
kwargs.pop(kw, None)
pool = InspectedHTTPSConnectionPool(host, port, **kwargs)
pool.inspector = self.inspector
return pool
class TLSInspectorAdapter(HTTPAdapter):
def __init__(self, inspector):
self._inspector = inspector
super(TLSInspectorAdapter, self).__init__()
def init_poolmanager(self, connections, maxsize, block=False, **pool_kwargs):
self.poolmanager = InspectedPoolManager(num_pools=connections, maxsize=maxsize, block=block, strict=True, **pool_kwargs)
self.poolmanager.inspector = self._inspector
def connection_inspector(host, port, connection):
print 'host is %s' % host
print 'port is %s' % port
print 'connection is %s' % connection
sock = connection.sock
sock_connection = sock.connection
print 'socket is %s' % sock
print 'Protocol version: %s' % sock_connection.get_protocol_version_name()
print 'Cipher is %s/%s' % (sock_connection.get_cipher_name(), sock_connection.get_cipher_version())
print 'Remote certificate: %s' % sock.getpeercert()
url = 'https://yahoo.com'
s = requests.Session()
s.mount(url, TLSInspectorAdapter(connection_inspector))
r = s.get(url)
是的,socket
和connection
在命名上有很多混淆:requests使用了一个“连接池”,它有一组连接,实际上是,对于 HTTPS,一个 PyOpenSSL WrappedSocket,它本身有一个底层真实的 TLS 连接(即 PyOpenSSL Connection 对象)。因此 connection_inspector
中出现了奇怪的形式。
但这会返回预期的结果:
host is yahoo.com
port is 443
connection is <requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x10bb372d0>
socket is <requests.packages.urllib3.contrib.pyopenssl.WrappedSocket object at 0x10bb37410>
Protocol version: TLSv1.2
Cipher is ECDHE-RSA-AES128-GCM-SHA256/TLSv1.2
Remote certificate: {'subjectAltName': [('DNS', '*.www.yahoo.com'), ('DNS', 'add.my.yahoo.com'), ('DNS', '*.amp.yimg.com'), ('DNS', 'au.yahoo.com'), ('DNS', 'be.yahoo.com'), ('DNS', 'br.yahoo.com'), ('DNS', 'ca.my.yahoo.com'), ('DNS', 'ca.rogers.yahoo.com'), ('DNS', 'ca.yahoo.com'), ('DNS', 'ddl.fp.yahoo.com'), ('DNS', 'de.yahoo.com'), ('DNS', 'en-maktoob.yahoo.com'), ('DNS', 'espanol.yahoo.com'), ('DNS', 'es.yahoo.com'), ('DNS', 'fr-be.yahoo.com'), ('DNS', 'fr-ca.rogers.yahoo.com'), ('DNS', 'frontier.yahoo.com'), ('DNS', 'fr.yahoo.com'), ('DNS', 'gr.yahoo.com'), ('DNS', 'hk.yahoo.com'), ('DNS', 'hsrd.yahoo.com'), ('DNS', 'ideanetsetter.yahoo.com'), ('DNS', 'id.yahoo.com'), ('DNS', 'ie.yahoo.com'), ('DNS', 'in.yahoo.com'), ('DNS', 'it.yahoo.com'), ('DNS', 'maktoob.yahoo.com'), ('DNS', 'malaysia.yahoo.com'), ('DNS', 'mbp.yimg.com'), ('DNS', 'my.yahoo.com'), ('DNS', 'nz.yahoo.com'), ('DNS', 'ph.yahoo.com'), ('DNS', 'qc.yahoo.com'), ('DNS', 'ro.yahoo.com'), ('DNS', 'se.yahoo.com'), ('DNS', 'sg.yahoo.com'), ('DNS', 'tw.yahoo.com'), ('DNS', 'uk.yahoo.com'), ('DNS', 'us.yahoo.com'), ('DNS', 'verizon.yahoo.com'), ('DNS', 'vn.yahoo.com'), ('DNS', 'www.yahoo.com'), ('DNS', 'yahoo.com'), ('DNS', 'za.yahoo.com')], 'subject': ((('commonName', u'*.www.yahoo.com'),),)}
其他想法:
poolmanager.pool_classes_by_scheme['http'] = MyHTTPConnectionPool
;但这仍然是猴子修补,令人遗憾的是 PoolManager 没有为 pool_classes_by_scheme
变量提供一个很好的 API 以便能够轻松覆盖它init_poolmanager
中,您只需要在调用父类(super class)之前在 kwargs
中设置 ssl_context;这个例子在 https://gist.github.com/aiguofer/1eb881ccf199d4aaa2097d87f93ace6a <= 或者可能不是,因为实际上该结构来自 ssl.create_default_context
而 ssl
远不如 PyOpenSSL
强大,我看不出有什么办法使用 ssl
添加回调,它们存在于 PyOpenSSL
中。 YMMV。附言:
_validate_conn
,你可以在它获得正确的连接对象时覆盖它,生活就更容易了关于ssl - 是否可以识别 TLS 信息。在请求响应中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55431014/
我使用的是linux的windows子系统,安装了ubuntu,bash运行流畅。 我正在尝试使用make,似乎bash 无法识别gcc。尝试将其添加到 PATH,但没有任何改变。奇怪的是 - cmd
ImageMagick 已正确安装。 WAMP 的“PHP 扩展”菜单也显示带有勾选的 php_imagick。除了 Apache 和系统环境变量外,phpinfo() 没有显示任何 imagick
我是这么想的,因为上限是 2^n,并且考虑到它们都是有限机,n 状态 NFA 和具有 2^n 或更少状态的 DFA 的交集将是有效。 我错了吗? 最佳答案 你是对的。 2^n 是一个上限,因此生成的
我有一个大型数据集,其中包含每日值,指示一年中的特定一天是否特别热(用 1 或 0 表示)。我的目标是识别 3 个或更多特别炎热的日子的序列,并创建一个包含每个日子的长度以及开始和结束日期的新数据集。
我有一个向量列表,每个向量看起来像这样 c("Japan", "USA", "country", "Japan", "source", "country", "UK", "source", "coun
是否有任何工具或方法可以识别静态定义数组中的缓冲区溢出(即 char[1234] 而不是 malloc(1234))? 昨天我花了大部分时间来追踪崩溃和奇怪的行为,最终证明是由以下行引起的: // e
我一直在尝试通过导入制表符分隔的文件来手动创建 Snakemake 通配符,如下所示: dataset sample species frr PRJNA493818_GSE120639_SRP1628
我一直在尝试通过导入制表符分隔的文件来手动创建 Snakemake 通配符,如下所示: dataset sample species frr PRJNA493818_GSE120639_SRP1628
我想录下某人的声音,然后根据我获得的关于他/她声音的信息,如果那个人再次说话,我就能认出来!问题是我没有关于哪些统计数据(如频率)导致人声差异的信息,如果有人可以帮助我如何识别某人的声音? 在研究过程
我希望我的程序能够识别用户何时按下“enter”并继续循环播放。但是我不知道如何使程序识别“输入”。尝试了两种方法: string enter; string ent = "\n"; dice d1;
我创建了这个带有一个参数(文件名)的 Bash 小脚本,该脚本应该根据文件的扩展名做出响应: #!/bin/bash fileFormat=${1} if [[ ${fileFormat} =~ [F
我正在寻找一种在 for 循环内迭代时识别 subview 对象的方法,我基本上通过执行 cell.contentView.subviews 从 UITableView 的 contentView 获
我正在尝试在 Swift 中使用 CallKit 来识别调用者。 我正在寻找一种通过发出 URL 请求来识别调用者的方法。 例如:+1-234-45-241 给我打电话,我希望它向 mydomain.
我将(相当古老的)插件称为“thickbox”,如下所述: 创建厚盒时,它包含基于查询的内容列表。 使用 JavaScript 或 jQuery,我希望能够访问 type 的值(在上面的示例中 t
我想编写一些可以接受某种输入并将其识别为方波、三角波或某种波形的代码。我还需要一些产生所述波的方法。 我确实有使用 C/C++ 的经验,但是,我不确定我将如何模拟所有这些。最终,我想将其转换为微 Co
我创建了一个 for 循环,用于在每个部分显示 8 个项目,但我试图在循环中识别某些项目。例如,我想识别前两项,然后是第五项和第六项,但我的识别技术似乎是正确的。 for (int i = 0; i
如何识别 UIStoryboard? 该类具有创建和实例化的方法,但我没有看到带有类似name 的@property。例如 获取 Storyboard对象 + storyboardWithName:b
如何确定所运行的SQLServer2005的版本 要确定所运行的SQLServer2005的版本,请使用SQLServerManagementStudio连接到SQLServer2005,然后运行
这个问题在这里已经有了答案: How to check whether an object is a date? (26 个答案) 关闭2 年前。 我正在使用一个 npm 模块,它在错误时抛出一个空
我正在制作一个使用 ActivityRecognition API 在后台跟踪用户 Activity 的应用,如果用户在指定时间段(例如 1 小时)内停留在同一个地方,系统就会推送通知告诉用户去散步.
我是一名优秀的程序员,十分优秀!