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
--- 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')
--- /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')