From 1cf43e501784731678d52655b2bb9fa67734cb12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Kr=C3=B6ger?= Date: Fri, 23 Aug 2019 23:48:16 +0200 Subject: [PATCH] Handle multiple Content-Type headers correctly (#31238) * Handle multiple Content-Type headers correctly Avoids situations where mulitple Content-Type headers including charset information can result in errors like ``` LookupError: unknown encoding: UTF-8, text/html ``` * Account for multiple conflicting values for content-type and charset * Add changelog fragment --- .../31238-uri-multi-content-type.yaml | 3 +++ lib/ansible/modules/net_tools/basics/uri.py | 27 ++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/31238-uri-multi-content-type.yaml diff --git a/changelogs/fragments/31238-uri-multi-content-type.yaml b/changelogs/fragments/31238-uri-multi-content-type.yaml new file mode 100644 index 00000000000..2aa6ff71001 --- /dev/null +++ b/changelogs/fragments/31238-uri-multi-content-type.yaml @@ -0,0 +1,3 @@ +bugfixes: +- uri - Handle multiple Content-Type headers correctly + (https://github.com/ansible/ansible/pull/31238) diff --git a/lib/ansible/modules/net_tools/basics/uri.py b/lib/ansible/modules/net_tools/basics/uri.py index eea77d8a858..7cf1e63341c 100644 --- a/lib/ansible/modules/net_tools/basics/uri.py +++ b/lib/ansible/modules/net_tools/basics/uri.py @@ -654,9 +654,30 @@ def main(): # Default content_encoding to try content_encoding = 'utf-8' if 'content_type' in uresp: - content_type, params = cgi.parse_header(uresp['content_type']) - if 'charset' in params: - content_encoding = params['charset'] + # Handle multiple Content-Type headers + charsets = [] + content_types = [] + for value in uresp['content_type'].split(','): + ct, params = cgi.parse_header(value) + if ct not in content_types: + content_types.append(ct) + if 'charset' in params: + if params['charset'] not in charsets: + charsets.append(params['charset']) + + if content_types: + content_type = content_types[0] + if len(content_types) > 1: + module.warn( + 'Received multiple conflicting Content-Type values (%s), using %s' % (', '.join(content_types), content_type) + ) + if charsets: + content_encoding = charsets[0] + if len(charsets) > 1: + module.warn( + 'Received multiple conflicting charset values (%s), using %s' % (', '.join(charsets), content_encoding) + ) + u_content = to_text(content, encoding=content_encoding) if any(candidate in content_type for candidate in JSON_CANDIDATES): try: