"""
def __init__(self, method=None, uri=None, version="HTTP/1.0", headers=None,
body=None, host=None, files=None, connection=None,
- start_line=None):
+ start_line=None, server_connection=None):
if start_line is not None:
method, uri, version = start_line
self.method = method
self.host_name = split_host_and_port(self.host.lower())[0]
self.files = files or {}
self.connection = connection
+ self.server_connection = server_connection
self._start_time = time.time()
self._finish_time = None
server = HTTPServer(router)
-Subclasses of `~.httputil.HTTPMessageDelegate` and old-style callables can also be used as
+Implementations of `~.httputil.HTTPServerConnectionDelegate` and old-style callables can also be used as
rule targets:
.. code-block:: python
router = RuleRouter([
Rule(PathMatches("/callable"), request_callable), # def request_callable(request): ...
- Rule(PathMatches("/delegate"), HTTPMessageDelegateSubclass)
+ Rule(PathMatches("/delegate"), HTTPServerConnectionDelegateImpl())
])
server = HTTPServer(router)
server = HTTPServer(router)
Rules are instances of `Rule` class. They contain some target (`~.web.Application` instance,
-`~.httputil.HTTPMessageDelegate` subclass, a callable or a nested `Router`) and provide the
-basic routing logic defining whether this rule is a match for a particular request.
+`~.httputil.HTTPServerConnectionDelegate` implementation, a callable or a nested `Router`) and
+provide the basic routing logic defining whether this rule is a match for a particular request.
This routing logic is implemented in `Matcher` subclasses (see `HostMatches`, `PathMatches`
and others).
import re
from functools import partial
-from inspect import isclass
from tornado import httputil
from tornado.httpserver import _CallableAdapter
raise NotImplementedError()
def start_request(self, server_conn, request_conn):
- return _RoutingDelegate(self, request_conn)
+ return _RoutingDelegate(self, server_conn, request_conn)
class ReversibleRouter(Router):
class _RoutingDelegate(httputil.HTTPMessageDelegate):
- def __init__(self, router, request_conn):
- self.connection = request_conn
+ def __init__(self, router, server_conn, request_conn):
+ self.server_conn = server_conn
+ self.request_conn = request_conn
self.delegate = None
self.router = router # type: Router
def headers_received(self, start_line, headers):
request = httputil.HTTPServerRequest(
- connection=self.connection, start_line=start_line,
- headers=headers)
+ connection=self.request_conn,
+ server_connection=self.server_conn,
+ start_line=start_line, headers=headers)
self.delegate = self.router.find_handler(request)
return self.delegate.headers_received(start_line, headers)
if isinstance(target, Router):
return target.find_handler(request, **target_params)
- elif isclass(target) and issubclass(target, httputil.HTTPMessageDelegate):
- return target(request.connection)
+ elif isinstance(target, httputil.HTTPServerConnectionDelegate):
+ return target.start_request(request.server_connection, request.connection)
elif callable(target):
return _CallableAdapter(
whether the rule should be considered a match for a specific
request.
:arg target: a Rule's target (typically a ``RequestHandler`` or
- `~.httputil.HTTPMessageDelegate` subclass or even a nested `Router`).
+ `~.httputil.HTTPServerConnectionDelegate` subclass or even a nested `Router`).
:arg dict target_kwargs: a dict of parameters that can be useful
at the moment of target instantiation (for example, ``status_code``
for a ``RequestHandler`` subclass). They end up in
from __future__ import absolute_import, division, print_function, with_statement
-from tornado.httputil import HTTPHeaders, HTTPMessageDelegate, ResponseStartLine
+from tornado.httputil import HTTPHeaders, HTTPMessageDelegate, HTTPServerConnectionDelegate, ResponseStartLine
from tornado.routing import HostMatches, PathMatches, ReversibleRouter, Rule, RuleRouter
from tornado.testing import AsyncHTTPTestCase
from tornado.web import Application, RequestHandler
self.assertEqual(response.body, b"app2: first_handler: /first_handler")
-class MessageDelegate(HTTPMessageDelegate):
- def __init__(self, connection):
- self.connection = connection
+class ConnectionDelegate(HTTPServerConnectionDelegate):
+ def start_request(self, server_conn, request_conn):
- def finish(self):
- response_body = b"OK"
- self.connection.write_headers(
- ResponseStartLine("HTTP/1.1", 200, "OK"),
- HTTPHeaders({"Content-Length": str(len(response_body))}))
- self.connection.write(response_body)
- self.connection.finish()
+ class MessageDelegate(HTTPMessageDelegate):
+ def __init__(self, connection):
+ self.connection = connection
+
+ def finish(self):
+ response_body = b"OK"
+ self.connection.write_headers(
+ ResponseStartLine("HTTP/1.1", 200, "OK"),
+ HTTPHeaders({"Content-Length": str(len(response_body))}))
+ self.connection.write(response_body)
+ self.connection.finish()
+
+ return MessageDelegate(request_conn)
class RuleRouterTest(AsyncHTTPTestCase):
]),
Rule(PathMatches("/first_handler"), FirstHandler, name="first_handler"),
Rule(PathMatches("/request_callable"), request_callable),
- ("/message_delegate", MessageDelegate)
+ ("/connection_delegate", ConnectionDelegate())
])
return app
response = self.fetch("/first_handler", headers={'Host': 'www.example.com'})
self.assertEqual(response.body, b"second_handler: /first_handler")
- response = self.fetch("/message_delegate")
+ response = self.fetch("/connection_delegate")
self.assertEqual(response.body, b"OK")
response = self.fetch("/request_callable")