Nginx प्रॉक्सी में URL डिकोडिंग को अक्षम करना


21

जब मैं इस URL को ब्राउज़ करता हूं: http://localhost:8080/foo/%5B-%5Dसर्वर ( nc -l 8080) इसे प्राप्त करता है:

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

हालाँकि जब मैं nginx (1.1.19) के माध्यम से इस एप्लिकेशन को प्रॉक्सी करता हूं:

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

नंगेक्स पोर्ट के माध्यम से रूट किए गए एक ही अनुरोध को मार्ग डीकोड किए जाने के साथ अग्रेषित किया जाता है:

GET /foo/[-] HTTP/1.1

जीईटी पथ में डिकोड किए गए वर्ग कोष्ठक लक्ष्य सर्वर ( HTTP स्थिति 400 - पथ में अवैध वर्ण ... ) की त्रुटियों का कारण बन रहे हैं क्योंकि वे अन-एस्केप हो गए हैं।

क्या URL डिकोडिंग को अक्षम करने या इसे वापस एनकोड करने का एक तरीका है ताकि nginx के माध्यम से रूट किए जाने पर लक्ष्य सर्वर को ठीक वैसा ही रास्ता मिल जाए? कुछ चतुर URL फिर से लिखते हैं?


जवाबों:


19

वैलेन्टिन वी। बारटेनेव को उद्धृत करते हुए (जिन्हें इस उत्तर का पूरा श्रेय मिलना चाहिए):

प्रलेखन से एक उद्धरण :

  • यदि प्रॉक्सी_पास यूआरआई के साथ निर्दिष्ट किया जाता है , तो सर्वर से अनुरोध पारित करते समय, सामान्यीकृत अनुरोध का एक हिस्सा यूआरआई के स्थान का मिलान यूआरआई द्वारा निर्देश में निर्दिष्ट किया जाता है

  • यदि URI के बिनाproxy_pass निर्दिष्ट किया जाता है , तो मूल अनुरोध को संसाधित करते समय क्लाइंट द्वारा भेजे गए रूप में URI सर्वर से उसी रूप में अनुरोध किया जाता है

आपके मामले में सही कॉन्फ़िगरेशन होगा:

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

8
मैं बदलना पड़ा http://localhost:8080/करने http://localhost:8080के मामले में किसी को भी एक ही स्थिति मैंने किया था के रूप में है।
herrtim

4
बैकग्राउंड सर्वर पर जाने से पहले Nginx URI को क्यों डीकोड करता है? अगर यह यूआरआई को अछूता रखता है तो क्या यह अधिक समझ में नहीं आएगा?
प्लैटिपस

@platypus, इसे तब तक अछूता रखा जाता है, जब तक कि आप स्पष्ट रूप से
सबस्टेशनों का

2

ध्यान दें कि URL डिकोडिंग, जिसे आमतौर पर nginx के प्रलेखन के भीतर $uri"सामान्यीकरण" के रूप में जाना जाता है , बैकएंड IFF से पहले होता है:

  • या तो किसी भी यूआरआई को proxy_passअपने भीतर निर्दिष्ट किया जाता है, भले ही केवल अनुगामी सभी द्वारा स्लैश किया जाए,

  • या, यूआरआई को प्रोसेसिंग के दौरान, उदाहरण के लिए, के माध्यम से बदल दिया जाता है rewrite


दोनों स्थितियों को स्पष्ट रूप से http://nginx.org/r/proxy_pass (जोर मेरा) पर प्रलेखित किया गया है :

  • यदि proxy_passनिर्देश एक यूआरआई के साथ निर्दिष्ट किया जाता है , तो जब एक अनुरोध सर्वर को दिया जाता है, तो सामान्यीकृत अनुरोध यूआरआई के स्थान का मिलान करने वाला हिस्सा यूआरआई द्वारा निर्देश में निर्दिष्ट किया जाता है

  • अगर proxy_passनिर्दिष्ट किया जाता है यूआरआई के बिना , अनुरोध URI में सर्वर से पारित हो जाता है एक ही फार्म के रूप में एक ग्राहक द्वारा भेजे गए जब मूल अनुरोध संसाधित किया जाता है, या पूर्ण सामान्यीकृत अनुरोध URI पारित हो जाता है जब प्रसंस्करण बदल यूआरआई


समाधान या तो URI को ओपी के मामले में छोड़ना है, या, वास्तव में, एक चतुर rewriteनियम का उपयोग करें :

# 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;
}

आप इसे नियंत्रण समूह सहित संबंधित स्टैक ओवरफ्लो उत्तर में लाइव देख सकते हैं


प्रलेखन यहाँ भ्रमित है। दोनों रूपों में एक यूआरआई होता है। यह है पथ घटक है कि एक में मौजूद और अन्य में लापता है।
माइकल हैम्पटन

@ मायकिल हैम्पटन, मैं असहमत हूं - पथ को आम तौर पर यूआरआई कहा जाता है, इसलिए, पथ के बिना, इसमें यूआरआई शामिल नहीं है।
cnst

अकेले एक सापेक्ष पथ भी एक मान्य URL हो सकता है। बिंदु है, शेष भी एक वैध यूआरआई (जैसे http://localhost:8080) है। आप असहमत हैं, तो आप यह समय लग सकता है आरएफसी 3986. के लेखकों के साथ
माइकल हैम्पटन

@ मिचेल हैम्पटन दुर्भाग्य से, ऐसा लगता है कि योजना और रास्ता एक यूआरआई होना अनिवार्य है, प्राधिकरण, तर्क, टुकड़ा वैकल्पिक हैं
नॉर्मन जू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.