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)
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
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