tornado.httpserver — 非阻塞 HTTP 服务器

一个非阻塞的单线程 HTTP 服务器。

典型的应用程序很少直接与 HTTPServer 类交互,除了在进程开始时启动服务器(甚至这通常通过 tornado.web.Application.listen 间接完成)。

在版本 4.0 中变更: 以前位于此模块中的 HTTPRequest 类已移动到 tornado.httputil.HTTPServerRequest。旧名称保留为别名。

HTTP 服务器

class tornado.httpserver.HTTPServer(request_callback: Union[httputil.HTTPServerConnectionDelegate, Callable[[httputil.HTTPServerRequest], None]], no_keep_alive: bool = False, xheaders: bool = False, ssl_options: Union[Dict[str, Any], ssl.SSLContext] = None, protocol: Optional[str] = None, decompress_request: bool = False, chunk_size: Optional[int] = None, max_header_size: Optional[int] = None, idle_connection_timeout: Optional[float] = None, body_timeout: Optional[float] = None, max_body_size: Optional[int] = None, max_buffer_size: Optional[int] = None, trusted_downstream: Optional[List[str]] = None)[source]

一个非阻塞的单线程 HTTP 服务器。

服务器由 HTTPServerConnectionDelegate 的子类定义,或者,为了向后兼容,回调函数接受 HTTPServerRequest 作为参数。委托通常是 tornado.web.Application

HTTPServer 默认情况下支持保持活动连接(对于 HTTP/1.1 自动,或者对于 HTTP/1.0 当客户端请求 Connection: keep-alive 时)。

如果 xheadersTrue,我们支持 X-Real-Ip/X-Forwarded-ForX-Scheme/X-Forwarded-Proto 头部,它们会覆盖所有请求的远程 IP 和 URI 方案/协议。这些头部在 Tornado 运行在反向代理或负载均衡器后面时非常有用。如果 Tornado 运行在 SSL 解码代理后面,并且该代理没有设置任何支持的 xheaders,则 protocol 参数也可以设置为 https

默认情况下,当解析 X-Forwarded-For 头部时,Tornado 会选择主机列表中的最后一个(即最靠近)地址作为远程主机 IP 地址。要选择链中的下一个服务器,可以将信任的下游主机列表作为 trusted_downstream 参数传递。解析 X-Forwarded-For 头部时会跳过这些主机。

要使此服务器提供 SSL 流量,请使用 ssl_options 关键字参数发送一个 ssl.SSLContext 对象。为了与旧版本的 Python 兼容,ssl_options 也可以是 ssl.SSLContext.wrap_socket 方法的关键字参数字典。

ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_ctx.load_cert_chain(os.path.join(data_dir, "mydomain.crt"),
                        os.path.join(data_dir, "mydomain.key"))
HTTPServer(application, ssl_options=ssl_ctx)

HTTPServer 初始化遵循三种模式之一(初始化方法定义在 tornado.tcpserver.TCPServer 上)

  1. listen: 单进程

    async def main():
        server = HTTPServer()
        server.listen(8888)
        await asyncio.Event.wait()
    
    asyncio.run(main())
    

    在许多情况下,tornado.web.Application.listen 可以用来避免显式创建 HTTPServer

    虽然此示例不会自行创建多个进程,但是当将 reuse_port=True 参数传递给 listen() 时,您可以多次运行该程序来创建多进程服务。

  2. add_sockets: 多进程

    sockets = bind_sockets(8888)
    tornado.process.fork_processes(0)
    async def post_fork_main():
        server = HTTPServer()
        server.add_sockets(sockets)
        await asyncio.Event().wait()
    asyncio.run(post_fork_main())
    

    add_sockets 接口比较复杂,但它可以与 tornado.process.fork_processes 一起使用,以运行一个多进程服务,所有工作进程都从单个父进程派生。 add_sockets 也可以在单进程服务器中使用,如果您想以除 bind_sockets 之外的其他方式创建监听套接字。

    请注意,在使用此模式时,在 fork_processes 之前不能运行任何接触事件循环的内容。

  3. bind/start: 简单 **已弃用** 多进程

    server = HTTPServer()
    server.bind(8888)
    server.start(0)  # Forks multiple sub-processes
    IOLoop.current().start()
    

    这种模式已弃用,因为它需要 asyncio 模块中的接口,这些接口自 Python 3.10 以来已被弃用。在 Tornado 的未来版本中,将删除在 start 方法中创建多个进程的支持。

在版本 4.0 中更改: 添加了 decompress_requestchunk_sizemax_header_sizeidle_connection_timeoutbody_timeoutmax_body_size 参数。添加了对 HTTPServerConnectionDelegate 实例作为 request_callback 的支持。

在版本 4.1 中更改: HTTPServerConnectionDelegate.start_request 现在使用两个参数 (server_conn, request_conn)(符合文档)调用,而不是一个 (request_conn)

在版本 4.2 中更改: HTTPServer 现在是 tornado.util.Configurable 的子类。

在版本 4.5 中更改: 添加了 trusted_downstream 参数。

在版本 5.0 中更改: 已删除 io_loop 参数。

此类的公共接口主要继承自 TCPServer,并在该类下有记录。

coroutine close_all_connections() None[source]

关闭所有打开的连接并异步等待它们完成。

此方法与 stop 结合使用以支持干净的关闭(尤其是对于单元测试)。典型的用法是先调用 stop() 来停止接受新的连接,然后调用 await close_all_connections() 来等待现有连接完成。

此方法目前不关闭打开的 websocket 连接。

请注意,此方法是一个协程,必须使用 await 调用。