与超时的TLS连接(以及其他一些困难)

2024-09-26 17:40:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Python中的HTTP客户端,需要使用TLS。我不仅需要 进行加密连接,同时从 远程计算机,如证书颁发者。我需要做 连接到许多HTTP服务器,通常表现不好,所以我绝对 需要超时。对于非TLS连接, mysocket.settimeout(5)做我想做的事。

在众多TLS Python模块中:

python-gnutls不允许在套接字上使用settimeout(),因为 它使用非阻塞套接字:

gnutls.errors.OperationWouldBlock: Function was interrupted.

python-openssl也有类似的问题:

OpenSSL.SSL.WantReadError

标准库的SSL module不适用于Python 2.5条。

TLSlite这样的其他库显然不允许访问 证书的元数据。

程序是线程化的,所以我不能使用信号。我需要详细的 控件,因此我不能使用标准库(如urllib2)。

背景:这是 调查项目DNSwitness。相关的SO线程:Timeout on a Python function callHow to limit execution time of a function call in Python


Tags: 服务器http客户端ssl标准远程计算机tls
3条回答

我假设您遇到的问题如下,您正在使用PyOpenSSL打开一个连接,并且总是会得到一个WantReadError异常。你无法区分这个错误和超时。请考虑以下示例:

#!/usr/bin/python

import OpenSSL
import socket
import struct

context = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
connection = OpenSSL.SSL.Connection(context,s)
connection.connect(("www.gmail.com",443))

# Put the socket in blocking mode
connection.setblocking(1)

# Set the timeout using the setsockopt
tv = struct.pack('ii', int(6), int(0))
connection.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, tv)

print "Connected to " , connection.getpeername()
print "Sate " , connection.state_string()

while True:
    try:
        connection.do_handshake()
        break
    except OpenSSL.SSL.WantReadError:
        print "Exception"
        pass
print "Sate " , connection.state_string()


print connection.send("koekoek\r\n")


while True:
    try:
        recvstr = connection.recv(1024)
        break
    except OpenSSL.SSL.WantReadError:
        print "Exception"
        pass

print recvstr 

这将打开到gmail的SSL连接,发送一个无效字符串,读取响应并打印它。注意: *连接明确地设置为阻塞模式 *在这种情况下,recv超时被明确设置为6秒。

现在的行为是什么,当超时发生时,WantReadError异常将是thornw,在本例中是在等待6秒之后。(您可以删除while True以避免重试,但在本例中,我添加了它们以进行测试)。套接字上设置的超时仅在connect()调用中有效。

另一种选择是,当套接字保持非阻塞模式时(这可能也适用于GNUTLS情况),您可以自己执行计时,您可以在启动调用时获得时间,在while True中,尝试:除了WantReadError之外,您可以每次自己执行检查,以查看您是否等待了太长时间。

我还建议使用Twisted,并使用M2Crypto作为TLS parts

虽然我从来没有把它用于这个目的,Twisted应该做你想做的。唯一的缺点是它是一个相当大的库,您还需要安装PyOpenSSL(Twisted依赖于它)。如果您以前从未使用过它,Twisted基于回调的体系结构可能需要一些时间来适应(您在开始之前确实想阅读教程)。

但除此之外,它是围绕管理大量连接的思想设计的,它当然允许您指定超时、重新连接等,并且您可以检索证书信息(请参见here)。

相关问题 更多 >

    热门问题