Fixed #32397 -- Made startapp/startproject management commands set User-Agent.
This sets User-Agent to 'Django/<version>'.
This commit is contained in:
parent
e361621dbc
commit
9a6e2df3a8
|
@ -7,7 +7,7 @@ import shutil
|
||||||
import stat
|
import stat
|
||||||
import tempfile
|
import tempfile
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from urllib.request import urlretrieve
|
from urllib.request import build_opener
|
||||||
|
|
||||||
import django
|
import django
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -277,8 +277,14 @@ class TemplateCommand(BaseCommand):
|
||||||
|
|
||||||
if self.verbosity >= 2:
|
if self.verbosity >= 2:
|
||||||
self.stdout.write('Downloading %s' % display_url)
|
self.stdout.write('Downloading %s' % display_url)
|
||||||
|
|
||||||
|
the_path = os.path.join(tempdir, filename)
|
||||||
|
opener = build_opener()
|
||||||
|
opener.addheaders = [('User-Agent', f'Django/{django.__version__}')]
|
||||||
try:
|
try:
|
||||||
the_path, info = urlretrieve(url, os.path.join(tempdir, filename))
|
with opener.open(url) as source, open(the_path, 'wb') as target:
|
||||||
|
headers = source.info()
|
||||||
|
target.write(source.read())
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
raise CommandError("couldn't download URL %s to %s: %s" %
|
raise CommandError("couldn't download URL %s to %s: %s" %
|
||||||
(url, filename, e))
|
(url, filename, e))
|
||||||
|
@ -286,7 +292,7 @@ class TemplateCommand(BaseCommand):
|
||||||
used_name = the_path.split('/')[-1]
|
used_name = the_path.split('/')[-1]
|
||||||
|
|
||||||
# Trying to get better name from response headers
|
# Trying to get better name from response headers
|
||||||
content_disposition = info.get('content-disposition')
|
content_disposition = headers['content-disposition']
|
||||||
if content_disposition:
|
if content_disposition:
|
||||||
_, params = cgi.parse_header(content_disposition)
|
_, params = cgi.parse_header(content_disposition)
|
||||||
guessed_filename = params.get('filename') or used_name
|
guessed_filename = params.get('filename') or used_name
|
||||||
|
@ -295,7 +301,7 @@ class TemplateCommand(BaseCommand):
|
||||||
|
|
||||||
# Falling back to content type guessing
|
# Falling back to content type guessing
|
||||||
ext = self.splitext(guessed_filename)[1]
|
ext = self.splitext(guessed_filename)[1]
|
||||||
content_type = info.get('content-type')
|
content_type = headers['content-type']
|
||||||
if not ext and content_type:
|
if not ext and content_type:
|
||||||
ext = mimetypes.guess_extension(content_type)
|
ext = mimetypes.guess_extension(content_type)
|
||||||
if ext:
|
if ext:
|
||||||
|
|
|
@ -33,7 +33,11 @@ from django.test import (
|
||||||
LiveServerTestCase, SimpleTestCase, TestCase, override_settings,
|
LiveServerTestCase, SimpleTestCase, TestCase, override_settings,
|
||||||
)
|
)
|
||||||
from django.test.utils import captured_stderr, captured_stdout
|
from django.test.utils import captured_stderr, captured_stdout
|
||||||
|
from django.urls import path
|
||||||
from django.utils.version import PY39
|
from django.utils.version import PY39
|
||||||
|
from django.views.static import serve
|
||||||
|
|
||||||
|
from . import urls
|
||||||
|
|
||||||
custom_templates_dir = os.path.join(os.path.dirname(__file__), 'custom_templates')
|
custom_templates_dir = os.path.join(os.path.dirname(__file__), 'custom_templates')
|
||||||
|
|
||||||
|
@ -2127,6 +2131,33 @@ class StartProject(LiveServerTestCase, AdminScriptTestCase):
|
||||||
self.assertTrue(os.path.isdir(testproject_dir))
|
self.assertTrue(os.path.isdir(testproject_dir))
|
||||||
self.assertTrue(os.path.exists(os.path.join(testproject_dir, 'run.py')))
|
self.assertTrue(os.path.exists(os.path.join(testproject_dir, 'run.py')))
|
||||||
|
|
||||||
|
def test_custom_project_template_from_tarball_by_url_django_user_agent(self):
|
||||||
|
user_agent = None
|
||||||
|
|
||||||
|
def serve_template(request, *args, **kwargs):
|
||||||
|
nonlocal user_agent
|
||||||
|
user_agent = request.headers['User-Agent']
|
||||||
|
return serve(request, *args, **kwargs)
|
||||||
|
|
||||||
|
old_urlpatterns = urls.urlpatterns[:]
|
||||||
|
try:
|
||||||
|
urls.urlpatterns += [
|
||||||
|
path(
|
||||||
|
'user_agent_check/<path:path>',
|
||||||
|
serve_template,
|
||||||
|
{'document_root': os.path.join(urls.here, 'custom_templates')},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
template_url = f'{self.live_server_url}/user_agent_check/project_template.tgz'
|
||||||
|
args = ['startproject', '--template', template_url, 'urltestproject']
|
||||||
|
_, err = self.run_django_admin(args)
|
||||||
|
|
||||||
|
self.assertNoOutput(err)
|
||||||
|
self.assertIn('Django/%s' % get_version(), user_agent)
|
||||||
|
finally:
|
||||||
|
urls.urlpatterns = old_urlpatterns
|
||||||
|
|
||||||
def test_project_template_tarball_url(self):
|
def test_project_template_tarball_url(self):
|
||||||
"Startproject management command handles project template tar/zip balls from non-canonical urls"
|
"Startproject management command handles project template tar/zip balls from non-canonical urls"
|
||||||
template_url = '%s/custom_templates/project_template.tgz/' % self.live_server_url
|
template_url = '%s/custom_templates/project_template.tgz/' % self.live_server_url
|
||||||
|
|
Loading…
Reference in New Issue