Jinja: l'urlencode n'échappe pas aux barres obliques

Créé le 20 nov. 2015  ·  21Commentaires  ·  Source: pallets/jinja

Cela a été soulevé dans #444, mais ce code est toujours évalué à b'/' sur Python 3.4.1, donc les barres obliques ne sont toujours pas échappées.

Commentaire le plus utile

J'ai rencontré ce problème en essayant de créer un fichier dans un référentiel gitlab via des appels d'API. L'API gitlab nécessite que les barres obliques soient encodées. Pour que cela fonctionne, je fais : {{ myvar | urlencode | regex_replace('/','%2F') }}. Je travaille avec les filtres Ansible et Jinja2 dans mes tâches de playbook. Cela pourrait être une solution de contournement pour ceux d'entre vous qui y parviennent, car j'ai validé que cela fonctionne.

Tous les 21 commentaires

Juste un avertissement @mitsuhiko
Je ne sais pas pourquoi, mais do_urlencode n'échappe toujours pas aux barres obliques, alors que unicode_urlencode fonctionne comme prévu.

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'

Parce que le filtre urlencode n'échappe pas aux barres obliques. Y a-t-il une raison particulière pour laquelle il doit le faire ? Pour clarifier ceci : il code uniquement les barres obliques dans la position de valeur des paires clé/valeur passées.

Je pense qu'il s'agit d'un comportement standard pour la fonction destinée à l'encodage d'URL. Des outils comme http://meyerweb.com/eric/tools/dencoder/ se comportent de cette façon. De plus, j'ai au moins un outil au sein de notre entreprise qui s'attend à ce que les URL soient transmises dans les requêtes GET avec des barres obliques échappées.
De plus, je ne comprends pas pourquoi unicode_urlencode appelé à l' intérieur de do_urlencode avec for_qs=True .
Peut-être que je comprends quelque chose de mal.

Les barres obliques sont des caractères réservés dans le composant de chemin et le comportement le plus courant consiste à tout encoder, à l'exception des barres obliques lorsque l'on force les choses à adopter un comportement codé par URL. L'alternative (pour coder les barres obliques en %2f ) n'a même pas de sens car la plupart des serveurs rejettent carrément ces demandes en raison de problèmes de sécurité car les serveurs principaux ne peuvent généralement pas distinguer %2f et / dans le composant de chemin car ils fonctionnent sur des octets décodés.

Donc, la seule partie où un slash a un sens pour l'encodage est dans les chaînes de requête et c'est là que l'encodeur basé sur dict que urlencode a fonctionne comme ça. Cependant, même là, une barre oblique n'a pas besoin d'être codée, il n'y a donc aucune raison de forcer son codage.

La fonction urlencode devrait être utilisée par défaut pour la plupart des gens, c'est pourquoi elle n'encode pas de slash. Si vous avez des exigences personnalisées, vous pouvez remplacer la fonction dans votre enregistrement de filtre.

D'accord. Merci Armine.

Salut, j'ai eu le même problème avec le slash de rejet, voici le code :

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

Je veux rejeter le disque racine, mais cela ne fonctionne plus, comment le résoudre ?

>>> 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'

Travaille pour moi.

Cela ne fonctionnerait toujours pas pour moi, @ThiefMaster , le problème serait-il un python? quelle est la version de python que tu as utilisé.

    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'

