Jinja: urlencode tidak lolos dari garis miring

Dibuat pada 20 Nov 2015  ·  21Komentar  ·  Sumber: pallets/jinja

Ini dimunculkan di #444, tetapi kode ini selalu dievaluasi ke b'/' pada Python 3.4.1, jadi garis miring masih belum lolos.

Komentar yang paling membantu

Saya mengalami masalah ini ketika mencoba membuat file di repositori gitlab melalui panggilan API. Api gitlab membutuhkan garis miring untuk dikodekan. Untuk membuat pekerjaan ini saya lakukan: {{ myvar | kode urlen | regex_replace('/','%2F') }}. Saya bekerja dengan filter Ansible dan Jinja2 dalam tugas buku pedoman saya. Ini bisa menjadi solusi bagi Anda yang melakukan ini, karena saya memvalidasinya.

Semua 21 komentar

Hanya peringatan @mitsuhiko
Saya tidak tahu mengapa, tetapi do_urlencode masih tidak bisa lepas dari garis miring, sementara unicode_urlencode berfungsi seperti yang diharapkan.

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'

Karena filter urlencode tidak lolos dari garis miring. Apakah ada alasan khusus mengapa harus? Untuk memperjelas ini: itu hanya mengkodekan garis miring di posisi nilai dari pasangan kunci/nilai yang diteruskan.

Saya percaya ini adalah perilaku standar untuk fungsi yang dimaksudkan untuk menyandikan url. Alat seperti http://meyerweb.com/eric/tools/dencoder/ berperilaku seperti ini. Saya juga memiliki setidaknya satu alat di dalam perusahaan kami yang mengharapkan URL diteruskan di dalam permintaan GET dengan garis miring yang lolos.
Juga, saya tidak mengerti mengapa unicode_urlencode dipanggil di dalam do_urlencode dengan for_qs=True .
Mungkin saya mengerti sesuatu yang salah.

Garis miring adalah karakter yang dicadangkan dalam komponen jalur dan perilaku yang lebih umum adalah menyandikan semuanya kecuali garis miring di sana saat memaksa sesuatu ke perilaku yang disandikan url. Alternatif (untuk menyandikan garis miring ke %2f ) bahkan tidak masuk akal karena sebagian besar server langsung menolak permintaan tersebut karena masalah keamanan karena server backend biasanya tidak dapat membedakan %2f dan / dalam komponen jalur saat mereka beroperasi pada oktet yang didekodekan.

Jadi satu-satunya bagian di mana garis miring benar-benar masuk akal pengkodean dalam string kueri dan di sinilah encoder berbasis dict yang urlencode bekerja seperti itu. Namun bahkan ada garis miring tidak harus dikodekan, jadi tidak ada alasan untuk memaksanya untuk dikodekan.

Fungsi urlencode harus digunakan untuk kebanyakan orang secara default karena itu tidak menyandikan garis miring. Jika Anda memiliki persyaratan khusus maka Anda dapat mengganti fungsi dalam pendaftaran filter Anda.

Oke. Terima kasih Armin.

Hai, saya mendapat masalah yang sama dengan reject slash, ini kodenya:

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

Saya ingin menolak root disk, tetapi tidak berfungsi lagi, bagaimana cara mengatasinya?

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

Bekerja untuk saya.

Masih tidak berfungsi untuk saya, @ThiefMaster , apakah masalah python? apa versi python yang Anda gunakan.

    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 menggunakan is (dan Anda tidak dapat mengharapkan 'foo' is 'foo' bekerja). Anda ingin equalto yang menggunakan == .

Ya berhasil, saya tidak sekeluarga dengan Jinja2. Terima kasih, @ThiefMaster

Jadi satu-satunya bagian di mana garis miring benar-benar masuk akal pengkodean adalah dalam string kueri dan di sinilah encoder berbasis dict yang urlencode miliki berfungsi seperti itu. Namun bahkan ada garis miring tidak harus dikodekan, jadi tidak ada alasan untuk memaksanya untuk dikodekan.

Tidak, misalnya Anda perlu menyandikan / dalam nama pengguna dan kata sandi juga.
Itulah alasan mengapa JS memiliki encodeURI __and__ encodeURIComponent .

