diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index ecb38a3dd6f..a14a02ebb9b 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -971,11 +971,6 @@ class Binary(http.Controller): addons_path = http.addons_manifest['web']['addons_path'] return open(os.path.join(addons_path, 'web', 'static', 'src', 'img', image), 'rb').read() - def force_contenttype(self, headers, contenttype='image/png'): - dictheaders = dict(headers) - dictheaders['Content-Type'] = contenttype - return list(dictheaders.items()) - @http.route(['/web/content', '/web/content/', '/web/content//', @@ -1034,14 +1029,13 @@ class Binary(http.Controller): return request.env['ir.http']._response_by_status(status, headers, image_base64) if not image_base64: image_base64 = base64.b64encode(self.placeholder(image=placeholder)) - headers = self.force_contenttype(headers, contenttype='image/png') if not (width or height): width, height = odoo.tools.image_guess_size_from_field_name(field) image_base64 = image_process(image_base64, (width, height), crop=crop) content = base64.b64decode(image_base64) - headers.append(('Content-Length', len(content))) + headers = http.set_safe_image_headers(headers, content) response = request.make_response(content, headers) response.status_code = status return response diff --git a/addons/website_profile/controllers/main.py b/addons/website_profile/controllers/main.py index 3b5bc7843bc..5d379643e5d 100644 --- a/addons/website_profile/controllers/main.py +++ b/addons/website_profile/controllers/main.py @@ -98,7 +98,7 @@ class WebsiteProfile(http.Controller): image_base64 = tools.image_process(image_base64, (width, height), crop=crop) content = base64.b64decode(image_base64) - headers.append(('Content-Length', len(content))) + headers = http.set_safe_image_headers(headers, content) response = request.make_response(content, headers) response.status_code = status return response diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py index 754edf27960..4da2d91f6a7 100644 --- a/addons/website_slides/controllers/main.py +++ b/addons/website_slides/controllers/main.py @@ -531,7 +531,7 @@ class WebsiteSlides(WebsiteProfile): image_base64 = tools.image_process(image_base64, (width, height), crop=crop) content = base64.b64decode(image_base64) - headers.append(('Content-Length', len(content))) + headers = http.set_safe_image_headers(headers, content) response = request.make_response(content, headers) response.status_code = status return response diff --git a/odoo/http.py b/odoo/http.py index ddb18eb1048..750c0b3c0d5 100644 --- a/odoo/http.py +++ b/odoo/http.py @@ -50,6 +50,7 @@ from .service.server import memory_info from .service import security, model as service_model from .tools.func import lazy_property from .tools import ustr, consteq, frozendict, pycompat, unique, date_utils +from .tools.mimetypes import guess_mimetype from .modules.module import module_manifest @@ -1617,5 +1618,39 @@ def content_disposition(filename): return "attachment; filename*=UTF-8''%s" % escaped + +def set_safe_image_headers(headers, content): + """Return new headers based on `headers` but with `Content-Length` and + `Content-Type` set appropriately depending on the given `content` only if it + is safe to do.""" + content_type = guess_mimetype(content) + safe_types = ['image/jpeg', 'image/png', 'image/gif', 'image/x-icon'] + if content_type in safe_types: + headers = set_header_field(headers, 'Content-Type', content_type) + set_header_field(headers, 'Content-Length', len(content)) + return headers + + +def set_header_field(headers, name, value): + """ Return new headers based on `headers` but with `value` set for the + header field `name`. + + :param headers: the existing headers + :type headers: list of tuples (name, value) + + :param name: the header field name + :type name: string + + :param value: the value to set for the `name` header + :type value: string + + :return: the updated headers + :rtype: list of tuples (name, value) + """ + dictheaders = dict(headers) + dictheaders[name] = value + return list(dictheaders.items()) + + # main wsgi handler root = Root()