Nginx位置块可以匹配URL查询字符串吗?


23

可以nginx的 location匹配URL查询字符串?

例如,哪个位置块可能与HTTP GET请求匹配

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

我猜是“位置/ git / sample-repository / info / refs?service = git-receive-pack”,因为nginx只是进行字符串比较。
JosefScript '16

整个URL的字符串比较还是问号(?)之前的字符串比较?
德里克·马哈尔



1
当我自己偶然发现此问题时,需要进行最后的澄清:nginx.org/en/docs/http/request_processing.html明确指出:“请注意,所有类型的位置仅测试请求行的URI部分而不包含参数。之所以这样做是因为参数在查询字符串可以用几种方式”给予
托马斯城市

Answers:


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_pagelocation @name。请注意,在这个例子中,我在尝试使用@name替换参数rewrite均告失败。
德里克·马哈尔

1
顺便说一句,应该是$args ~$arg_somerandomfield =
德里克·马哈尔

1
一个人也可以map为此使用nginx 功能,这是更快的。
Tero Kilkanen

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

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.