我想在Python中构建一个真正非阻塞的HTTPS服务器。如果每个人都遵守规则,以下最简代码将完美运行:
然而,问题在于此服务器至少在TLS握手期间被阻塞。
测试代码:
wget进程阻塞,表示服务器中有某些内容被阻塞。一旦关闭nc进程,wget就会继续执行。这显然根本不实用。
如何在Python中获得真正的非阻塞HTTPS服务器,最好不要使用额外的第三方软件?
我应该提到,完全相同的代码在没有TLS的情况下可以按预期工作(即没有wrap_socket行)。
Steffen Ullrich指出了如何做到这一点:将“do_handshake_on_connect = False”传递给“wrap_socket”,然后自己进行握手。在这种情况下,子类化“BaseHTTPServer.HTTPServer”,覆盖“handle”,然后按Python文档中所示执行握手(套接字称为“self.request”),然后调用超级方法。
import BaseHTTPServer
import SimpleHTTPServer
import SocketServer
import ssl
class ThreadedHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
pass
httpd = ThreadedHTTPServer(('localhost', 4443), SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, keyfile="localhost.key", certfile="localhost.pem", server_side=True)
httpd.serve_forever()
然而,问题在于此服务器至少在TLS握手期间被阻塞。
测试代码:
$ nc localhost 4443 # leave this open
然后在另一个终端中执行以下命令:
$ wget --no-check-certificate https://localhost:4443/
--2014-10-23 16:55:54-- https://localhost:4443/
Resolving localhost (localhost)... 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:4443... connected.
wget进程阻塞,表示服务器中有某些内容被阻塞。一旦关闭nc进程,wget就会继续执行。这显然根本不实用。
如何在Python中获得真正的非阻塞HTTPS服务器,最好不要使用额外的第三方软件?
我应该提到,完全相同的代码在没有TLS的情况下可以按预期工作(即没有wrap_socket行)。
Steffen Ullrich指出了如何做到这一点:将“do_handshake_on_connect = False”传递给“wrap_socket”,然后自己进行握手。在这种情况下,子类化“BaseHTTPServer.HTTPServer”,覆盖“handle”,然后按Python文档中所示执行握手(套接字称为“self.request”),然后调用超级方法。