diff --git a/changelogs/fragments/29680-fetch-file-file-name-too-long.yml b/changelogs/fragments/29680-fetch-file-file-name-too-long.yml new file mode 100644 index 00000000000..9d7505d4c1b --- /dev/null +++ b/changelogs/fragments/29680-fetch-file-file-name-too-long.yml @@ -0,0 +1,3 @@ +bugfixes: +- fetch_file - Ensure we only use the filename when calculating a tempfile, and do not incude the query string + (https://github.com/ansible/ansible/issues/29680) diff --git a/lib/ansible/module_utils/urls.py b/lib/ansible/module_utils/urls.py index 3e0965af6d4..691ecc3879f 100644 --- a/lib/ansible/module_utils/urls.py +++ b/lib/ansible/module_utils/urls.py @@ -1989,7 +1989,8 @@ def fetch_file(module, url, data=None, headers=None, method=None, ''' # download file bufsize = 65536 - file_name, file_ext = os.path.splitext(str(url.rsplit('/', 1)[1])) + parts = urlparse(url) + file_name, file_ext = os.path.splitext(os.path.basename(parts.path)) fetch_temp_file = tempfile.NamedTemporaryFile(dir=module.tmpdir, prefix=file_name, suffix=file_ext, delete=False) module.add_cleanup_file(fetch_temp_file.name) try: diff --git a/test/units/module_utils/urls/test_fetch_file.py b/test/units/module_utils/urls/test_fetch_file.py new file mode 100644 index 00000000000..d536ffaf3a5 --- /dev/null +++ b/test/units/module_utils/urls/test_fetch_file.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# (c) 2018 Matt Martz +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +from ansible.module_utils.urls import fetch_file + +import pytest +from units.compat.mock import MagicMock + + +def test_fetch_file(mocker): + tempfile = mocker.patch('ansible.module_utils.urls.tempfile') + tempfile.NamedTemporaryFile.side_effect = RuntimeError('boom') + + module = MagicMock() + module.tmpdir = '/tmp' + + with pytest.raises(RuntimeError): + fetch_file(module, 'http://ansible.com/foo.tar.gz?foo=%s' % ('bar' * 100)) + + tempfile.NamedTemporaryFile.assert_called_once_with(dir='/tmp', prefix='foo.tar', suffix='.gz', delete=False)