Example #1
0
    def best_match_language(accept_language):
        """Determines best available locale from the Accept-Language header.

        :returns: the best language match or None if the 'Accept-Language'
                  header was not available in the request.
        """
        if not accept_language:
            return None
        all_languages = gettextutils.get_available_languages('ceilometer')
        return accept_language.best_match(all_languages)
Example #2
0
    def best_match_language(accept_language):
        """Determines best available locale from the Accept-Language header.

        :returns: the best language match or None if the 'Accept-Language'
                  header was not available in the request.
        """
        if not accept_language:
            return None
        all_languages = gettextutils.get_available_languages('ceilometer')
        return accept_language.best_match(all_languages)
Example #3
0
    def __call__(self, environ, start_response):
        # Request for this state, modified by replace_start_response()
        # and used when an error is being reported.
        state = {}

        def replacement_start_response(status, headers, exc_info=None):
            """Overrides the default response to make errors parsable.
            """
            try:
                status_code = int(status.split(" ")[0])
                state["status_code"] = status_code
            except (ValueError, TypeError):  # pragma: nocover
                raise Exception(("ErrorDocumentMiddleware received an invalid " "status %s" % status))
            else:
                if (state["status_code"] / 100) not in (2, 3):
                    # Remove some headers so we can replace them later
                    # when we have the full error message and can
                    # compute the length.
                    headers = [(h, v) for (h, v) in headers if h not in ("Content-Length", "Content-Type")]
                # Save the headers in case we need to modify them.
                state["headers"] = headers
                return start_response(status, headers, exc_info)

        app_iter = self.app(environ, replacement_start_response)
        if (state["status_code"] / 100) not in (2, 3):
            req = webob.Request(environ)
            # Find the first TranslationHook in the array of hooks and use the
            # translatable_error object from it
            error = None
            for hook in self.app.hooks:
                if isinstance(hook, hooks.TranslationHook):
                    error = hook.local_error.translatable_error
                    break
            user_locale = req.accept_language.best_match(
                gettextutils.get_available_languages("ceilometer"), default_match="en_US"
            )

            if req.accept.best_match(["application/json", "application/xml"]) == "application/xml":
                try:
                    # simple check xml is valid
                    fault = et.ElementTree.fromstring("\n".join(app_iter))
                    # Add the translated error to the xml data
                    if error is not None:
                        for fault_string in fault.findall("faultstring"):
                            fault_string.text = gettextutils.get_localized_message(error, user_locale)
                    body = [
                        et.ElementTree.tostring(
                            et.ElementTree.fromstring(
                                "<error_message>" + et.ElementTree.tostring(fault) + "</error_message>"
                            )
                        )
                    ]
                except ParseError as err:
                    LOG.error("Error parsing HTTP response: %s" % err)
                    body = ["<error_message>%s" % state["status_code"] + "</error_message>"]
                state["headers"].append(("Content-Type", "application/xml"))
            else:
                try:
                    fault = json.loads("\n".join(app_iter))
                    if error is not None and "faultstring" in fault:
                        fault["faultstring"] = gettextutils.get_localized_message(error, user_locale)
                    body = [json.dumps({"error_message": json.dumps(fault)})]
                except ValueError as err:
                    body = [json.dumps({"error_message": "\n".join(app_iter)})]
                state["headers"].append(("Content-Type", "application/json"))
            state["headers"].append(("Content-Length", len(body[0])))
        else:
            body = app_iter
        return body
Example #4
0
    def __call__(self, environ, start_response):
        # Request for this state, modified by replace_start_response()
        # and used when an error is being reported.
        state = {}

        def replacement_start_response(status, headers, exc_info=None):
            """Overrides the default response to make errors parsable.
            """
            try:
                status_code = int(status.split(' ')[0])
                state['status_code'] = status_code
            except (ValueError, TypeError):  # pragma: nocover
                raise Exception((
                    'ErrorDocumentMiddleware received an invalid '
                    'status %s' % status
                ))
            else:
                if (state['status_code'] / 100) not in (2, 3):
                    # Remove some headers so we can replace them later
                    # when we have the full error message and can
                    # compute the length.
                    headers = [(h, v)
                               for (h, v) in headers
                               if h not in ('Content-Length', 'Content-Type')
                               ]
                # Save the headers in case we need to modify them.
                state['headers'] = headers
                return start_response(status, headers, exc_info)

        app_iter = self.app(environ, replacement_start_response)
        if (state['status_code'] / 100) not in (2, 3):
            req = webob.Request(environ)
            # Find the first TranslationHook in the array of hooks and use the
            # translatable_error object from it
            error = None
            for hook in self.app.hooks:
                if isinstance(hook, hooks.TranslationHook):
                    error = hook.local_error.translatable_error
                    break
            user_locale = req.accept_language.best_match(
                gettextutils.get_available_languages('ceilometer'),
                default_match='en_US')

            if (req.accept.best_match(['application/json', 'application/xml'])
               == 'application/xml'):
                try:
                    # simple check xml is valid
                    fault = et.ElementTree.fromstring('\n'.join(app_iter))
                    # Add the translated error to the xml data
                    if error is not None:
                        for fault_string in fault.findall('faultstring'):
                            fault_string.text = (
                                gettextutils.get_localized_message(
                                    error, user_locale))
                    body = [et.ElementTree.tostring(
                            et.ElementTree.fromstring(
                                '<error_message>'
                                + et.ElementTree.tostring(fault)
                                + '</error_message>'))]
                except ParseError as err:
                    LOG.error('Error parsing HTTP response: %s' % err)
                    body = ['<error_message>%s' % state['status_code']
                            + '</error_message>']
                state['headers'].append(('Content-Type', 'application/xml'))
            else:
                try:
                    fault = json.loads('\n'.join(app_iter))
                    if error is not None and 'faultstring' in fault:
                        fault['faultstring'] = (
                            gettextutils.get_localized_message(
                                error, user_locale))
                    body = [json.dumps({'error_message': json.dumps(fault)})]
                except ValueError as err:
                    body = [json.dumps({'error_message': '\n'.join(app_iter)})]
                state['headers'].append(('Content-Type', 'application/json'))
            state['headers'].append(('Content-Length', len(body[0])))
        else:
            body = app_iter
        return body