Tornado 使用 Router
类实现将 HTTP 请求路由到适当的处理程序。tornado.web.Application
类是一个路由器实现,可以直接使用,也可以使用此模块中的类来增加灵活性。 RuleRouter
类可以匹配比 Application
更多的条件,或者可以对 Router
接口进行子类化以实现最大程度的定制。
Router
接口扩展了 HTTPServerConnectionDelegate
以提供额外的路由功能。 这也意味着任何 Router 实现都可以直接用作 HTTPServer
构造函数的 request_callback
。
路由器子类必须实现一个 find_handler
方法来提供一个合适的 HTTPMessageDelegate
实例来处理请求:
class CustomRouter(Router):
def find_handler(self, request, **kwargs):
# some routing logic providing a suitable HTTPMessageDelegate instance
return MessageDelegate(request.connection)
class MessageDelegate(HTTPMessageDelegate):
def __init__(self, connection):
self.connection = connection
def finish(self):
self.connection.write_headers(
ResponseStartLine("HTTP/1.1", 200, "OK"),
HTTPHeaders({"Content-Length": "2"}),
b"OK")
self.connection.finish()
router = CustomRouter()
server = HTTPServer(router)
Router
实现的主要职责是提供从请求到处理该请求的 HTTPMessageDelegate
实例的映射。 在上面的示例中,我们可以看到即使没有实例化应用程序也可以进行路由。
为了路由到RequestHandler
实现,我们需要一个Application
实例。 get_handler_delegate
提供了一种方便的方法来为给定的请求和 RequestHandler
创建 HTTPMessageDelegate
。
这是一个简单的示例,说明我们如何通过 HTTP 方法路由到 RequestHandler
子类:
resources = {}
class GetResource(RequestHandler):
def get(self, path):
if path not in resources:
raise HTTPError(404)
self.finish(resources[path])
class PostResource(RequestHandler):
def post(self, path):
resources[path] = self.request.body
class HTTPMethodRouter(Router):
def __init__(self, app):
self.app = app
def find_handler(self, request, **kwargs):
handler = GetResource if request.method == "GET" else PostResource
return self.app.get_handler_delegate(request, handler, path_args=[request.path])
router = HTTPMethodRouter(Application())
server = HTTPServer(router)
ReversibleRouter
接口增加了区分路由并使用路由名称和附加参数将它们反转为原始 url 的能力。 Application
本身是 ReversibleRouter
类的实现。
RuleRouter
和 ReversibleRuleRouter
是 Router
和 ReversibleRouter
接口的实现,可用于创建基于规则的路由配置。
Rules是Rule
类的实例。 它们包含一个 Matcher
,它提供了用于确定规则是否与特定请求和目标匹配的逻辑,可以是以下之一:
1、HTTPServerConnectionDelegate
的一个实例:
router = RuleRouter([
Rule(PathMatches("/handler"), ConnectionDelegate()),
# ... more rules
])
class ConnectionDelegate(HTTPServerConnectionDelegate):
def start_request(self, server_conn, request_conn):
return MessageDelegate(request_conn)
2、接受 HTTPServerRequest
类型的单个参数的可调用对象
router = RuleRouter([
Rule(PathMatches("/callable"), request_callable)
])
def request_callable(request):
request.write(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK")
request.finish()
3、另一个Router
实例:
router = RuleRouter([
Rule(PathMatches("/router.*"), CustomRouter())
])
这其中当然允许嵌套 RuleRouter 或 Application:
router = RuleRouter([
Rule(HostMatches("example.com"), RuleRouter([
Rule(PathMatches("/app1/.*"), Application([(r"/app1/handler", Handler)])),
]))
])
server = HTTPServer(router)
在下面的示例中RuleRouter
用于在应用程序之间进行路由:
app1 = Application([
(r"/app1/handler", Handler1),
# other handlers ...
])
app2 = Application([
(r"/app2/handler", Handler2),
# other handlers ...
])
router = RuleRouter([
Rule(PathMatches("/app1.*"), app1),
Rule(PathMatches("/app2.*"), app2)
])
server = HTTPServer(router)
抽象路由器接口
必须实现以返回可以为请求提供服务的适当的 HTTPMessageDelegate
实例。 路由实现可能会传递额外的 kwargs 来扩展路由逻辑。
参数:
request
(httputil.HTTPServerRequest) – 当前的 HTTP 请求。kwargs
– 路由实现传递的附加关键字参数。返回:
一个用于处理请求的 HTTPMessageDelegate
实例。
抽象路由器接口,用于路由器,可处理命名路由,并支持将其反转为原始URL。
返回给定路由名称和参数的 url 字符串,如果未找到匹配项,则返回 None。
参数:
name
(str) - 路由名称。args
- 网址参数。返回:
给定路由名称(或无)的参数化 url 字符串。
基于规则的路由器实现。
从规则的有序列表构造一个路由器:
RuleRouter([
Rule(PathMatches("/handler"), Target),
# ... more rules
])
您还可以省略显式Rule
构造函数并使用参数元组:
RuleRouter([
(PathMatches("/handler"), Target),
])
PathMatches
是一个默认匹配器,所以上面的例子可以简化:
RuleRouter([
("/handler", Target),
])
在上面的示例中,Target
可以是嵌套的 Router
实例、HTTPServerConnectionDelegate
的实例或旧式可调用对象,并接受请求参数。
参数: rules – Rule
实例列表或 Rule
构造函数参数的元组。
将新规则附加到路由器。
参数:rules – Rule
实例列表(或参数元组,传递给 Rule
构造函数)。
覆盖此方法以对每个规则进行额外的预处理。
参数:rule(Rule
)——要处理的规则。
返回:相同或修改的规则实例。
返回规则目标的 HTTPMessageDelegate
实例。 此方法由 find_handler
调用,并且可以扩展以提供其他目标类型。
参数:
target
——Rule的目标。request
(httputil.HTTPServerRequest) – 当前请求。target_params
– 可用于创建 HTTPMessageDelegate
的附加参数。实现 reverse_url
方法的基于规则的路由器。
添加到此路由器的每个规则都可能有一个名称属性,可用于重建原始 URI
。 实际的重建发生在规则的匹配器中
路由规则。
构造一个 Rule
实例。
参数:
matcher
(Matcher) – 一个 Matcher 实例,用于确定是否应将规则视为特定请求的匹配项。target
- Rule的目标(通常是 RequestHandler
或 HTTPServerConnectionDelegate
子类,甚至是嵌套路由器,具体取决于路由实现)。target_kwargs
(dict) – 在目标实例化时可能有用的参数字典(例如,RequestHandler
子类的 status_code
)。 它们最终出现在 RuleRouter.get_target_delegate
方法的 target_params['target_kwargs']
中。name
(str) -- 可用于在 ReversibleRouter.reverse_url
实现中找到它的规则的名称。表示请求功能的匹配器
将当前实例与请求匹配
参数:request
(httputil.HTTPServerRequest) – 当前的 HTTP 请求
返回:要传递给目标处理程序的参数字典(例如,可以传递 handler_kwargs
、path_args
、path_kwargs
以进行正确的 RequestHandler
实例化)。 空 dict 是一个有效的(和常见的)返回值,用于在不使用参数传递功能时指示匹配。 必须返回 None 以指示不匹配。
从匹配器实例和附加参数重建完整的 url
匹配任何请求
匹配来自 host_pattern
正则表达式指定的主机的请求
匹配来自等于应用程序 default_host 的主机的请求。 如果存在 X-Real-Ip
标头,则始终不返回匹配项。
将请求与 path_pattern
正则表达式指定的路径匹配。
指定 URL 和处理程序之间的映射。
参数:
pattern
:要匹配的正则表达式。 正则表达式中的任何捕获组都将作为参数传递给处理程序的 get/post等方法(如果命名则按关键字,如果未命名则按位置。命名和未命名的捕获组不能在同一规则中混合使用)。handler
:要调用的 RequestHandler
子类。kwargs
(可选):要传递给处理程序构造函数的附加参数字典。name
(可选):此处理程序的名称。由 reverse_url
使用。