2009/07/18

"OpenSSL.SSL.WantReadError"

暫く Twisted でねばってたんですが
SSL 周りを低いところから攻めてみようと思いまして
でもちょっとは楽したいなと思いながら
from twisted.internet import reactor
from twisted.internet.protocol import Protocol, ClientFactory
from twisted.internet.ssl import CertificateOptions

class MyProtocol(Protocol):
def connectionMade(self):
self.transport.socket.do_handshake()
reactor.stop()

class MyProtocolFactory(ClientFactory):
protocol = MyProtocol

if __name__ == '__main__':
f = MyProtocolFactory()
ctx = CertificateOptions()
reactor.connectSSL('www.blogger.com', 443, f, ctx)
reactor.run()
繋がったら切るってどういうことだよ!
っていうのを先ず書いてみたら
  File "test.py", line 7, in connectionMade
self.transport.socket.do_handshake()
OpenSSL.SSL.WantReadError:
例外ってしまいました

OpenSSL ってのは pyOpenSSL のことでしたが
まぁとりあえずググってみるかっつーダメな考えで
TLS connection with timeouts (and a few other difficulties) - Stack Overflow
とても丁寧な回答が投稿されてました

Twisted なのでそもそも reactor.connectSSL の socket は
timeout=30 ってのがデフォルト設定されていて
socket は non-blocking になっているので
handshake しに client hello して返事読もうとするんだけど
せっかちだからまだ返事来てなくってエラーになってるんで
落ち着いてちょっと待てってことでした
17.2.1 socket オブジェクト でも良く読めと

なので、待つことにしたら何も無しに終わるようになりました
@@ -1,10 +1,18 @@
+from time import sleep
+
from twisted.internet import reactor
from twisted.internet.protocol import Protocol, ClientFactory
from twisted.internet.ssl import CertificateOptions
+from OpenSSL.SSL import WantReadError

class MyProtocol(Protocol):
def connectionMade(self):
- self.transport.socket.do_handshake()
+ while True:
+ try:
+ self.transport.socket.do_handshake()
+ break
+ except WantReadError:
+ sleep(0.1)
reactor.stop()

class MyProtocolFactory(ClientFactory):
なんか、ちょっと可哀そうだから sleep 入れてみた
入れないと 2000 回以上 WantReadError してました
コンピューターは速いなぁ

あ、ほんとは、
Protocol とかでなくて twisted.protocols.basic.LineReceiver とかで
line を送ったり受けとったりし始めたらいいんです
handshake なんて裏でちょちょいとやってくれます
でもほら、
Protocol と ClientFactory だけで色々試してみたいじゃないですか

0 件のコメント:

コメントを投稿