2013-08-26 11 views
5

Ich versuche, das folgende Muster zu arbeiten. Ich muss einen dynamischen Pfad in meinem clientseitigen Code angeben, um zu einigen vordefinierten Hosts wechseln zu können. Ich ordne diese Hosts ab, indem ich ihren Alias ​​an eine/fwd/url angehängt habe. Die Alias ​​wird an den realen Server in nginx wie folgt abgebildet:Dynamische Proxy_pass mit Karte und regexp

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

dann in der Serverkonfiguration Teil ertappe ich jede URL beginnend mit fwd und gelten den zugeordneten Alias-Wert. Der restliche Teil der URL, nach dem Alias, sollte ebenfalls an die URL angehängt werden.

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

Wenn ich dies zu testen mit:

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

ich:

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

Aber als Test die Ergebnisse aus der regexp ich:

$1: foo 
$2: something/else 

So Gesamt es scheint zu funktionieren. Die Regex scheint in Ordnung zu sein, aber ich kann es nicht in eine Zeichenfolge verketten? Irgendwelche Ideen oder gibt es einen leichteren/besseren Weg, um das Gleiche zu erreichen?

[EDIT]

fand ich einen möglicherweise viel einfachen Weg, dies zu tun, indem Sie einen Abfrage-Parameter vorwärts genannt werden. Erste Karte der Abfrage-Parameter auf ein die richtige host:

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

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

}

dann die Parameter in dem Pfad verwenden, um weitergeleitet:

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

Ich würde erwarten, und URL wie:

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

Ergebnis:

http://foo.domain.nl/ 

... aber das funktioniert immer noch nicht. Ich bekomme eine 404 zurück. Was vermisse ich?

Antwort

6

Ich ging schließlich zurück zum ersten Ansatz, weil es nicht bequem ist, einen Abfrageparameter zu einer URL dafür hinzuzufügen. Es macht die Client-Logik unnötig komplex.

Ich fand die Lösung zu meinem ersten Ansatz. Die Regex in der Standortangabe war falsch. Sie müssen die Regex in Variablennamen erfassen, indem Sie? wie folgt:

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

Dann $ fwd_alias wird den Alias ​​wie foo oder bar enthalten. $ fwd_path mit enthält den gesamten Pfad danach.

Um auf den vollständigen Pfad einschließlich optionaler Abfrageparameter übergeben Sie die proxy_pass angeben wie:

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

Das ist es!

So, jetzt, auch die Abbildung in dem ersten Beispiel, und das Hinzufügen der Resolver, kommt es darauf an:

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

und eine Anfrage mit dem folgenden Pfad:

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

Karten:

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

Jede Chance, Sie können eine "vollständige" Kopie der Lösung bitte posten. Ich folge dem (so weit ich kann), aber immer noch 404. Alstublief. – Guy

1

Ich war auf dem richtigen Weg.

Wenn Sie mit einem variablen Argumente verwenden proxy_pass mögen, müssen Sie zwei Dinge tun:

  1. eine Resolver-Anweisung hinzufügen, den Host-Namen aufzulösen. Wie ich es verstehe, sucht nginx beim Start alle Domänennamen in der Konfiguration und ordnet sie IPs zu. Da wir einen variablen Hostnamen verwenden, kann nginx beim Laden der Konfiguration nicht nachsehen, und wir müssen den DNS-Resolver angeben.

  2. Wenn Sie eine Variable in proxy_pass verwenden, müssen Sie http: // hinzufügen. Nicht sicher, warum das so ist.

So ergibt sich:

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

Und es funktioniert!:)