如何使用PyOpenSSL连接对象安全地使用select?

时间:2012-10-29 21:42:26

标签: python pyopenssl

Python:Windows Vista上的2.7.2 Egenix PyOpenSSL:0.13.0

我正在尝试编写代理服务。基本上,代理服务侦听常规套接字和SSL套接字,在两者之间中继数据。

我能够获得半可靠的中继数据,但是当SSL套接字另一端的服务器完成发送数据时,我收到一个虚假信号,表明有更多数据可供读取。代码基本上如下所示:

(rs, ws, xs) = select.select([client, sslserver], [], [])
for r in rs:
    if r == client:
        # tons of client code
    elif r == sslserver:
        (rs, ws, xs) = select.select([sslserver], [], [], 0)
        print 'Reading server: %s, %s' % (len(rs), server.pending())
        while len(rs) > 0 or sslserver.pending() > 0:
            t = sslserver.read(sslserver.pending())
            # Do more useful stuff
            (rs, ws, xs) = select.select([sslserver], [], [], 0)

使用此代码,我有时会在进入读取块之前看到文本Reading server: 1, 0。当我实际执行t = sslserver.read(sslserver.pending())时,结果是一个折腾。我经常得到一个EOF异常(SSL.SysCallError()[1] =='意外的EOF')。问题是,有时这是一个真正的EOF,有时SSL只是没有提供任何数据。

但是,如果我将读取行改为像这样读取

t = sslserver.read(4096)

在大多数套接字读取代码中都是如此,而不是得到任何东西来指示EOF(常规套接字会!选择说套接字已准备好读取。没有数据要读取。所以立即返回没有数据!),我的代码只是在没有数据要读取时阻塞。当然,这没有任何意义。毕竟,插座已准备好进行读取。它应该阻止,直到EOF通过解密阶段。

但事实并非如此。这是一个永久的障碍。

我有什么选择?我现在绝对相信select.select对于PyOpenSSL套接字是不安全的。是否有其他方法来监视带有常规套接字的SSL套接字,或者我是否需要将SSL套接字移动到单独的线程中并使用普通套接字将数据中继到我的主线程中?

0 个答案:

没有答案