Jinja: urlencode не избегает косой черты

Созданный на 20 нояб. 2015  ·  21Комментарии  ·  Источник: pallets/jinja

Это было поднято в # 444, но этот код всегда оценивается как b'/' на Python 3.4.1, поэтому косые черты все еще не экранированы.

Самый полезный комментарий

Я столкнулся с этой проблемой при попытке создать файл в репозитории gitlab с помощью вызовов API. API gitlab требует, чтобы косые черты были закодированы. Чтобы выполнить эту работу, я делаю: {{myvar | urlencode | regex_replace ('/', '% 2F')}}. Я работаю с фильтрами Ansible и Jinja2 в своих задачах playbook. Это может быть обходным путем для тех из вас, кто сталкивается с этим, поскольку я подтвердил, что это работает.

Все 21 Комментарий

Просто предупреждаю @mituhiko
Понятия не имею, почему, но do_urlencode прежнему не избегает косой черты, а unicode_urlencode работает должным образом.

Python 3.4.3 (default, Oct 14 2015, 20:28:29)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import jinja2
>>> jinja2.utils.unicode_urlencode("http://url.by", for_qs=True)
'http%3A%2F%2Furl.by'
>>> jinja2.filters.do_urlencode("http://url.by")
'http%3A//url.by'
>>> jinja2.__version__
'2.9.dev'

Поскольку фильтр urlencode не избегает косой черты. Есть ли конкретная причина, по которой это нужно? Чтобы прояснить это: он кодирует косую черту только в позиции значения переданных пар ключ / значение.

Я считаю, что это стандартное поведение функции, предназначенной для кодирования URL-адресов. Такие инструменты, как http://meyerweb.com/eric/tools/dencoder/, ведут себя подобным образом. Кроме того, у меня есть по крайней мере один инструмент внутри нашей компании, который ожидает, что URL-адреса будут передаваться внутри запросов GET с экранированными косыми чертами.
Кроме того, я не понимаю, почему unicode_urlencode вызывается внутри do_urlencode с for_qs=True .
Может я что-то не так понимаю.

Косые черты - это зарезервированные символы в компоненте пути, и более распространенным поведением является кодирование всего, кроме косых черт, при принудительном использовании поведения в кодировке URL. Альтернатива (кодировать косую черту в %2f ) даже не имеет смысла, поскольку большинство серверов полностью отклоняют эти запросы из-за проблем с безопасностью, поскольку внутренние серверы обычно не могут различать %2f и / в компонент пути, поскольку они работают с декодированными октетами.

Таким образом, единственная часть, где косая черта действительно имеет смысл кодировать, - это строки запроса, и именно здесь кодировщик на основе dict, который имеет urlencode , работает таким образом. Однако даже там косую черту не нужно кодировать, поэтому нет причин заставлять ее кодировать.

Функция urlencode должна использоваться большинством людей по умолчанию, поэтому она не кодирует косую черту. Если у вас есть индивидуальные требования, вы можете переопределить эту функцию в своей регистрации фильтра.

Ok. Спасибо, Армин.

Привет, у меня такая же проблема с отклонением косой черты, вот код:

jinja2.Template ("{{диски | reject ('sameas', '/') | list}}"). render (disks = ["/", "/ mnt / disk0", "/ mnt / disk1"])
u "['/', '/ mnt / disk0', '/ mnt / disk1']»

Я хочу отклонить корневой диск, но он больше не работает, как это решить?

>>> import jinja2
>>> jinja2.Template("{{ disks|reject('sameas', '/')|list }}").render(disks=["/", "/mnt/disk0", "/mnt/disk1"])
u"['/mnt/disk0', '/mnt/disk1']"
>>> jinja2.__version__
Out[3]: '2.8'

Работает для меня.

Все еще не работает для меня, @ThiefMaster , проблема с питоном? какую версию Python вы использовали.

    Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import jinja2
    >>> jinja2.Template("{{ disks|reject('sameas', '/')|list }}").render(disks=["/", "/mnt/disk0", "/mnt/disk1"])
    u"['/', '/mnt/disk0', '/mnt/disk1']"
    >>> jinja2.__version__
    '2.8'

