diff --git a/odoo/addons/base/models/ir_http.py b/odoo/addons/base/models/ir_http.py index b374240f57b..4f91d14178c 100644 --- a/odoo/addons/base/models/ir_http.py +++ b/odoo/addons/base/models/ir_http.py @@ -22,7 +22,7 @@ from odoo.exceptions import AccessDenied, AccessError, MissingError from odoo.http import request, content_disposition, Response, ROUTING_KEYS from odoo.service import security from odoo.tools import consteq, submap -from odoo.tools.mimetypes import guess_mimetype +from odoo.tools.mimetypes import get_extension, guess_mimetype from odoo.modules.module import get_resource_path, get_module_path _logger = logging.getLogger(__name__) @@ -354,7 +354,7 @@ class IrHttp(models.AbstractModel): mimetype = guess_mimetype(content, default=default_mimetype) # extension - has_extension = bool(mimetypes.guess_type(filename)[0]) + has_extension = get_extension(filename) or mimetypes.guess_type(filename)[0] if not has_extension: extension = mimetypes.guess_extension(mimetype) if extension: diff --git a/odoo/addons/base/tests/test_mimetypes.py b/odoo/addons/base/tests/test_mimetypes.py index 8de2f43d713..774c5ac1b89 100644 --- a/odoo/addons/base/tests/test_mimetypes.py +++ b/odoo/addons/base/tests/test_mimetypes.py @@ -2,7 +2,7 @@ import base64 import unittest from odoo.tests.common import BaseCase -from odoo.tools.mimetypes import guess_mimetype +from odoo.tools.mimetypes import get_extension, guess_mimetype PNG = b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAAAElFTkSuQmCC' GIF = b"R0lGODdhAQABAIAAAP///////ywAAAAAAQABAAACAkQBADs=" @@ -75,6 +75,20 @@ class test_guess_mimetype(BaseCase): self.assertEqual(mimetype, 'application/zip') + def test_mimetype_get_extension(self): + self.assertEqual(get_extension('filename.Abc'), '.abc') + self.assertEqual(get_extension('filename.scss'), '.scss') + self.assertEqual(get_extension('filename.torrent'), '.torrent') + self.assertEqual(get_extension('.htaccess'), '.htaccess') + # enough to suppose that extension is present and don't suffix the filename + self.assertEqual(get_extension('filename.tar.gz'), '.gz') + self.assertEqual(get_extension('filename'), '') + self.assertEqual(get_extension('filename.'), '') + self.assertEqual(get_extension('filename.not_alnum'), '') + self.assertEqual(get_extension('filename.with space'), '') + self.assertEqual(get_extension('filename.notAnExtension'), '') + + if __name__ == '__main__': unittest.main() diff --git a/odoo/tools/mimetypes.py b/odoo/tools/mimetypes.py index 14a0099bd98..b89434117ce 100644 --- a/odoo/tools/mimetypes.py +++ b/odoo/tools/mimetypes.py @@ -195,3 +195,13 @@ def neuter_mimetype(mimetype, user): if wrong_type and not user._is_system(): return 'text/plain' return mimetype + +def get_extension(filename): + """ Return the extension the current filename based on the heuristic that + ext is less than or equal to 10 chars and is alphanumeric. + + :param str filename: filename to try and guess a extension for + :returns: detected extension or `` + """ + ext = '.' in filename and filename.split('.')[-1] + return ext and len(ext) <= 10 and ext.isalnum() and '.' + ext.lower() or ''