diff -r 0c111b232927 -r 88c71ad83d47 wsgi/handler.py --- 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 . -"""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