--- a/wsgi/handler.py Wed Aug 01 10:30:48 2012 +0200
+++ b/wsgi/handler.py Thu Mar 21 18:13:31 2013 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -15,14 +15,16 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""WSGI request handler for cubicweb
+"""WSGI request handler for cubicweb"""
-"""
+
__docformat__ = "restructuredtext en"
+from itertools import chain, repeat, izip
+
from cubicweb import AuthenticationError
-from cubicweb.web import Redirect, DirectResponse, StatusResponse, LogOut
+from cubicweb.web import DirectResponse
from cubicweb.web.application import CubicWebPublisher
from cubicweb.wsgi.request import CubicWebWsgiRequest
@@ -71,7 +73,6 @@
505: 'HTTP VERSION NOT SUPPORTED',
}
-
class WSGIResponse(object):
"""encapsulates the wsgi response parameters
(code, headers and body if there is one)
@@ -79,7 +80,9 @@
def __init__(self, code, req, body=None):
text = STATUS_CODE_TEXT.get(code, 'UNKNOWN STATUS CODE')
self.status = '%s %s' % (code, text)
- self.headers = [(str(k), str(v)) for k, v in req.headers_out.items()]
+ self.headers = list(chain(*[izip(repeat(k), v)
+ for k, v in req.headers_out.getAllRawHeaders()]))
+ self.headers = [(str(k), str(v)) for k, v in self.headers]
if body:
self.body = [body]
else:
@@ -103,95 +106,31 @@
def __init__(self, config, vreg=None):
self.appli = CubicWebPublisher(config, vreg=vreg)
self.config = config
- self.base_url = None
-# self.base_url = config['base-url'] or config.default_base_url()
-# assert self.base_url[-1] == '/'
-# self.https_url = config['https-url']
-# assert not self.https_url or self.https_url[-1] == '/'
+ self.base_url = config['base-url']
+ self.https_url = config['https-url']
self.url_rewriter = self.appli.vreg['components'].select_or_none('urlrewriter')
def _render(self, req):
"""this function performs the actual rendering
- XXX missing: https handling, url rewriting, cache management,
- authentication
"""
if self.base_url is None:
self.base_url = self.config._base_url = req.base_url()
- # XXX https handling needs to be implemented
- if req.authmode == 'http':
- # activate realm-based auth
- realm = self.config['realm']
- req.set_header('WWW-Authenticate', [('Basic', {'realm' : realm })], raw=False)
try:
- self.appli.connect(req)
- except Redirect, ex:
- return self.redirect(req, ex.location)
- path = req.path
- if not path or path == "/":
- path = 'view'
- try:
- result = self.appli.publish(path, req)
+ path = req.path
+ result = self.appli.handle_request(req, path)
except DirectResponse, ex:
- return WSGIResponse(200, req, ex.response)
- except StatusResponse, ex:
- return WSGIResponse(ex.status, req, ex.content)
- except AuthenticationError: # must be before AuthenticationError
- return self.request_auth(req)
- except LogOut:
- if self.config['auth-mode'] == 'cookie':
- # in cookie mode redirecting to the index view is enough :
- # either anonymous connection is allowed and the page will
- # be displayed or we'll be redirected to the login form
- msg = req._('you have been logged out')
-# if req.https:
-# req._base_url = self.base_url
-# req.https = False
- url = req.build_url('view', vid='index', __message=msg)
- return self.redirect(req, url)
- else:
- # in http we have to request auth to flush current http auth
- # information
- return self.request_auth(req, loggedout=True)
- except Redirect, ex:
- return self.redirect(req, ex.location)
- if not result:
- # no result, something went wrong...
- self.error('no data (%s)', req)
- # 500 Internal server error
- return self.redirect(req, req.build_url('error'))
- return WSGIResponse(200, req, result)
+ return ex.response
+ return WSGIResponse(req.status_out, req, result)
def __call__(self, environ, start_response):
"""WSGI protocol entry point"""
- req = CubicWebWsgiRequest(environ, self.appli.vreg, self.base_url)
+ req = CubicWebWsgiRequest(environ, self.appli.vreg)
response = self._render(req)
start_response(response.status, response.headers)
return response.body
- def redirect(self, req, location):
- """convenience function which builds a redirect WSGIResponse"""
- self.debug('redirecting to %s', location)
- req.set_header('location', str(location))
- return WSGIResponse(303, req)
- def request_auth(self, req, loggedout=False):
- """returns the appropriate WSGIResponse to require the user to log in
- """
-# if self.https_url and req.base_url() != self.https_url:
-# return self.redirect(self.https_url + 'login')
- if self.config['auth-mode'] == 'http':
- code = 401 # UNAUTHORIZED
- else:
- code = 403 # FORBIDDEN
- if loggedout:
-# if req.https:
-# req._base_url = self.base_url
-# req.https = False
- content = self.appli.loggedout_content(req)
- else:
- content = self.appli.need_login_content(req)
- return WSGIResponse(code, req, content)
# these are overridden by set_log_methods below
# only defining here to prevent pylint from complaining