Python中真正无阻塞的HTTPS服务器 [英] Truly non-blocking HTTPS Server in Python

查看:1061
本文介绍了Python中真正无阻塞的HTTPS服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Python中构建一个真正无阻塞的HTTPS服务器。如果每个人都玩得很好,下面的最小代码就可以了:

I'm trying to build a truly non-blocking HTTPS server in Python. The following minimal code works just fine if everyone is playing nice:

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握手期间阻塞。

However, the problem is that this server blocks at least during the TLS handshake.

测试:

$ nc localhost 4443  # leave this open

然后(在另一个终端):

And then (in another terminal):

$ 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就会继续。这显然不实用。

The wget process blocks, indicating that something is blocked in the server. Once I close the nc process, wget continues. This is obviously not practical at all.

如何在Python中获得真正无阻塞的HTTPS服务器,最好不需要额外的第三方软件?

How do I get a truly non-blocking HTTPS server in Python, preferably without additional third-party software?

我应该提一下,在没有TLS的情况下,相同的代码可以正常工作(即没有wrap_socket行)。

I should mention that the very same code works as expected without TLS (i.e., without the wrap_socket line).

Steffen Ullrich指出如何做到这一点:将 do_handshake_on_connect = False 传递给 wrap_socket ,然后自己做握手。在这种情况下,子类 BaseHTTPServer.HTTPServer ,覆盖 handle ,然后执行握手,如Python文档中所示(套接字称为 self.request ),然后调用super方法。

Steffen Ullrich pointed out how to do it: pass do_handshake_on_connect=False to wrap_socket, then do the handshake yourself. In this case, subclass BaseHTTPServer.HTTPServer, override handle, and then do the handshake as shown in the Python docs (the socket is called self.request) followed by calling the super method.

推荐答案

您必须通过使用 do_handshake_on_connect = False 以及稍后调用 ssl.wrap_socket 来执行非阻塞SSL接受自己调用 do_handshake 直到成功为止。请参见 https://docs.python.org/3/library/ssl .html #notes-on-non-blocking-socket .......

You have to do a non-blocking SSL accept by calling ssl.wrap_socket with do_handshake_on_connect=False and later calling do_handshake yourself until it succeeds. See https://docs.python.org/3/library/ssl.html#notes-on-non-blocking-sockets.

你也可以简单地使用 Tornado ,这是一个用python编写的Web服务器,它也完全不阻塞SSL处理。即使您不想自己使用它,您也可以查看源代码以了解如何完成此操作(搜索 do_handshake )。

You might also simply use Tornado which is a web server written in python and which also does fully non-blocking SSL handling. Even if you don't want to use it yourself you might have a look at the source code to see how this is done (search for do_handshake).

这篇关于Python中真正无阻塞的HTTPS服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