2013-08-26 37 views
5

Sto cercando di ottenere il seguente schema per funzionare. Devo specificare un percorso dinamico nel mio codice lato client per poter passare ad alcuni host predefiniti. Mappo questi host aggiungendo il loro alias a/fwd/url. L'alias viene mappato al server reale nginx come questo:proxy_pass dinamico con mappa e espressione regolare

map $uri $repoUrl { 
    default    invalid; 
    ~^/fwd/foo/.*  http://foo.domain.nl/; 
    ~^/fwd/bar/.*  http://bar.domain.nl/; 
    } 

Poi, nella parte server config prendo qualsiasi url che comincia per FWD e applicare il valore alias mappato. La parte rimanente dell'URL, dopo l'alias, dovrebbe essere aggiunta all'URL.

location /fwd/(\w+)/(.*)$ { 
    add_header X-FwdHost "$repoUrl$2"; 
    add_header Access-Control-Allow-Origin "*"; 
    proxy_pass   "$repoUrl$2"; 
    proxy_redirect off; 
    access_log on; 
} 

Se provo questo con:

curl -i http://localhost:8080/fwd/foo/something/else 

ottengo:

X-FwdHost: http://foo.domain.nl/ 

Ma quando prova i risultati del regexp ottengo:

$1: foo 
$2: something/else 

Quindi nel complesso sembra che funzioni. La regex sembra essere ok, ma non riesco a farlo concatenare in una stringa? Qualche idea o c'è un modo più semplice/migliore per realizzare lo stesso?

[EDIT]

ho trovato un modo forse molto più facile da fare questo, utilizzando un parametro di query denominata in avanti. In primo luogo mappare il parametro di query a una destra host:

map $arg_forward $repo_forward { 
default   http://invalid_repo_forward/; 

foo    http://foo.domain.nl/; 
bar    http://bar.domain.nl/; 

}

quindi utilizzare il parametro nel percorso da inoltrare:

location /fwd/ { 
    add_header X-FwdHost $repo_forward; 
    add_header Access-Control-Allow-Origin "*"; 
    proxy_pass   $repo_forward; 
    proxy_redirect off; 
    access_log on; 
} 

mi si aspetterebbe e url del tipo:

http://localhost:8080/fwd/?forward=foo 

Per ottenere in:

http://foo.domain.nl/ 

... ma ciò non funziona. Ricevo un 404 restituito. Cosa mi manca?

risposta

6

Alla fine sono tornato al primo approccio, perché non è conveniente aggiungere un parametro di query a un URL per questo. Rende la logica client inutile complessa.

Ho trovato la soluzione al mio primo approccio. La regex nell'istruzione location era sbagliata. Hai bisogno di catturare la regex nei nomi delle variabili usando? così:

location ~ ^/fwd/(?<fwd_alias>\w+)/(?<fwd_path>.*)$ 

Quindi $ fwd_alias conterrà l'alias come foo o bar. $ fwd_path con contiene l'intero percorso dopo di ciò.

di trasmettere il percorso completo tra cui i parametri di ricerca opzionali si specifica il proxy_pass come:

proxy_pass http://$repo_url$fwd_path$is_args$args; 

Questo è tutto!

Così ora, compresa la mappatura nel primo esempio, e aggiungendo il risolutore, si tratta di:

location ~ ^/fwd/(?<fwd_alias>\w+)/(?<fwd_path>.*)$ { 
    resolver 8.8.8.8; 
    add_header Access-Control-Allow-Origin "*"; 
    proxy_pass http://$repo_url$fwd_path$is_args$args; 
    proxy_redirect off; 
    access_log on; 
} 

E una richiesta con il seguente percorso:

http://localhost:8080/fwd/foo/something/else?with=query 

mappe a:

http://foo.domain.nl/something/else?with=query 
+0

Ogni possibilità di inviare una copia "completa" della soluzione per favore. Sto seguendo questo (per quanto posso) ma sto ancora ricevendo 404. Alstublieft. – Guy

1

Ero sulla strada giusta.

Se si desidera utilizzare proxy_pass con un argomento variabile è necessario fare due cose:

  1. aggiungere un'istruzione di risoluzione per risolvere i nomi degli host. A quanto ho capito, all'avvio nginx cerca tutti i nomi di dominio nella configurazione e li mappa su IP. Dato che stiamo usando un nome host variabile, nginx non può cercarlo durante il caricamento della configurazione e dobbiamo specificare il resolver DNS.

  2. Quando si utilizza una variabile in proxy_pass, è necessario aggiungere http: // ad essa. Non sono sicuro del perché.

Quindi questo si traduce in:

location /fwd/ { 
    resolver 8.8.8.8; 
    add_header X-FwdHost $repo_forward; 
    add_header Access-Control-Allow-Origin "*"; 
    proxy_pass http://$repo_forward; 
    proxy_redirect off; 
    access_log on; 
} 

e funziona!:)