Saya mencoba untuk mengonversi proksi terbalik menggunakan pengaturan mod_rewrite Apache yang menarik untuk menggunakan Nginx sebagai gantinya (karena kekhawatiran eksternal kami bergerak dari Apache ke Nginx, dan sebagian besar semuanya berfungsi dengan baik kecuali bagian ini).
Pengaturan awal saya adalah membaca cookie HTTP (ditetapkan oleh beberapa aplikasi) dan tergantung pada nilainya, arahkan proxy terbalik ke backend yang berbeda. Bunyinya kira-kira seperti ini:
RewriteCond %{HTTP_COOKIE} proxy-target-A
RewriteRule ^/original-request/ http://backend-a/some-application [P,QSA]
RewriteCond %{HTTP_COOKIE} proxy-target-B
RewriteRule ^/original-request http://backend-b/another-application [P,QSA]
RewriteRule ^/original-request http://primary-backend/original-application [P,QSA]
Saya mencoba untuk mencapai hal yang sama menggunakan Nginx, dan konfigurasi awal saya adalah sesuatu seperti ini (di mana "proxy_override" adalah nama cookie):
location /original-request {
if ($cookie_proxy_override = "proxy-target-A") {
rewrite . http://backend-a/some-application;
break;
}
if ($cookie_proxy_override = "proxy-target-B") {
rewrite . http://backend-b/another-application;
break;
}
proxy_pass http://primary-backend/original-application;
}
Tapi ternyata tidak. Saya sudah mencoba untuk melihat apakah Nginx dapat membaca cookie saya dengan menulis proksi primer untuk mengalihkan ke sesuatu berdasarkan ${cookie_proxy_override}
dan saya dapat melihat bahwa itu membaca konten baik-baik saja, tetapi if
tampaknya selalu gagal.
Percobaan saya berikutnya, menurut jawaban Rikih adalah ini:
location /original-request {
if ($http_cookie ~ "proxy-target-A") {
rewrite . http://backend-a/some-application;
break;
}
if ($http_cookie ~ "proxy-target-B") {
rewrite . http://backend-b/another-application;
break;
}
proxy_pass http://primary-backend/original-application;
}
Dan sekarang saya dapat melihat bahwa if
blok diaktifkan, tetapi alih-alih memproksi permintaan (seperti yang saya pikir akan lakukan) ia mengembalikan 302 redirect ke URL yang ditentukan - yang bukan apa yang saya coba lakukan: Saya perlu server untuk menyampaikan permintaan secara transparan ke backend dan mengirimkan respons ke klien asli.
Apa yang saya lakukan salah?
if
) dan saya menerapkannya. Namun ada satu masalah - Nginx (setidaknya versi saya: 1.0.0) tidak suka menangkap bernomormap
, jadi saya harus menggunakannya~^(?P<name>[\w-]+) $name;
sebagai gantinya. Saya telah mengedit jawaban Anda sesuai dengan itu.Akhirnya solusi saya intinya adalah:
Tes ini dilakukan dalam
server
ruang lingkup untuk setiap permintaan (sebelum pengalihan aktual diselesaikan) dan hanya digunakan untuk mengatur variabel - ini tampaknya merupakan penggunaan modul "menulis ulang" Nginx yang didukung. Ini juga menguji keseluruhan$http_cookie
seperti yang disarankan @Rikih, tetapi menyertakan nama cookie untuk memastikan saya tidak cocok dengan hal-hal acak yang mungkin dilontarkan orang kepada saya.Kemudian dalam
location
lingkup di mana saya ingin melakukan redirect, saya menggunakan nama variabel yang berisi konfigurasi hulu default atau ditimpa oleh cookie.sumber
Sudahkah Anda mencoba $ http_cookie? http://wiki.nginx.org/HttpRewriteModule
if ($ http_cookie ~ * "proxy-target-A") {foo; }
sumber
rewrite
sebenarnya tidak melakukan penulisan ulang proxy tetapi mengembalikan redirect ke klien, dan saya tidak bisa menggunakan proxy_pass diif
blok. Saya telah memperbarui pertanyaannya.Saya punya sampel yang saya gunakan untuk mendeteksi header permintaan berdasarkan udid dan itu berfungsi, mungkin Anda akan mendapatkan beberapa ide.
sumber
nginx: [emerg] "proxy_pass" may not have URI part in location given by regular expression, or inside named location, or inside the "if" statement, or inside the "limit_except" block in /etc/nginx/conf.d/proxy.conf:47
proxy_pass
perintah, jadi saya tidak yakin bagaimana cara kerjanya untuk Anda mengingat diskusi forum di atas.