Oh.. sameas utilise is (et vous ne pouvez pas vous attendre 'foo' is 'foo' ce que equalto qui utilise == .

Oui ça marche, je ne suis pas de la famille avec Jinja2. Merci, @ThiefMaster

Donc, la seule partie où un slash a un sens pour l'encodage est dans les chaînes de requête et c'est là que l'encodeur basé sur dict que urlencode a fonctionne comme ça. Cependant, même là, une barre oblique n'a pas besoin d'être codée, il n'y a donc aucune raison de forcer son codage.

Non, par exemple, vous devez également encoder / dans les noms d'utilisateur et les mots de passe.
C'est la raison pour laquelle JS a encodeURI __and__ encodeURIComponent .

C'est assez juste, mais dans la pratique, ce n'est pas non plus nécessaire et les informations d'identification incluses sont de toute façon obsolètes. Comme il est peu probable que ceux-ci soient produits dans des modèles, il s'agit d'un cas limite qui ne vaut pas vraiment la peine d'être considéré.

Ansible utilise Jinja et il est assez courant de gérer les informations d'identification de sécurité lors de la configuration des systèmes. Je viens de rencontrer un cas où un mot de passe généré automatiquement contenait une barre oblique qui n'a pas été remplacée par urlencode pour générer une URL de base de données, ce qui est assez regrettable. Alors que briser le comportement actuel serait problématique, pourquoi ne pas introduire un deuxième filtre qui échappe aux barres obliques ?

Ansible pourrait le faire. Il n'est pas nécessaire qu'un tel changement soit dans Jinja lui-même - il est suffisamment extensible pour ajouter des filtres personnalisés ou même remplacer ceux intégrés.

@ThiefMaster Les cas d'utilisation autres que la construction de modèles HTML ne sont-ils pas pertinents pour déterminer ce qui est utile à inclure dans Jinja lui-même ? Par exemple, le projet Saltstack, avec un objectif similaire à celui d'Ansible, utilise également Jinja pour la création de modèles et bénéficierait du même changement.

@danielkza qu'est-ce qui empêche saltstack de fournir un filtre qui fait cela?

@mitsuhiko Pourquoi Jinja inclut-il alors des filtres intégrés ? Je ne peux que supposer que c'est parce qu'ils sont utiles dans plusieurs cas d'utilisation. J'ai utilisé Ansible et Salt comme deux exemples d'endroits où l'on souhaite pouvoir échapper aux barres obliques dans les URL, et par conséquent, il serait utile de le rendre disponible pour tout le monde.

Qu'en est-il de l'ajout d'un argument safe à urlencode , comme l'a fait urllib.url_quote de Python, afin que les barres obliques soient préservées par défaut, mais d'une manière qui puisse être facilement remplacée ?

Jinja tente de fournir certaines fonctionnalités couramment utilisées. Nous avons deux modes pour le codage d'urlen, ce qui vous permet d'y accéder à environ 95%. Vous pouvez encoder des chaînes de requêtes entières en encodant un dict et vous pouvez encoder dans un ensemble commun qui est valide pour les chemins via urlencode sur les chaînes.

Nous ne faisons rien d'autre que l'utf-8 ou ça. Car où cela s'arrêterait-il. Il y a trop de parties d'une URL, il y a des iris et elles ont toutes leurs propres défauts. Quand nous y sommes, pourquoi ne pas simplement fournir également un encodeur punycode pour le netloc ?

J'ai rencontré ce problème en essayant de créer un fichier dans un référentiel gitlab via des appels d'API. L'API gitlab nécessite que les barres obliques soient encodées. Pour que cela fonctionne, je fais : {{ myvar | urlencode | regex_replace('/','%2F') }}. Je travaille avec les filtres Ansible et Jinja2 dans mes tâches de playbook. Cela pourrait être une solution de contournement pour ceux d'entre vous qui y parviennent, car j'ai validé que cela fonctionne.

Je vois un débat sur les caractères qui doivent être codés en pourcentage, à ma connaissance, cela est actuellement couvert par la RFC3986. https://tools.ietf.org/html/rfc3986#section -2.2

Bien que pour mon cas d'utilisation, @ahuffman a fourni une

Je veux fermer ceci parce qu'il est revenu à nouveau. Mes arguments contre l'existence de cela figuraient déjà ici plus tôt, mais je tiens à les réitérer car il existe actuellement un PR ouvert (#864) qui propose d'ajouter un autre filtre pour aider l'API de GitLab.

L'API de GitLab est cassée si elle est placée derrière toutes sortes de configurations de proxy et qu'il y a des problèmes ouverts pour cela ( Exemple de problème ). Je proposerais plutôt de documenter une solution de contournement et pourquoi les gens ne devraient pas le faire.

Voici un exemple de solution de contournement :

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

C'est un peu prendre position, mais cela peut encourager les gens à ne pas répéter les erreurs des autres qui les ont précédés.

Cette page vous a été utile?
0 / 5 - 0 notes