def request(self, environ): try: path = environ.get('PATH_INFO') if not path or path == '/': return self.home(environ) else: path = path[1:] leaf = True if path.endswith('/'): leaf = False path = path[:-1] keys = tuple(path.split('/')) bits = [] route = None while keys: route = self.routes.get(keys) if route: break bits.insert(0, keys[-1]) keys = keys[:-1] if route is None: raise HttpException(status=404) return route(self, environ, bits) except HttpException as e: status = e.status if has_empty_content(status, environ['REQUEST_METHOD']): return wsgi.WsgiResponse(status, response_headers=e.headers) else: content = error_messages.get(status,'') title = responses.get(status) content = '<h1>%s - %s</h1>%s' % (status, title, content) return self.render(content, title=title, status=status, headers=e.headers)
def get_headers(self): """The list of headers for this response """ headers = self.headers if has_empty_content(self.status_code): headers.pop('content-type', None) headers.pop('content-length', None) self._content = () else: if not self.is_streamed: cl = 0 for c in self.content: cl += len(c) if cl == 0 and self.content_type in JSON_CONTENT_TYPES: self._content = (b'{}', ) cl = len(self._content[0]) headers['Content-Length'] = str(cl) ct = self.content_type # content type encoding available if self.encoding: ct = ct or 'text/plain' if 'charset=' not in ct: ct = '%s; charset=%s' % (ct, self.encoding) if ct: headers['Content-Type'] = ct if self.method == HEAD: self._content = () if self.can_set_cookies(): for c in self.cookies.values(): headers.add_header('Set-Cookie', c.OutputString()) return list(headers)
def handle_wsgi_error(environ, failure): '''The default handler for errors while serving an Http requests. :parameter environ: The WSGI environment. :parameter failure: a :class:`Failure`. :return: a :class:`WsgiResponse` ''' request = wsgi_request(environ) response = request.response error = failure.error if isinstance(error, HTTPError): response.status_code = error.code or 500 else: response.status_code = getattr(error, 'status', 500) response.headers.update(getattr(error, 'headers', None) or ()) path = '@ path "%s"' % environ.get('PATH_INFO', '/') status = response.status_code if status == 500: failure.log(msg='Unhandled exception during WSGI response %s.%s' % (path, dump_environ(environ)), level='critical') else: failure.log(msg='WSGI %s status code %s' % (status, path), level='warning') if has_empty_content(status, request.method) or status in REDIRECT_CODES: content = None else: request.cache.pop('html_document', None) renderer = environ.get('error.handler') or render_error try: content = renderer(request, failure) except Exception: LOGGER.critical('Error while rendering error') content = None response.content = content return response
def get_headers(self): """The list of headers for this response """ headers = self.headers if has_empty_content(self.status_code, self.method): headers.pop("content-type", None) headers.pop("content-length", None) self._content = () else: if not self.is_streamed: cl = 0 for c in self.content: cl += len(c) if cl == 0 and self.content_type in JSON_CONTENT_TYPES: self._content = (b"{}",) cl = len(self._content[0]) headers["Content-Length"] = str(cl) ct = self.content_type # content type encoding available if self.encoding: ct = ct or "text/plain" if "charset=" not in ct: ct = "%s; charset=%s" % (ct, self.encoding) if ct: headers["Content-Type"] = ct if self.can_set_cookies(): for c in self.cookies.values(): headers.add_header("Set-Cookie", c.OutputString()) return list(headers)
def get_headers(self): """The list of headers for this response """ headers = self.headers if has_empty_content(self.status_code): headers.pop('content-type', None) headers.pop('content-length', None) self._content = () else: if not self.is_streamed: cl = 0 for c in self.content: cl += len(c) if cl == 0 and self.content_type in JSON_CONTENT_TYPES: self._content = (b'{}',) cl = len(self._content[0]) headers['Content-Length'] = str(cl) ct = self.content_type # content type encoding available if self.encoding: ct = ct or 'text/plain' if 'charset=' not in ct: ct = '%s; charset=%s' % (ct, self.encoding) if ct: headers['Content-Type'] = ct if self.method == HEAD: self._content = () if self.can_set_cookies(): for c in self.cookies.values(): headers.add_header('Set-Cookie', c.OutputString()) return list(headers)
def handle_wsgi_error(environ, trace=None, content_type=None, encoding=None): """The default handler for errors while serving an Http requests. :parameter environ: The WSGI environment. :parameter trace: the error traceback. If not avaiable it will be obtained from ``sys.exc_info()``. :parameter content_type: Optional content type. :parameter encoding: Optional charset. :return: a :class:`WsgiResponse` """ content_type = content_type or environ.get("CONTENT_TYPE") response = WsgiResponse(content_type=content_type, environ=environ, encoding=encoding) if not trace: trace = sys.exc_info() error = trace[1] content = None response.status_code = getattr(error, "status", 500) response.headers.update(getattr(error, "headers", None) or ()) path = " @ path %s" % environ.get("PATH_INFO", "/") if response.status_code == 500: LOGGER.critical("Unhandled exception during WSGI response %s", path, exc_info=trace) else: LOGGER.info("WSGI %s status code %s", response.status_code, path) if has_empty_content(response.status_code) or response.status_code in REDIRECT_CODES: content = () response.content_type = None else: renderer = environ.get("wsgi_error_handler") if renderer: try: content = renderer(environ, response, trace) if is_failure(content): content.log() content = None except: LOGGER.critical("Error while rendering error", exc_info=True) content = None if content is None: msg = error_messages.get(response.status_code) or response.response if response.content_type == "text/html": content = textwrap.dedent( """\ <!DOCTYPE html> <html> <head> <title>{0[reason]}</title> </head> <body> <h1>{0[reason]}</h1> {0[msg]} <h3>{0[version]}</h3> </body> </html> """ ).format({"reason": response.status, "msg": msg, "version": pulsar.SERVER_SOFTWARE}) else: content = wsgi_error_msg(response, msg) response.content = content return response
def is_chunked(self): '''Only use chunked responses when the client is speaking HTTP/1.1 or newer and there was no Content-Length header set.''' if self.environ['wsgi.version'] <= (1,0): return False elif has_empty_content(int(self.status[:3])): # Do not use chunked responses when the response # is guaranteed to not have a response body. return False elif self.headers.get('Transfer-Encoding') == 'chunked': return True else: return self.content_length is None
def get_headers(self): headers = self.headers if has_empty_content(self.status_code, self.method): headers.pop("content-type", None) headers.pop("content-length", None) elif not self.is_streamed: cl = 0 for c in self.content: cl += len(c) headers["Content-Length"] = str(cl) for c in self.cookies.values(): headers["Set-Cookie"] = c.OutputString() return list(headers)
def is_chunked(self): '''Check if the response uses chunked transfer encoding. Only use chunked responses when the client is speaking HTTP/1.1 or newer and there was no Content-Length header set. ''' if (self.version <= (1, 0) or self._status == '200 Connection established' or has_empty_content(int(self.status[:3]))): return False elif self.headers.get('Transfer-Encoding') == 'chunked': return True else: return self.content_length is None
def handle_wsgi_error(environ, exc): '''The default error handler while serving a WSGI request. :param environ: The WSGI environment. :param exc: the exception :return: a :class:`.WsgiResponse` ''' if isinstance(exc, tuple): exc_info = exc exc = exc[1] else: exc_info = True request = wsgi_request(environ) request.cache.handle_wsgi_error = True response = request.response logger = get_logger(environ) # if isinstance(exc, HTTPError): response.status_code = exc.code or 500 else: response.status_code = getattr(exc, 'status', 500) response.headers.update(getattr(exc, 'headers', None) or ()) status = response.status_code if status >= 500: logger.critical('%s - @ %s.\n%s', exc, request.first_line, dump_environ(environ), exc_info=exc_info) else: log_wsgi_info(logger.warning, environ, response.status, exc) if has_empty_content(status, request.method) or status in REDIRECT_CODES: response.content_type = None response.content = None else: request.cache.pop('html_document', None) renderer = environ.get('error.handler') or render_error try: content = renderer(request, exc) except Exception: logger.critical('Error while rendering error', exc_info=True) response.content_type = 'text/plain' content = 'Critical server error' if content is not response: response.content = content return response
def handle_wsgi_error(environ, exc): '''The default error handler while serving a WSGI request. :param environ: The WSGI environment. :param exc: the exception :return: a :class:`.WsgiResponse` ''' if isinstance(exc, tuple): exc_info = exc exc = exc[1] else: exc_info = True request = wsgi_request(environ) request.cache.handle_wsgi_error = True response = request.response if isinstance(exc, HTTPError): response.status_code = exc.code or 500 else: response.status_code = getattr(exc, 'status', 500) response.headers.update(getattr(exc, 'headers', None) or ()) path = '@ %s "%s"' % (request.method, request.path) status = response.status_code if status == 500: logger.critical('Unhandled exception during HTTP response %s.%s', path, dump_environ(environ), exc_info=exc_info) else: msg = str(exc) msg = '' if not msg else ' - %s' % msg logger.warning('HTTP %s %s%s', response.status, path, msg) if has_empty_content(status, request.method) or status in REDIRECT_CODES: response.content_type = None response.content = None else: request.cache.pop('html_document', None) renderer = environ.get('error.handler', render_error) try: content = renderer(request, exc) except Exception: logger.critical('Error while rendering error', exc_info=True) response.content_type = 'text/plain' content = 'Critical server error' if content is not response: response.content = content return response
def handle_wsgi_error(environ, exc): '''The default error handler while serving a WSGI request. :param environ: The WSGI environment. :param exc: the exception :return: a :class:`.WsgiResponse` ''' if isinstance(exc, tuple): exc_info = exc exc = exc[1] else: exc_info = True request = wsgi_request(environ) request.cache.handle_wsgi_error = True response = request.response if isinstance(exc, HTTPError): response.status_code = exc.code or 500 else: response.status_code = getattr(exc, 'status', 500) response.headers.update(getattr(exc, 'headers', None) or ()) path = '@ %s "%s"' % (request.method, request.path) status = response.status_code if status == 500: logger.critical('Unhandled exception during HTTP response %s.%s', path, dump_environ(environ), exc_info=exc_info) else: msg = str(exc) msg = '' if not msg else ' - %s' % msg logger.warning('HTTP %s %s%s', response.status, path, msg) if has_empty_content(status, request.method) or status in REDIRECT_CODES: response.content_type = None response.content = None else: request.cache.pop('html_document', None) renderer = environ.get('error.handlers', {}).get(status, render_error) try: content = renderer(request, exc) except Exception: logger.critical('Error while rendering error', exc_info=True) response.content_type = 'text/plain' content = 'Critical server error' if content is not response: response.content = content return response
def get_headers(self): headers = self.headers if has_empty_content(self.status_code, self.method): headers.pop('content-type', None) headers.pop('content-length', None) self._content = () else: if not self.is_streamed: cl = 0 for c in self.content: cl += len(c) if cl == 0 and self.content_type in JSON_CONTENT_TYPES: self._content = (b'{}',) cl = len(self._content[0]) headers['Content-Length'] = str(cl) if not self.content_type: headers['Content-Type'] = 'text/plain' for c in self.cookies.values(): headers['Set-Cookie'] = c.OutputString() return list(headers)
def get_headers(self): headers = self.headers if has_empty_content(self.status_code, self.method): headers.pop('content-type', None) headers.pop('content-length', None) self._content = () else: if not self.is_streamed: cl = 0 for c in self.content: cl += len(c) if cl == 0 and self.content_type in JSON_CONTENT_TYPES: self._content = (b'{}', ) cl = len(self._content[0]) headers['Content-Length'] = str(cl) if not self.content_type and self.encoding: headers['Content-Type'] = ('text/plain; charset=%s' % self.encoding) for c in self.cookies.values(): headers['Set-Cookie'] = c.OutputString() return list(headers)