Пример #1
0
 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)
Пример #2
0
 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)
Пример #3
0
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
Пример #4
0
 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)
Пример #5
0
 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)
Пример #6
0
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
Пример #7
0
    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
Пример #8
0
 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)
Пример #9
0
    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
Пример #10
0
    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
Пример #11
0
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
Пример #12
0
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
Пример #13
0
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
Пример #14
0
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
Пример #15
0
 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)
Пример #16
0
 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)
Пример #17
0
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