क्या nginx लोकेशन ब्लॉक एक URL क्वेरी स्ट्रिंग से मेल खा सकते हैं?


23

क्या nginx locationब्लॉक एक URL क्वेरी स्ट्रिंग से मेल खा सकता है ?

उदाहरण के लिए, कौन सा स्थान ब्लॉक HTTP GETअनुरोध से मेल खा सकता है

GET /git/sample-repository/info/refs?service=git-receive-pack HTTP/1.1

मुझे लगता है कि "लोकेशन / गिट / सैंपल-रिपॉजिटरी / इंफॉर्मेशन / रिफ्स? सर्विस = गिट-रिसीट-पैक" नगनेक्स के रूप में सिर्फ स्ट्रिंग तुलना करता है।
जोसेफस्क्रिप्ट 16

पूरे URL की स्ट्रिंग या प्रश्न चिह्न से पहले का हिस्सा ( ?)?
डेरेक महार



1
कुछ अंतिम स्पष्टीकरण जैसा कि मैंने स्वयं इस समस्या पर ठोकर खाई है: nginx.org/en/docs/http/request_processing.html स्पष्ट रूप से बताता है: "ध्यान दें कि सभी प्रकार के स्थान बिना अनुरोध के केवल अनुरोध लाइन के एक URI भाग का परीक्षण करते हैं। यह तर्क इसलिए किया जाता है क्योंकि तर्क क्वेरी स्ट्रिंग में कई तरीकों से दिया जा सकता है "
थॉमस अर्बन

जवाबों:


37

क्या nginx लोकेशन ब्लॉक एक URL क्वेरी स्ट्रिंग से मेल खा सकते हैं?

संक्षिप्त उत्तर : नहीं।

दीर्घ उत्तर : यदि हमारे पास केवल कुछ स्थान हैं, तो एक समाधान है।

यहां 3 लोकेशन ब्लॉक के लिए एक नमूना वर्कअराउंड है, जो विशिष्ट क्वेरी स्ट्रिंग्स से मेल खाने की आवश्यकता है:

server {
  #... common definitions such as server, root

  location / {
    error_page 418 = @queryone;
    error_page 419 = @querytwo;
    error_page 420 = @querythree;

    if ( $query_string = "service=git-receive-pack" ) { return 418; }
    if ( $args ~ "service=git-upload-pack" ) { return 419; }
    if ( $arg_somerandomfield = "somerandomvaluetomatch" ) { return 420; }

    # do the remaining stuff
    # ex: try_files $uri =404;

  }

  location @queryone {
    # do stuff when queryone matches
  }

  location @querytwo {
    # do stuff when querytwo matches
  }

  location @querythree {
    # do stuff when querythree matches
  }
}

आप $ query_string, $ args या $ arg_fieldname का उपयोग कर सकते हैं। सब काम करेंगे। आप आधिकारिक डॉक्स में error_page के बारे में अधिक जान सकते हैं ।

चेतावनी: कृपया सुनिश्चित करें कि मानक HTTP कोड का उपयोग करें ।


1
दिलचस्प दृष्टिकोण! क्या मैं $args ~ "service=git-send-pack"इसके बजाय की सिफारिश कर सकता हूं $args = "service=git-send-pack"? यह फ़ॉर्म कई क्वेरी मापदंडों को समायोजित करता है।
डेरेक महार

1
stackoverflow.com/a/40313590/107158 उस दृष्टिकोण का चित्रण करता है जो मैंने क्वेरी स्ट्रिंग तर्कों को संभालने के लिए किया था। आपके उत्तर की तरह, मेरा उपयोग करता है ifऔर $arg_fieldname, लेकिन rewriteइसके बजाय error_pageऔर का उपयोग करता है location @name। ध्यान दें कि कि उदाहरण में, का उपयोग करने में मेरी प्रयास @nameके लिए प्रतिस्थापन में पैरामीटर rewriteअसफल रहे थे।
डेरेक महार

1
वैसे, यह होना चाहिए $args ~और $arg_somerandomfield =
डेरेक महार

1
mapइस उद्देश्य के लिए कोई भी nginx सुविधा का उपयोग कर सकता है , जो तेज है।
टेरो किलकेनन

1
@PothiKalimuthu, इसे स्पष्ट करने के लिए धन्यवाद। इस बीच मैंने जो किया है वह इसके बजाय queryएक यूआरएल मार्ग द्वारा पैरामीटर को बदलने के लिए feedback/{auth_key}है /feedback?auth_key=abc। इस तरह मुझे उपयोग करने की आवश्यकता नहीं है if, मैं स्थान पैटर्न का उपयोग करके परिभाषित कर सकता हूं regexऔर यही है।
WM

4

मुझे पता है कि यह सवाल एक साल से अधिक पुराना है, लेकिन मैंने पिछले कुछ दिनों से इसी तरह की समस्या पर अपने मस्तिष्क को नष्ट कर दिया है। मैं सार्वजनिक और निजी रेपो के लिए अलग प्रमाणीकरण और हैंडलिंग नियम चाहता था, जिसमें धक्का देना और खींचना भी शामिल था। यह वही है जो मैं अंत में आया था, इसलिए मुझे लगा कि मैं साझा करूंगा। मुझे पता ifहै कि एक मुश्किल निर्देश है, लेकिन यह मेरे लिए ठीक काम लगता है:

# pattern for all repos, public or private, followed by username and reponame
location ~ ^(?:\/(private))?\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?$ {

    # if this is a pull request
    if ( $arg_service = "git-upload-pack" ) {

        # rewrite url with a prefix
        rewrite ^ /upload$uri;

    }

    # if this is a push request
    if ( $arg_service = "git-receive-pack" ) {

        # rewrite url with a prefix
        rewrite ^ /receive$uri;

    }

}

# for pulling public repos
location ~ ^\/upload(\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?)$ {

    # auth_basic "git";
    # ^ if you want

    # ...
    # fastcgi_pass unix:/var/run/fcgiwrap.socket;
    # ...

}

# for pushing public repos
location ~ ^\/receive(\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?)$ {

    # auth_basic "git";
    # ^ if you want

    # ...
    # fastcgi_pass unix:/var/run/fcgiwrap.socket;
    # ...

}

# for pulling private repos
location ~ ^\/upload\/private(\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?)$ {

    # auth_basic "git";
    # ^ if you want

    # ...
    # fastcgi_pass unix:/var/run/fcgiwrap.socket;
    # ...

}

# for pushing private repos
location ~ ^\/receive\/private(\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?)$ {

    # auth_basic "git";
    # ^ if you want

    # ...
    # fastcgi_pass unix:/var/run/fcgiwrap.socket;
    # ...

}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.