web-dev-qa-db-fra.com

Les blocs d'emplacement nginx peuvent-ils correspondre à une chaîne de requête URL?

nginxlocation blocs peut-il correspondre à une chaîne de requête URL?

Par exemple, quel bloc d'emplacement peut correspondre à la demande HTTP GET

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

Les blocs d'emplacement nginx peuvent-ils correspondre à une chaîne de requête URL?

Réponse courte : Non.

Réponse longue : Il existe une solution de contournement si nous n'avons qu'une poignée de ces blocs de localisation.

Voici un exemple de solution de contournement pour 3 blocs d'emplacement qui doivent correspondre à des chaînes de requête spécifiques:

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

Vous pouvez utiliser $ query_string, $ args ou $ arg_fieldname. Tous feront l'affaire. Vous pouvez en savoir plus sur error_page dans les documents officiels .

Avertissement: veuillez vous assurer de ne pas utiliser les codes HTTP standard .

39
Pothi Kalimuthu

Je sais que cette question a plus d'un an, mais j'ai passé les derniers jours à détruire mon cerveau pour un problème similaire. Je voulais des règles d'authentification et de gestion différentes pour les dépôts publics et privés, y compris pour pousser et tirer. C'est ce que j'ai finalement trouvé, alors j'ai pensé que je partagerais. Je sais que if est une directive délicate, mais cela semble très bien fonctionner pour moi:

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

}
4
Jared Brandt