Algunas últimas aclaraciones cuando me topé con este problema: nginx.org/en/docs/http/request_processing.html establece claramente: "Tenga en cuenta que las ubicaciones de todos los tipos prueban solo una parte URI de la línea de solicitud sin argumentos. Esto se hace porque los argumentos en la cadena de consulta se puede dar de varias maneras "
Thomas Urban
Respuestas:
37
¿Pueden los bloques de ubicación nginx coincidir con una cadena de consulta de URL?
Respuesta corta : no.
Respuesta larga : hay una solución alternativa si solo tenemos un puñado de dichos bloques de ubicación.
Aquí hay una solución alternativa de muestra para 3 bloques de ubicación que deben coincidir con cadenas de consulta específicas:
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
}
}
Enfoque interesante! ¿Puedo recomendar en $args ~ "service=git-send-pack"lugar de $args = "service=git-send-pack"? Este formulario acomoda múltiples parámetros de consulta.
Derek Mahar
1
stackoverflow.com/a/40313590/107158 ilustra el enfoque que seguí para manejar argumentos de cadena de consulta. Al igual que su respuesta, la mía usa ify $arg_fieldname, pero usa en rewritelugar de error_pagey location @name. Tenga en cuenta que en ese ejemplo, mis intentos de usar @nameel parámetro de reemplazorewrite no tuvieron éxito.
Derek Mahar
1
Por cierto, debería ser $args ~y $arg_somerandomfield =.
Derek Mahar
1
También se puede usar la mapfunción nginx para este propósito, que es más rápido.
Tero Kilkanen
1
@PothiKalimuthu, gracias por aclarar esto. Mientras tanto, lo que he hecho es reemplazar el queryparámetro por una ruta de URL como esta en feedback/{auth_key}lugar de /feedback?auth_key=abc. De esta manera no necesito usar if, puedo definir el patrón de ubicación usando regexy eso es todo.
WM
4
Sé que esta pregunta tiene más de un año, pero he pasado los últimos días destruyendo mi cerebro por un problema similar. Quería diferentes reglas de autenticación y manejo para repositorios públicos y privados, incluyendo empujar y tirar. Esto es lo que finalmente se me ocurrió, así que pensé en compartir. Sé que ifes una directiva complicada, pero esto parece funcionar bien para mí:
# 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;
# ...
}
?
)?Respuestas:
Respuesta corta : no.
Respuesta larga : hay una solución alternativa si solo tenemos un puñado de dichos bloques de ubicación.
Aquí hay una solución alternativa de muestra para 3 bloques de ubicación que deben coincidir con cadenas de consulta específicas:
Puede usar $ query_string, $ args o $ arg_fieldname. Todos harán el trabajo. Puede saber más sobre error_page en los documentos oficiales .
Advertencia: asegúrese de no utilizar los códigos HTTP estándar .
fuente
$args ~ "service=git-send-pack"
lugar de$args = "service=git-send-pack"
? Este formulario acomoda múltiples parámetros de consulta.if
y$arg_fieldname
, pero usa enrewrite
lugar deerror_page
ylocation @name
. Tenga en cuenta que en ese ejemplo, mis intentos de usar@name
el parámetro de reemplazorewrite
no tuvieron éxito.$args ~
y$arg_somerandomfield =
.map
función nginx para este propósito, que es más rápido.query
parámetro por una ruta de URL como esta enfeedback/{auth_key}
lugar de/feedback?auth_key=abc
. De esta manera no necesito usarif
, puedo definir el patrón de ubicación usandoregex
y eso es todo.Sé que esta pregunta tiene más de un año, pero he pasado los últimos días destruyendo mi cerebro por un problema similar. Quería diferentes reglas de autenticación y manejo para repositorios públicos y privados, incluyendo empujar y tirar. Esto es lo que finalmente se me ocurrió, así que pensé en compartir. Sé que
if
es una directiva complicada, pero esto parece funcionar bien para mí:fuente