Nginx proxy’de URL kod çözme işlevini devre dışı bırakma


21

Bu URL'ye göz attığımda: http://localhost:8080/foo/%5B-%5Dserver ( nc -l 8080) olduğu gibi alıyor:

GET /foo/%5B-%5D HTTP/1.1

Ancak, bu uygulamayı nginx (1.1.19) aracılığıyla proxy'leydiğimde:

location /foo {
        proxy_pass    http://localhost:8080/foo;
}

Nginx portu üzerinden yönlendirilen aynı istek kodu çözülmüş yolla iletilir:

GET /foo/[-] HTTP/1.1

GET yolundaki kodu çözülmüş köşeli parantezler, hedef sunucudaki hatalara neden olur ( HTTP Durum 400 - Yoldaki geçersiz karakter ... ).

URL kod çözmeyi devre dışı bırakmak veya geri kodlamak için hedef sunucunun nginx üzerinden yönlendirildiğinde aynı yolu alabilmesi için bir yolu var mı? Bazı zeki URL yeniden yazma kuralı?


Yanıtlar:


19

Aktaran Valentin V. Bartenev (Bu yanıt için tam kredi almalısınız):

Dokümantasyondan bir alıntı :

  • Proxy_pass, URI ile belirtilirse , bir isteği sunucuya iletirken, konumla eşleşen normalleştirilmiş bir istek URI'sının bir parçası , yönergede belirtilen bir URI ile değiştirilir.

  • Eğer proxy_passbelirtilen URI olmadan orijinal bir isteği işlerken bir istemci tarafından gönderilen gibi bir istek URI aynı formda sunucuya geçirilir

Durumunuzda doğru yapılandırma şöyle olacaktır:

location /foo {
   proxy_pass http://localhost:8080;
}

8
Benimle aynı durumda olan birine http://localhost:8080/geçmek zorunda kaldım http://localhost:8080.
herrtim

4
Nginx neden URI'yı arka uç sunucusuna aktarmadan önce kodunu çözüyor? URI'ya dokunulmaz olsaydı daha mantıklı olmaz mıydı?
ornitorenk

@platypus, oyuncu değişikliği gerçekleştirmeye başlayana kadar dokunulmadı
cnst

2

Genellikle nginx belgelerinde $uri"normalizasyon" olarak bilinen URL kod çözmenin arka uç IFF'den önce gerçekleştiğini unutmayın:

  • Her bir URI proxy_passkendi içinde belirtilir , sadece izleyen kısım kendi kendine kesse bile,

  • veya, işleme sırasında URI değiştirilir, örn rewrite.


Her iki koşul da açıkça http://nginx.org/r/proxy_pass adresinde belgelenmiştir (benimki vurgusu):

  • Eğer proxy_passyönerge belirtilen bir URI ile , daha sonra bir istek sunucuya geçirildiğinde, bir kısmı normalize URI yer eşleşen istek bir URI ile değiştirilmiştir yönergede belirtilen

  • Eğer proxy_passbelirtilirse , bir URI olmadan , istek URI'sında sunucuya geçirilen bir istemci tarafından gönderilen aynı formda orijinal istek işlendiğinde, ya tam normalize istek URI geçirildiğinde zaman işleme değişti URI


Çözüm, URI’yi OP’lerde olduğu gibi atlamak ya da akıllıca bir rewritekural kullanmaktır :

# map `/foo` to `/foo`:
location /foo {
    proxy_pass  http://localhost:8080;  # no URI -- not even just a slash
}

# map `/foo` to `/bar`:
location /foo {
    rewrite  ^  $request_uri;            # get original URI
    rewrite  ^/foo(/.*)  /bar$1  break;  # drop /foo, put /bar
    return 400;   # if the second rewrite won't match
    proxy_pass    http://localhost:8080$uri;
}

Sen olabilir bu, ilgili yığın taşması yanıtında yaşadığını görmek kontrol grubu da dahil olmak üzere.


Belgeler burada kafa karıştırıcı. Her iki form da bir URI içerir. Birinde var olan ve diğerinde eksik olan yol bileşenidir .
Michael Hampton

@ MichaelHampton, katılmıyorum - PATH genellikle URI olarak adlandırılır, yani, yolu olmayan, URI içermez.
cn

Yalnız göreceli bir yol elbette geçerli bir URL olabilir. Mesele şu ki, kalan da geçerli bir URI (örn. http://localhost:8080). Kabul etmiyorsanız, RFC 3986'nın yazarlarından alabilirsiniz.
Michael Hampton

@MichaelHampton Ne yazık ki, şema ve yolun bir URI olması zorunlu olduğu görünüyor, otorite, argümanlar, fragman isteğe bağlı
Norman Xu
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.