2016-12-11 5 views
0

Ich habe einige Probleme mit dem Umschreiben, wenn es um mehrere Token-Nummern geht.Nginx Rewrite mit Regex Mehrere Token (+)

Ich arbeite an Versionierung unserer API, so dass veraltete Aufrufe unserer Version auf unsere neueste Version gehen. Der Einfachheit halber möchten wir sagen, dass wir v4 und v5 unterstützen. Wenn einige unsere v1-3 treffen, müssen wir es zu v5 gehen. Ebenso, wenn jemand v6 schlägt, sollte es auch zu v5 gehen.

Unsere nginx.conf verwendet proxy_pass mit vorgeschaltetem so habe ich jede Version, die wir

upstream v4 { 
    server 127.0.0.1:3000 
} 

upstream v5 { 
    server 127.0.0.1:3001 
} 

blockiert dann auf Proxy verwenden Standort auf einem anderen Port läuft

location ^~ /v5 { 
    proxy_pass $scheme://v5; 
} 

location ^~ /v4 { 
    proxy_pass $scheme://v4; 
} 

location ~* "^/v[0-9]+" { 
    rewrite ^/v[0-9]+/(.*)$ /$latestVersion/$1; 
    proxy_pass $scheme://$latestUpstream; 
} 

Der letzte Standort Block arbeitet für v0-9 aber nicht fangen, wenn die Zahl mehrere Ziffern wie v11 ist, obwohl ich die + benutze.

Jede Hilfe dazu wäre großartig. Wirklich verwirrt dadurch. Vielen Dank!

Antwort

0

Im folgenden Block:

location ~* "^/v[0-9]+" { 
    rewrite ^/v[0-9]+/(.*)$ /$latestVersion/$1; 
    proxy_pass $scheme://$latestUpstream; 
} 

Die rewrite Anweisung führt eine implizites rewrite ... last, was bedeutet, dass der URI schließlich von dem location ^~ /v5 Block verarbeitet wird, in diesem Block die proxy_pass Anweisung Rendering fast redundant. Siehe this document für rewrite Syntax.

Die rewrite nicht übereinstimmen, wenn der URI als die Versionszeichenfolge allein präsentiert ohne/ einen nachlauf, z.B. /v11.

Sie müssen die / nach der Versionszeichenfolge optional machen. Versuchen:

location ^~ /v { 
    rewrite ^/v[0-9]+(/.*)$ /$latestVersion$1 last; 
} 

Der reguläre Ausdruck location Block wahrscheinlich nicht notwendig ist, so habe ich ersetzt einen kürzer Präfix location (siehe this document für location Syntax).

Ich habe ein last Suffix hinzugefügt, um die Absicht der rewrite klar zu machen.


EDIT: Als Reaktion auf Ihren Kommentar

Unterscheidung zwischen den URIs /v5 und /v51 (das heißt ohne die Hinter /) ist problematisch, mit Präfix location allein blockiert. Wenn der URI immer (mindestens) einen nach der Versionszeichenfolge folgenden / hätte, wäre es leicht zu lösen, indem einfach ein nachlaufender / zu Ihren zwei vorhandenen location Blöcken hinzugefügt wird.

Aber vorausgesetzt, Sie benötigen die kurzen URIs wie /v5 und /v51 zu arbeiten, sollten Sie die Lösung auf regulären Ausdruck location Blöcke zu wechseln.

Beachten Sie, dass reguläre Ausdrücke location Blöcke unterschiedlich ausgewertet werden, und diese Reihenfolge ist wichtig. Möglicherweise müssen Sie diese location Blöcke vor anderen regulären Ausdrücken location Blöcke verschieben, um zu verhindern, dass sie von anderem Code in Ihrer Konfigurationsdatei überschrieben werden.

Zum Beispiel:

location ~* ^/v5(/|$) { 
    proxy_pass $scheme://v5; 
} 
location ~* ^/v4(/|$) { 
    proxy_pass $scheme://v4; 
} 
location ~* ^/v[0-9] { 
    rewrite ^/v[0-9]+(/.*)$ /$latestVersion$1 last; 
} 

Beachten Sie, dass der Modifikator zu ~* geändert wird, die einen regulären Ausdruck bringt (und macht es auch Groß- und Kleinschreibung - die oder möglicherweise nicht für Sie wichtig sein kann).

+0

Danke für die Erklärung, das war wirklich hilfreich. Ich habe ein unerwartetes Verhalten gefunden, bei dem '/ v40..9' und'/v50 ... 9' zu den '/ v4' und'/v5' Positionen gehen, wo ich möchte, dass sie von '/ v' abgefangen werden Lage. Hast du Vorschläge dafür? Ich habe versucht, Regex wie '(/ | $)' zu tun, aber das hat nicht funktioniert. – Dan