[view] fix TypeError when calling req.view('vid', entity=entity) (closes #1947474)
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr## This file is part of CubicWeb.## CubicWeb is free software: you can redistribute it and/or modify it under the# terms of the GNU Lesser General Public License as published by the Free# Software Foundation, either version 2.1 of the License, or (at your option)# any later version.## CubicWeb is distributed in the hope that it will be useful, but WITHOUT# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more# details.## 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"""__docformat__="restructuredtext en"fromcubicwebimportAuthenticationErrorfromcubicweb.webimportRedirect,DirectResponse,StatusResponse,LogOutfromcubicweb.web.applicationimportCubicWebPublisherfromcubicweb.wsgi.requestimportCubicWebWsgiRequest# See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.htmlSTATUS_CODE_TEXT={100:'CONTINUE',101:'SWITCHING PROTOCOLS',200:'OK',201:'CREATED',202:'ACCEPTED',203:'NON-AUTHORITATIVE INFORMATION',204:'NO CONTENT',205:'RESET CONTENT',206:'PARTIAL CONTENT',300:'MULTIPLE CHOICES',301:'MOVED PERMANENTLY',302:'FOUND',303:'SEE OTHER',304:'NOT MODIFIED',305:'USE PROXY',306:'RESERVED',307:'TEMPORARY REDIRECT',400:'BAD REQUEST',401:'UNAUTHORIZED',402:'PAYMENT REQUIRED',403:'FORBIDDEN',404:'NOT FOUND',405:'METHOD NOT ALLOWED',406:'NOT ACCEPTABLE',407:'PROXY AUTHENTICATION REQUIRED',408:'REQUEST TIMEOUT',409:'CONFLICT',410:'GONE',411:'LENGTH REQUIRED',412:'PRECONDITION FAILED',413:'REQUEST ENTITY TOO LARGE',414:'REQUEST-URI TOO LONG',415:'UNSUPPORTED MEDIA TYPE',416:'REQUESTED RANGE NOT SATISFIABLE',417:'EXPECTATION FAILED',500:'INTERNAL SERVER ERROR',501:'NOT IMPLEMENTED',502:'BAD GATEWAY',503:'SERVICE UNAVAILABLE',504:'GATEWAY TIMEOUT',505:'HTTP VERSION NOT SUPPORTED',}classWSGIResponse(object):"""encapsulates the wsgi response parameters (code, headers and body if there is one) """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))fork,vinreq.headers_out.items()]ifbody:self.body=[body]else:self.body=[]def__iter__(self):returniter(self.body)classCubicWebWSGIApplication(object):"""This is the wsgi application which will be called by the wsgi server with the WSGI ``environ`` and ``start_response`` parameters. XXX: missing looping tasks and proper repository shutdown when the application is stopped. NOTE: no pyro """def__init__(self,config,vreg=None):self.appli=CubicWebPublisher(config,vreg=vreg)self.config=configself.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.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 """ifself.base_urlisNone:self.base_url=self.config._base_url=req.base_url()# XXX https handling needs to be implementedifreq.authmode=='http':# activate realm-based authrealm=self.config['realm']req.set_header('WWW-Authenticate',[('Basic',{'realm':realm})],raw=False)try:self.appli.connect(req)exceptRedirect,ex:returnself.redirect(req,ex.location)path=req.pathifnotpathorpath=="/":path='view'try:result=self.appli.publish(path,req)exceptDirectResponse,ex:returnWSGIResponse(200,req,ex.response)exceptStatusResponse,ex:returnWSGIResponse(ex.status,req,ex.content)exceptAuthenticationError:# must be before AuthenticationErrorreturnself.request_auth(req)exceptLogOut:ifself.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 formmsg=req._('you have been logged out')# if req.https:# req._base_url = self.base_url# req.https = Falseurl=req.build_url('view',vid='index',__message=msg)returnself.redirect(req,url)else:# in http we have to request auth to flush current http auth# informationreturnself.request_auth(req,loggedout=True)exceptRedirect,ex:returnself.redirect(req,ex.location)ifnotresult:# no result, something went wrong...self.error('no data (%s)',req)# 500 Internal server errorreturnself.redirect(req,req.build_url('error'))returnWSGIResponse(200,req,result)def__call__(self,environ,start_response):"""WSGI protocol entry point"""req=CubicWebWsgiRequest(environ,self.appli.vreg,self.base_url)response=self._render(req)start_response(response.status,response.headers)returnresponse.bodydefredirect(self,req,location):"""convenience function which builds a redirect WSGIResponse"""self.debug('redirecting to %s',location)req.set_header('location',str(location))returnWSGIResponse(303,req)defrequest_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')ifself.config['auth-mode']=='http':code=401# UNAUTHORIZEDelse:code=403# FORBIDDENifloggedout:# if req.https:# req._base_url = self.base_url# req.https = Falsecontent=self.appli.loggedout_content(req)else:content=self.appli.need_login_content(req)returnWSGIResponse(code,req,content)# these are overridden by set_log_methods below# only defining here to prevent pylint from complaininginfo=warning=error=critical=exception=debug=lambdamsg,*a,**kw:NonefromloggingimportgetLoggerfromcubicwebimportset_log_methodsset_log_methods(CubicWebWSGIApplication,getLogger('cubicweb.wsgi'))