I blocchi posizione nginx possono corrispondere a una stringa di query URL?


23

I blocchi nginx possono corrispondere a una stringa di query URL?location

Ad esempio, quale blocco di posizione potrebbe corrispondere alla GETrichiesta HTTP

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

Immagino "location / git / sample-repository / info / refs? Service = git-receive-pack" dato che nginx fa il confronto delle stringhe.
JosefScript,

Confronto delle stringhe dell'intero URL o solo della parte prima del punto interrogativo ( ?)?
Derek Mahar,



1
Qualche ultimo chiarimento mentre mi sono imbattuto in questo problema da solo: nginx.org/en/docs/http/request_processing.html afferma chiaramente: "Nota che posizioni di tutti i tipi testano solo una parte URI della riga di richiesta senza argomenti. Questo viene fatto perché argomenti nella stringa di query può essere fornita in diversi modi "
Thomas Urban

Risposte:


37

I blocchi posizione nginx possono corrispondere a una stringa di query URL?

Risposta breve : No.

Risposta lunga : esiste una soluzione alternativa se abbiamo solo una manciata di tali blocchi di posizione.

Ecco una soluzione alternativa di esempio per 3 blocchi di posizione che devono corrispondere a stringhe di query specifiche:

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

Puoi usare $ query_string, $ args o $ arg_fieldname. Tutti faranno il lavoro. Puoi saperne di più su error_page nei documenti ufficiali .

Avvertenza: assicurarsi di non utilizzare i codici HTTP standard .


1
Approccio interessante! Posso raccomandare $args ~ "service=git-send-pack"invece di $args = "service=git-send-pack"? Questo modulo contiene più parametri di query.
Derek Mahar,

1
stackoverflow.com/a/40313590/107158 illustra l'approccio che ho seguito per gestire gli argomenti della stringa di query. Come la tua risposta, la mia usa ife $arg_fieldname, ma usa al rewriteposto di error_pagee location @name. Si noti che in questo esempio, i miei tentativi di utilizzo @nameper il parametro sostitutivorewrite non hanno avuto successo.
Derek Mahar,

1
A proposito, dovrebbe essere $args ~e $arg_somerandomfield =.
Derek Mahar,

1
Si può anche usare la mapfunzione nginx per questo scopo, che è più veloce.
Tero Kilkanen,

1
@PothiKalimuthu, grazie per aver chiarito questo. Quello che ho fatto nel frattempo è di sostituire il queryparametro con un percorso URL come questo feedback/{auth_key}anziché /feedback?auth_key=abc. In questo modo non ho bisogno di usare if, posso definire il modello di posizione usando regexe basta.
WM,

4

So che questa domanda ha più di un anno, ma ho passato gli ultimi giorni a distruggere il mio cervello per un problema simile. Volevo regole di autenticazione e gestione diverse per i repository pubblici e privati, inclusi push e pull. Questo è quello che alla fine ho pensato, quindi ho pensato di condividere. So che ifè una direttiva difficile, ma questo sembra funzionare bene per me:

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

}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.