diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-01-24 10:31:20 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-01-24 10:31:20 +0000 |
| commit | 7292d4d6a7d63c55a718dc50943bc9cbf90ae6fe (patch) | |
| tree | 61af50cf949b1f2d895375f37d223fbf12237fce /repoze/bfg/router.py | |
| parent | 5ab02920213361e245489c1eedd83757893e0ffa (diff) | |
| download | pyramid-7292d4d6a7d63c55a718dc50943bc9cbf90ae6fe.tar.gz pyramid-7292d4d6a7d63c55a718dc50943bc9cbf90ae6fe.tar.bz2 pyramid-7292d4d6a7d63c55a718dc50943bc9cbf90ae6fe.zip | |
Behavior Changes
----------------
- The ``repoze.bfg.view.render_view_to_response`` API will no longer
raise a ValueError if an object returned by a view function it calls
does not possess certain attributes (``headerlist``, ``app_iter``,
``status``). This API used to attempt to perform a check using the
``is_response`` function in ``repoze.bfg.view``, and raised a
``ValueError`` if the ``is_response`` check failed. The
responsibility is now the caller's to ensure that the return value
from a view function is a "real" response.
- WSGI environ dicts passed to ``repoze.bfg`` 's Router must now
contain a REQUEST_METHOD key/value; if they do not, a KeyError will
be raised (speed).
Implementation Changes
----------------------
- Various speed micro-tweaks.
Diffstat (limited to 'repoze/bfg/router.py')
| -rw-r--r-- | repoze/bfg/router.py | 74 |
1 files changed, 48 insertions, 26 deletions
diff --git a/repoze/bfg/router.py b/repoze/bfg/router.py index 05236cfed..c9366477c 100644 --- a/repoze/bfg/router.py +++ b/repoze/bfg/router.py @@ -18,7 +18,10 @@ from repoze.bfg.interfaces import IRootFactory from repoze.bfg.interfaces import IRouter from repoze.bfg.interfaces import IRoutesMapper from repoze.bfg.interfaces import ITraverserFactory +from repoze.bfg.interfaces import ISecurityPolicy from repoze.bfg.interfaces import ISettings +from repoze.bfg.interfaces import IView +from repoze.bfg.interfaces import IViewPermission from repoze.bfg.log import make_stream_logger @@ -33,10 +36,11 @@ from repoze.bfg.settings import Settings from repoze.bfg.urldispatch import RoutesRootFactory -from repoze.bfg.view import render_view_to_response -from repoze.bfg.view import view_execution_permitted +from repoze.bfg.view import _view_execution_permitted -_marker = () +_marker = object() + +# 95090 function calls (95087 primitive calls) in 0.277 CPU seconds class Router(object): """ The main repoze.bfg WSGI application. """ @@ -44,6 +48,10 @@ class Router(object): def __init__(self, registry): self.registry = registry + self.settings = registry.queryUtility(ISettings) + self.request_factory = registry.queryUtility(IRequestFactory) + self.security_policy = registry.queryUtility(ISecurityPolicy) + self.logger = registry.queryUtility(ILogger, 'repoze.bfg.debug') @property def root_policy(self): @@ -53,23 +61,25 @@ class Router(object): def __call__(self, environ, start_response): """ Accept ``environ`` and ``start_response``; route requests to - 'view' code based on registrations within the application - registry; call ``start_response`` and return an iterable. + ``repoze.bfg`` views based on registrations within the + application registry; call ``start_response`` and return an + iterable. """ - reg = self.registry - registry_manager.push(reg) + registry = self.registry + registry_manager.push(registry) try: - request_factory = reg.queryUtility(IRequestFactory) + request_factory = self.request_factory if request_factory is None: - method = environ.get('REQUEST_METHOD', 'GET') + method = environ['REQUEST_METHOD'] request_factory = HTTP_METHOD_FACTORIES.get(method, Request) - request = request_factory(environ) - reg.notify(NewRequest(request)) - root_factory = reg.getUtility(IRootFactory) + request = request_factory(environ) + + registry.has_listeners and registry.notify(NewRequest(request)) + root_factory = registry.getUtility(IRootFactory) root = root_factory(environ) - traverser = reg.getAdapter(root, ITraverserFactory) + traverser = registry.getAdapter(root, ITraverserFactory) context, view_name, subpath = traverser(environ) # XXX webob.Request's __setattr__ is slow here: investigate. @@ -78,36 +88,44 @@ class Router(object): request.view_name = view_name request.subpath = subpath - permitted = view_execution_permitted(context, request, view_name) + settings = self.settings - settings = reg.queryUtility(ISettings) debug_authorization = settings and settings.debug_authorization + security_policy = self.security_policy + + permission = None + + if security_policy is not None: + permission = registry.queryMultiAdapter((context, request), + IViewPermission, + name=view_name) + + permitted = _view_execution_permitted(context, request, view_name, + security_policy, permission, + debug_authorization) - logger = None + logger = self.logger if debug_authorization: - logger = reg.queryUtility(ILogger, 'repoze.bfg.debug') logger and logger.debug( 'debug_authorization of url %s (view name %r against ' 'context %r): %s' % ( - request.url, view_name, context, permitted.msg) + request.url, view_name, context, permitted) ) if not permitted: if debug_authorization: - msg = permitted.msg + msg = str(permitted) else: msg = 'Unauthorized: failed security policy check' app = HTTPUnauthorized(escape(msg)) return app(environ, start_response) - response = render_view_to_response(context, request, view_name, - secure=False) + response = registry.queryMultiAdapter( + (context, request), IView, name=view_name) if response is None: debug_notfound = settings and settings.debug_notfound if debug_notfound: - if logger is None: - logger = reg.queryUtility(ILogger, 'repoze.bfg.debug') msg = ( 'debug_notfound of url %s; path_info: %r, context: %r, ' 'view_name: %r, subpath: %r' % ( @@ -120,10 +138,14 @@ class Router(object): app = HTTPNotFound(escape(msg)) return app(environ, start_response) - reg.notify(NewResponse(response)) + registry.has_listeners and registry.notify(NewResponse(response)) - start_response(response.status, response.headerlist) - return response.app_iter + try: + start_response(response.status, response.headerlist) + return response.app_iter + except AttributeError: + raise ValueError( + 'Non-response object returned from view: %r' % response) finally: registry_manager.pop() |