Ох .. sameas использует is (и вы не можете ожидать, что 'foo' is 'foo' сработает). Вам нужен equalto который использует == .

Да, это работает, я не семья с Jinja2. Спасибо, @ThiefMaster

Таким образом, единственная часть, где косая черта действительно имеет смысл кодирования, - это строки запроса, и именно здесь кодировщик на основе dict, который имеет urlencode, работает так. Однако даже там косую черту не нужно кодировать, поэтому нет причин заставлять ее кодировать.

Нет, например, вам нужно также закодировать / в именах пользователей и паролях.
Это причина, по которой JS имеет encodeURI __and__ encodeURIComponent .

Это справедливо, но на практике в этом нет необходимости, и включенные учетные данные в любом случае устарели. Поскольку они вряд ли будут созданы в шаблонах, это крайний случай, который на самом деле не стоит рассматривать.

Ansible использует Jinja, и довольно часто при настройке систем обрабатываются учетные данные безопасности. Я только что нашел случай, когда автоматически сгенерированный пароль содержал косую черту, которая не была заменена на urlencode для генерации URL-адреса базы данных, что довольно прискорбно. Хотя нарушение текущего поведения было бы проблематичным, почему бы не ввести второй фильтр, который избегает косой черты?

Ansible мог это сделать. Нет необходимости в таком изменении в самом Jinja - он достаточно расширяемый, чтобы добавлять собственные фильтры или даже заменять встроенные.

@ThiefMaster Неужели

@danielkza, что мешает saltstack предоставить такой фильтр?

@mituhiko Почему тогда Jinja включает в себя какие-либо встроенные фильтры? Я могу только догадываться, потому что они полезны во многих случаях использования. Я использовал Ansible и Salt как два примера того, где желательна возможность избегать косой черты в URL-адресах, и, следовательно, было бы полезно, чтобы она была доступна для всех.

Как насчет добавления аргумента safe к urlencode , как в Python urllib.url_quote , чтобы по умолчанию косые черты сохранялись, но таким образом, чтобы их можно было легко переопределить?

Jinja пытается предоставить некоторые часто используемые функции. У нас есть два режима кодирования urlencoding, что дает вам около 95% результатов. Вы можете кодировать целые строки запроса, кодируя dict, и вы можете кодировать в общий набор, который действителен для путей через urlencode в строках.

Мы не делаем ничего, кроме UTF-8 или чего-то подобного. Потому что где бы это остановиться? В URL-адресе слишком много частей, есть радужная оболочка, и все они имеют свои изгибы. Когда мы там, почему бы просто не предоставить кодировщик punycode для netloc?

Я столкнулся с этой проблемой при попытке создать файл в репозитории gitlab с помощью вызовов API. API gitlab требует, чтобы косые черты были закодированы. Чтобы выполнить эту работу, я делаю: {{myvar | urlencode | regex_replace ('/', '% 2F')}}. Я работаю с фильтрами Ansible и Jinja2 в своих задачах playbook. Это может быть обходным путем для тех из вас, кто сталкивается с этим, поскольку я подтвердил, что это работает.

Я вижу некоторые споры о том, какие символы следует кодировать в процентах, насколько я понимаю, в настоящее время это рассматривается в RFC3986. https://tools.ietf.org/html/rfc3986#section -2.2

Хотя для моего случая использования @ahuffman предоставил разумное

Я хочу закрыть это, потому что оно появилось снова. Мои аргументы против этого уже были здесь ранее, но я хочу повторить их, потому что на самом деле в настоящее время открыт PR (# 864), который предлагает добавить еще один фильтр, чтобы помочь GitLab API.

API GitLab не работает, если размещен за всеми видами настроек прокси, и для него открыты проблемы ( пример проблемы). Вместо этого я бы предложил задокументировать обходной путь и почему люди не должны этого делать.

Пример обходного пути может быть таким:

{{ value|urlencode|replace("/", "%2f") }}

Это немного занимает позицию, но это может побудить людей не повторять ошибок других, которые были до них.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги