Czy bloki nginx mogą pasować do ciągu zapytania URL?location
Na przykład, jaki blok lokalizacji może pasować do GET
żądania HTTP
GET /git/sample-repository/info/refs?service=git-receive-pack HTTP/1.1
?
)?
Czy bloki nginx mogą pasować do ciągu zapytania URL?location
Na przykład, jaki blok lokalizacji może pasować do GET
żądania HTTP
GET /git/sample-repository/info/refs?service=git-receive-pack HTTP/1.1
?
)?
Odpowiedzi:
Czy bloki lokalizacji nginx mogą pasować do ciągu zapytania adresu URL?
Krótka odpowiedź : nie
Długa odpowiedź : istnieje obejście, jeśli mamy tylko kilka takich bloków lokalizacji.
Oto przykładowe obejście dla 3 bloków lokalizacji, które muszą pasować do określonych ciągów zapytań:
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
}
}
Możesz użyć $ query_string, $ args lub $ arg_fieldname. Wszyscy wykonają robotę. Możesz dowiedzieć się więcej o error_page w oficjalnych dokumentach .
Ostrzeżenie: nie używaj standardowych kodów HTTP .
$args ~ "service=git-send-pack"
zamiast $args = "service=git-send-pack"
? Ten formularz obsługuje wiele parametrów zapytania.
if
i $arg_fieldname
, ale używa rewrite
zamiast error_page
i location @name
. Zauważ, że w tym przykładzie, moje próby używając @name
do zastępczego parametru rewrite
były nieudane.
$args ~
i $arg_somerandomfield =
.
map
tym celu można również użyć funkcji nginx , która jest szybsza.
query
parametru ścieżką URL taką jak ta feedback/{auth_key}
zamiast /feedback?auth_key=abc
. W ten sposób nie muszę używać if
, mogę zdefiniować wzór lokalizacji za pomocą regex
i to wszystko.
Wiem, że to pytanie ma ponad rok, ale ostatnie kilka dni spędziłem na niszczeniu mózgu przez podobny problem. Chciałem różnych zasad uwierzytelniania i obsługi publicznych i prywatnych repozytoriów, w tym wypychania i wyciągania. To w końcu wymyśliłem, więc pomyślałem, że podzielę się. Wiem, że if
jest to trudna dyrektywa, ale wydaje mi się, że to działa dobrze:
# 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;
# ...
}