Itu cukup adil tetapi dalam praktiknya juga tidak perlu di sana dan kredensial yang disertakan sudah tidak digunakan lagi. Karena itu tidak mungkin diproduksi di dalam templat, itu adalah kasus tepi yang tidak terlalu layak untuk dipertimbangkan.

Ansible menggunakan Jinja, dan itu cukup umum untuk menangani kredensial keamanan saat menyiapkan sistem. Saya baru saja menemukan kasus di mana kata sandi yang dibuat secara otomatis berisi garis miring yang tidak diganti dengan urlencode untuk menghasilkan URL basis data, yang sangat disayangkan. Meskipun melanggar perilaku saat ini akan menjadi masalah, mengapa tidak memperkenalkan filter kedua yang lolos dari garis miring?

Ansible bisa melakukan itu. Tidak perlu ada perubahan seperti itu di Jinja itu sendiri - cukup dapat diperluas untuk menambahkan filter khusus atau bahkan mengganti filter bawaan.

@ThiefMaster Apakah kasus penggunaan selain membuat templat HTML tidak relevan saat menentukan apa yang berguna untuk dimasukkan dalam Jinja itu sendiri? Misalnya, proyek Saltstack, dengan tujuan yang mirip dengan Ansible, juga menggunakan Jinja untuk templating, dan akan mendapat manfaat dari perubahan yang sama.

@danielkza apa yang menghentikan saltstack dari menyediakan filter yang melakukan itu?

@mitsuhiko Mengapa Jinja menyertakan filter

Bagaimana dengan menambahkan argumen safe ke urlencode , seperti yang dimiliki urllib.url_quote Python, sehingga secara default garis miring dipertahankan, tetapi dengan cara yang dapat dengan mudah diganti?

Jinja mencoba menyediakan beberapa fungsionalitas yang umum digunakan. Kami memiliki dua mode untuk urlencoding yang memberi Anda sekitar 95% di sana. Anda dapat menyandikan seluruh string kueri dengan menyandikan dict dan Anda dapat menyandikan ke set umum yang valid untuk jalur melalui urlencode pada string.

Kami tidak melakukan apa pun selain utf-8 atau itu. Karena di mana itu akan berhenti. Ada terlalu banyak bagian dari url, ada iris dan semuanya memiliki kekusutan sendiri. Ketika kami berada di sana, mengapa tidak menyediakan encoder punycode untuk netloc saja?

Saya mengalami masalah ini ketika mencoba membuat file di repositori gitlab melalui panggilan API. Api gitlab membutuhkan garis miring untuk dikodekan. Untuk membuat pekerjaan ini saya lakukan: {{ myvar | kode urlen | regex_replace('/','%2F') }}. Saya bekerja dengan filter Ansible dan Jinja2 dalam tugas buku pedoman saya. Ini bisa menjadi solusi bagi Anda yang melakukan ini, karena saya memvalidasinya.

Saya melihat beberapa perdebatan tentang karakter apa yang harus dikodekan persen, menurut pemahaman saya ini saat ini tercakup dalam RFC3986. https://tools.ietf.org/html/rfc3986#section -2.2

Meskipun untuk kasus penggunaan saya, @ahuffman telah memberikan solusi yang masuk akal.

Saya ingin menutup ini karena muncul lagi. Argumen saya yang menentang ini sudah ada di sini sebelumnya, tetapi saya ingin mengulanginya karena sebenarnya ada PR terbuka saat ini (#864) yang mengusulkan untuk menambahkan filter lain untuk membantu API GitLab.

API GitLab rusak jika ditempatkan di belakang semua jenis pengaturan proxy dan ada masalah terbuka untuk itu ( Contoh Masalah ). Saya malah akan mengusulkan untuk mendokumentasikan solusi dan mengapa orang tidak boleh melakukannya.

Contoh penyelesaiannya bisa seperti ini:

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

Ini sedikit mengambil sikap tetapi melakukan ini dapat mendorong orang untuk tidak mengulangi kesalahan orang lain yang datang sebelum mereka.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat