def _dispatch_call(self): """Handles dispatching the request to the function using Routes""" log_debug = self._pylons_log_debug req = pylons.request._current_obj() action = req.environ['pylons.routes_dict'].get('action') action_method = action.replace('-', '_') if log_debug: log.debug("Looking for %r method to handle the request", action_method) try: func = getattr(self, action_method, None) except UnicodeEncodeError: func = None if isinstance(func, types.MethodType): # Store function used to handle request req.environ['pylons.action_method'] = func response = self._inspect_call(func) else: if log_debug: log.debug("Couldn't find %r method to handle response", action) if pylons.config['debug']: raise NotImplementedError('Action %r is not implemented' % action) else: response = WSGIResponse(code=404) return response
def test_wsgiresponse_charset(): response = WSGIResponse(mimetype='text/html; charset=UTF-8') assert response.content_type == 'text/html' assert response.charset == 'UTF-8' response.write(u'test') response.write(u'test2') response.write('test3') status, headers, content = response.wsgi_response() for data in content: assert isinstance(data, str) WSGIResponse.defaults._push_object( dict(content_type='text/html', charset='iso-8859-1')) try: response = WSGIResponse() response.write(u'test') response.write(u'test2') response.write('test3') status, headers, content = response.wsgi_response() for data in content: assert isinstance(data, str) finally: WSGIResponse.defaults._pop_object() # WSGIResponse will allow unicode to pass through when no charset is # set WSGIResponse.defaults._push_object( dict(content_type='text/html', charset=None)) try: response = WSGIResponse(u'test') response.write(u'test1') status, headers, content = response.wsgi_response() for data in content: assert isinstance(data, unicode) finally: WSGIResponse.defaults._pop_object() WSGIResponse.defaults._push_object( dict(content_type='text/html', charset='')) try: response = WSGIResponse(u'test') response.write(u'test1') status, headers, content = response.wsgi_response() for data in content: assert isinstance(data, unicode) finally: WSGIResponse.defaults._pop_object()
def test_call_wsgiresponse(): resp = WSGIResponse(b'some content', 'application/octet-stream') def sp(status, response_headers): assert status == '200 OK' assert sorted(response_headers) == [ ('cache-control', 'no-cache'), ('content-type', 'application/octet-stream'), ] assert resp({}, sp) == [b'some content'] f = io.BytesIO(b'some content') resp = WSGIResponse(f, 'application/octet-stream') assert list(resp({}, sp)) == [b'some content'] f = io.BytesIO() resp = WSGIResponse(f, 'application/octet-stream') assert resp({'wsgi.file_wrapper': lambda x: x}, sp) is f
def _dispatch_call(self): """Dispatch the call to the function chosen by __call__""" raw_response = self._inspect_call(self._func) if not isinstance(raw_response, xmlrpclib.Fault): raw_response = (raw_response, ) response = xmlrpclib.dumps(raw_response, methodresponse=True, allow_none=self.allow_none) return WSGIResponse(response)
def __call__(self, environ, start_response): registry = environ['paste.registry'] environ_config = environ.setdefault('pylons.environ_config', {}) if self.setup_cache: registry.register(pylons.cache, environ['beaker.cache']) environ_config['cache'] = 'beaker.cache' if self.setup_session: registry.register(pylons.session, environ['beaker.session']) environ_config['session'] = 'beaker.session' if self.setup_g: registry.register(pylons.g, self.g) # Update the environ environ.update(self.environ) registry.register(pylons.request, WSGIRequest(environ)) registry.register(pylons.response, WSGIResponse()) return self.app(environ, start_response)
def __call__(self, *args, **kargs): """Makes our controller a callable to handle requests This is called when dispatched to as the Controller class docs explain more fully. """ req = pylons.request._current_obj() # Keep private methods private if req.environ['pylons.routes_dict'].get('action', '').startswith('_'): return WSGIResponse(code=404) if hasattr(self, '__before__'): self._inspect_call(self.__before__, **kargs) response = self._dispatch_call() # If its not a WSGI response, and we have content, it needs to # be wrapped in the response object if hasattr(response, 'wsgi_response'): # It's either a legacy WSGIResponse object, or an exception # that got tossed. Strip headers if its anything other than a # 2XX status code, and strip cookies if its anything other than # a 2XX or 3XX status code. if response.status_code < 300: response.headers.update(pylons.response.headers) if response.status_code < 400: for c in pylons.response.cookies.values(): response.headers.add('Set-Cookie', c.output(header='')) registry = req.environ['paste.registry'] registry.replace(pylons.response, response) elif isinstance(response, types.GeneratorType): pylons.response.content = response elif isinstance(response, basestring): pylons.response.write(response) response = pylons.response._current_obj() if hasattr(self, '__after__'): self._inspect_call(self.__after__) return response
def setup_app_env(self, environ, start_response): """Setup and register all the Pylons objects with the registry""" if self.log_debug: log.debug("Setting up Pylons stacked object globals") registry = environ['paste.registry'] registry.register(WSGIRequest.defaults, self.request_options) registry.register(WSGIResponse.defaults, self.response_options) req = WSGIRequest(environ) # Setup the basic pylons global objects registry.register(pylons.request, req) registry.register(pylons.response, WSGIResponse()) registry.register(pylons.buffet, self.buffet) registry.register(pylons.g, self.globals) registry.register(pylons.config, self.config) registry.register(pylons.h, self.helpers or \ pylons.legacy.load_h(self.package_name)) # Setup the translator global object registry.register(pylons.translator, gettext.NullTranslations()) lang = self.config.get('lang') if lang: set_lang(lang) if self.config['pylons.strict_c']: registry.register(pylons.c, ContextObj()) else: registry.register(pylons.c, AttribSafeContextObj()) econf = environ['pylons.environ_config'] if econf.get('session'): registry.register(pylons.session, environ[econf['session']]) if econf.get('cache'): registry.register(pylons.cache, environ[econf['cache']])
def response(self, environ): from paste.wsgiwrappers import WSGIResponse headers, content = self.prepare_content(environ) resp = WSGIResponse(code=self.code, content=content) resp.headers = resp.headers.fromlist(headers) return resp
def __call__(self, environ, start_response): log_debug = self._pylons_log_debug # Keep private methods private if environ['pylons.routes_dict'].get('action', '')[:1] in ('_', '-'): if log_debug: log.debug("Action starts with _, private action not allowed. " "Returning a 404 response") return WSGIResponse(code=404)(environ, start_response) start_response_called = [] def repl_start_response(status, headers, exc_info=None): response = pylons.response._current_obj() start_response_called.append(None) # Copy the headers from the global response # XXX: TODO: This should really be done with a more efficient # header merging function at some point. if log_debug: log.debug( "Merging pylons.response headers into " "start_response call, status: %s", status) response.headers.update(HeaderDict.fromlist(headers)) headers = response.headers.headeritems() for c in pylons.response.cookies.values(): headers.append(('Set-Cookie', c.output(header=''))) return start_response(status, headers, exc_info) self.start_response = repl_start_response if hasattr(self, '__before__'): response = self._inspect_call(self.__before__) if hasattr(response, '_exception'): return response(environ, self.start_response) response = self._dispatch_call() if not start_response_called: # If its not a WSGI response, and we have content, it needs to # be wrapped in the response object if hasattr(response, 'wsgi_response'): # It's either a legacy WSGIResponse object, or an exception # that got tossed. if log_debug: log.debug("Controller returned a Response object, merging " "it with pylons.response") response.headers.update(pylons.response.headers) for c in pylons.response.cookies.values(): response.headers.add('Set-Cookie', c.output(header='')) registry = environ['paste.registry'] registry.replace(pylons.response, response) elif isinstance(response, types.GeneratorType): if log_debug: log.debug("Controller returned a generator, setting it as " "the pylons.response content") pylons.response.content = response elif response is None: if log_debug: log.debug("Controller returned None") else: if log_debug: log.debug("Assuming controller returned a basestring or " "buffer, writing it to pylons.response") pylons.response.write(response) response = pylons.response._current_obj() if hasattr(self, '__after__'): after = self._inspect_call(self.__after__) if hasattr(after, '_exception'): return after(environ, self.start_response) if hasattr(response, 'wsgi_response'): # Copy the response object into the testing vars if we're testing if 'paste.testing_variables' in environ: environ['paste.testing_variables']['response'] = response if log_debug: log.debug("Calling Response object to return WSGI data") return response(environ, self.start_response) if log_debug: log.debug( "Response assumed to be WSGI content, returning un-touched") return response
def xmlrpc_fault(code, message): """Convienence method to return a Pylons response XMLRPC Fault""" fault = xmlrpclib.Fault(code, message) return WSGIResponse(xmlrpclib.dumps(fault, methodresponse=True))