Isso foi gerado em # 444, mas esse código sempre avalia como b'/'
no Python 3.4.1, portanto, as barras ainda não escaparam.
Apenas um aviso @mitsuhiko
Não tenho ideia do porquê, mas do_urlencode
ainda não escapa das barras, enquanto unicode_urlencode
funciona como esperado.
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'
Porque o filtro urlencode
não escapa das barras. Existe uma razão específica para isso? Para esclarecer isso: ele apenas codifica barras na posição do valor dos pares chave / valor passados.
Acredito que esse seja o comportamento padrão para funções destinadas à codificação de urls. Ferramentas como http://meyerweb.com/eric/tools/dencoder/ se comportam dessa maneira. Além disso, tenho pelo menos uma ferramenta dentro de nossa empresa que espera URLs sendo passados dentro de solicitações GET com barras de escape.
Além disso, não entendo por que unicode_urlencode
chamou dentro de do_urlencode
com for_qs=True
.
Pode ser que eu entenda algo errado.
As barras são caracteres reservados no componente de caminho e o comportamento mais comum é codificar tudo, exceto as barras, ao forçar as coisas para o comportamento de codificação de URL. A alternativa (codificar barras para %2f
) nem mesmo faz sentido, já que a maioria dos servidores rejeita completamente essas solicitações devido a problemas de segurança, pois os servidores de back-end normalmente não conseguem distinguir %2f
e /
em o componente de caminho à medida que operam em octetos decodificados.
Portanto, a única parte em que uma barra realmente faz sentido na codificação é em strings de consulta e é aqui que o codificador baseado em dict que urlencode
tem funciona assim. No entanto, mesmo lá, uma barra não precisa ser codificada, portanto, não há razão para forçá-la a ser codificada.
A função urlencode
deve ser usada pela maioria das pessoas por padrão, por isso ela não codifica uma barra. Se você tiver requisitos personalizados, poderá substituir a função no registro do filtro.
OK. Obrigado Armin.
Olá, tenho o mesmo problema com a rejeição de barra. Aqui está o código:
jinja2.Template ("{{discos | rejeitar ('sameas', '/') | lista}}"). render (disks = ["/", "/ mnt / disk0", "/ mnt / disk1"])
u "['/', '/ mnt / disk0', '/ mnt / disk1']"
Eu quero rejeitar o disco raiz, mas não funciona mais, como resolver isso?
>>> 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'
Funciona para mim.
Ainda não funciona para mim, @ThiefMaster .
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
usa is
(e você não pode esperar que 'foo' is 'foo'
funcione). Você quer equalto
que usa ==
.
Sim, funciona, não sou da família com Jinja2. Obrigado, @ThiefMaster
Portanto, a única parte em que uma barra realmente faz sentido na codificação é nas strings de consulta e é aqui que o codificador baseado em dict que o urlencode tem funciona assim. No entanto, mesmo lá, uma barra não precisa ser codificada, portanto, não há razão para forçá-la a ser codificada.
Não, por exemplo, você precisa codificar /
em nomes de usuário e senhas também.
É a razão pela qual JS tem encodeURI __and__ encodeURIComponent .
Isso é justo, mas na prática também não é necessário e as credenciais incluídas estão obsoletas de qualquer maneira. Como é improvável que sejam produzidos dentro de modelos, é um caso extremo que realmente não vale a pena considerar.
Ansible usa Jinja, e é muito comum lidar com credenciais de segurança ao configurar sistemas. Acabei de chegar a um caso em que uma senha gerada automaticamente continha uma barra que não foi substituída por urlencode
para gerar uma URL de banco de dados, o que é bastante lamentável. Embora quebrar o comportamento atual seja problemático, por que não introduzir um segundo filtro que escape das barras?
Ansible poderia fazer isso. Não há necessidade de tal mudança estar no próprio Jinja - é extensível o suficiente para adicionar filtros personalizados ou até mesmo substituir os embutidos.
@ThiefMaster Os casos de uso, além da construção de modelos HTML, são irrelevantes para determinar o que é útil incluir no próprio Jinja? Por exemplo, o projeto Saltstack, com finalidade semelhante ao Ansible, também usa Jinja para modelagem e se beneficiaria da mesma mudança.
@danielkza, o que impede que o saltstack forneça um filtro que faça isso?
@mitsuhiko Por que Jinja inclui algum filtro embutido então? Só posso supor que é porque eles são úteis em vários casos de uso. Usei Ansible e Salt como dois exemplos de onde é desejável poder escapar de barras em URLs e, portanto, seria valioso tê-lo disponível para todos.
Que tal adicionar um argumento safe
a urlencode
, como fez o urllib.url_quote
do Python, de forma que por padrão as barras sejam preservadas, mas de uma forma que possa ser facilmente substituída?
Jinja tenta fornecer alguma funcionalidade comumente usada. Temos dois modos de urlencoding, o que leva você a cerca de 95% lá. Você pode codificar querystrings inteiras codificando um dicionário e você pode codificar para um conjunto comum que é válido para caminhos através de urlencode em strings.
Não fazemos nada além de utf-8 ou isso. Porque onde isso iria parar. Há muitas partes de um url, há íris e todas têm suas próprias dobras. Quando estamos lá, por que não apenas fornecer um codificador punycode para o netloc?
Eu encontrei esse problema ao tentar criar um arquivo em um repositório gitlab por meio de chamadas de API. A API gitlab requer que as barras sejam codificadas. Para fazer este trabalho eu faço: {{myvar | urlencode | regex_replace ('/', '% 2F')}}. Estou trabalhando com os filtros Ansible e Jinja2 em minhas tarefas de manual. Isso pode ser uma solução alternativa para aqueles de vocês que estão acertando isso, pois eu validei que funciona.
Vejo alguns debates sobre quais caracteres devem ser codificados por cento, no meu entendimento, isso está atualmente coberto no RFC3986. https://tools.ietf.org/html/rfc3986#section -2.2
Embora, para meu caso de uso, @ahuffman tenha fornecido uma
Quero encerrar porque surgiu novamente. Meus argumentos contra isso já foram levantados aqui anteriormente, mas quero reiterá-los porque na verdade há um PR aberto atualmente (# 864) que propõe adicionar outro filtro para ajudar a API do GitLab.
API do GitLab quebrada se colocada atrás de todos os tipos de configurações de proxy e há questões abertas para ela ( problema de exemplo ). Em vez disso, eu proporia documentar uma solução alternativa e por que as pessoas não deveriam fazê-lo.
Um exemplo de solução alternativa poderia ser este:
{{ value|urlencode|replace("/", "%2f") }}
Isso é um pouco assumir uma posição, mas fazer isso pode encorajar as pessoas a não repetir os erros dos outros que vieram antes delas.
Comentários muito úteis
Eu encontrei esse problema ao tentar criar um arquivo em um repositório gitlab por meio de chamadas de API. A API gitlab requer que as barras sejam codificadas. Para fazer este trabalho eu faço: {{myvar | urlencode | regex_replace ('/', '% 2F')}}. Estou trabalhando com os filtros Ansible e Jinja2 em minhas tarefas de manual. Isso pode ser uma solução alternativa para aqueles de vocês que estão acertando isso, pois eu validei que funciona.