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使用。