# HG changeset patch # User Christophe de Vienne # Date 1404918872 -7200 # Node ID 39768d122f974d05b9b86dcd102d7225bee74fe3 # Parent 7b7ed56bf2fbd06cddb28986eb12f55eb8f9bfcc Isolate the default handler and extend its role The handler now does the job of CubicWebPublisher.main_handle_request() and calls CubicWebPublisher.core_handle(). Instead of using config.add_notfound_view, a catchall route is defined and the handler plugged to it. Related to #4291173 diff -r 7b7ed56bf2fb -r 39768d122f97 pyramid_cubicweb/__init__.py --- a/pyramid_cubicweb/__init__.py Sun Jul 06 18:25:31 2014 +0200 +++ b/pyramid_cubicweb/__init__.py Wed Jul 09 17:14:32 2014 +0200 @@ -1,6 +1,5 @@ from cubicweb.web.request import CubicWebRequestBase from cubicweb.cwconfig import CubicWebConfiguration -from cubicweb.web.application import CubicWebPublisher from cubicweb import repoapi import cubicweb @@ -63,25 +62,6 @@ status_out = property(_get_status_out, _set_status_out) -class PyramidSessionHandler(object): - """A CW Session handler that rely on the pyramid API to fetch the needed - informations""" - - def __init__(self, appli): - self.appli = appli - - def get_session(self, req): - return req._request.cw_session - - def logout(self, req, goto_url): - del req._request.session['cubicweb.sessionid'] - if not req.session.closed: - req.session.repo.close(req.session.sessionid) - for name, value in security.forget(req._request): - req.headers_out.setHeader(name, value) - raise cubicweb.web.LogOut(url=goto_url) - - def render_view(request, vid, **kwargs): vreg = request.registry['cubicweb.registry'] # XXX The select() function could, know how to handle a pyramid @@ -128,22 +108,6 @@ return response -class CubicWebPyramidHandler(object): - def __init__(self, appli): - self.appli = appli - - def __call__(self, request): - req = request.cw_request() - result = self.appli.handle_request(req, req.path) - if result is not None: - request.response.body = result - request.response.headers.clear() - for k, v in req.headers_out.getAllRawHeaders(): - for item in v: - request.response.headers.add(k, item) - return request.response - - def _cw_cnx(request): # XXX We should not need to use the session. A temporary one should be # enough. (by using repoapi.connect()) @@ -250,15 +214,4 @@ config.add_route('hello', '/hello') config.add_view(hello_world, route_name='hello') - # Set up a defaut route to handle non-catched urls. - # This is to keep legacy compatibility for cubes that makes use of the - # cubicweb controllers. - cwappli = CubicWebPublisher( - cwconfig.repository(), cwconfig, - session_handler_fact=PyramidSessionHandler) - handler = CubicWebPyramidHandler(cwappli) - - config.registry['cubicweb.appli'] = cwappli - config.registry['cubicweb.handler'] = handler - - config.add_notfound_view(handler) + config.include('pyramid_cubicweb.handler') diff -r 7b7ed56bf2fb -r 39768d122f97 pyramid_cubicweb/handler.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyramid_cubicweb/handler.py Wed Jul 09 17:14:32 2014 +0200 @@ -0,0 +1,86 @@ +from pyramid import security +from pyramid.httpexceptions import HTTPSeeOther + +from cubicweb.web.application import CubicWebPublisher + +from cubicweb.web import ( + StatusResponse, DirectResponse, Redirect, NotFound, LogOut, + RemoteCallFailed, InvalidSession, RequestError, PublishException) + + +class PyramidSessionHandler(object): + """A CW Session handler that rely on the pyramid API to fetch the needed + informations""" + + def __init__(self, appli): + self.appli = appli + + def get_session(self, req): + return req._request.cw_session + + def logout(self, req, goto_url): + raise LogOut(url=goto_url) + + +class CubicWebPyramidHandler(object): + def __init__(self, appli): + self.appli = appli + + def __call__(self, request): + """ + Handler that mimics what CubicWebPublisher.main_handle_request does and + call CubicWebPyramidHandler.core_handle. + + """ + # XXX In a later version of this handler, we need to by-pass + # core_handle and CubicWebPublisher altogether so that the various CW + # exceptions are converted to their pyramid equivalent. + + req = request.cw_request() + req.set_cnx(request.cw_cnx) + + # XXX The main handler of CW forbid anonymous https connections + # I guess we can drop this "feature" but in doubt I leave this comment + # so we don't forget about it. (cdevienne) + + try: + content = self.appli.core_handle(req, req.path) + + if content is not None: + request.response.body = content + request.response.headers.clear() + for k, v in req.headers_out.getAllRawHeaders(): + for item in v: + request.response.headers.add(k, item) + except LogOut as ex: + # The actual 'logging out' logic should be in separated function + # that is accessible by the pyramid views + del req._request.session['cubicweb.sessionid'] + if not req.session.closed: + req.session.repo.close(req.session.sessionid) + headers = security.forget(request) + raise HTTPSeeOther(ex.url, headers=headers) + except Redirect as ex: + raise HTTPSeeOther(ex.url) + # except AuthenticationError: + # XXX I don't think it makes sens to catch this ex here (cdevienne) + + return request.response + + +def includeme(config): + # Set up a defaut route to handle non-catched urls. + # This is to keep legacy compatibility for cubes that makes use of the + # cubicweb controllers. + cwconfig = config.registry['cubicweb.config'] + repository = config.registry['cubicweb.repository'] + cwappli = CubicWebPublisher( + repository, cwconfig, + session_handler_fact=PyramidSessionHandler) + handler = CubicWebPyramidHandler(cwappli) + + config.registry['cubicweb.appli'] = cwappli + config.registry['cubicweb.handler'] = handler + + config.add_route('catchall', pattern='*path') + config.add_view(handler, route_name='catchall')