Daylogs/Nginx
nginx rewrite 플래그의 차이점: last 와 break
ohgyun
2014. 12. 17. 12:14
발생일: 2014.12.17
키워드: nginx rewrite flags, last, break
문제:
nginx 의 rewrite 디렉티브에는 4가지 플래그(last, break, redirect, permanent)가 있는데, 그 중 last 와 break 는 자꾸 봐도 헷갈린다.
나중에 봐도 헷갈리지 않게 자세히 정리했다.
해결책:
API 문서에 있는 정의는 다음과 같다. (http://wiki.nginx.org/HttpRewriteModule)
Flags can be any of the following:
last - completes processing of current rewrite directives and restarts the process (including rewriting) with a search for a match on the URI from all available locations.
break - completes processing of current rewrite directives and non-rewrite processing continues within the current location block only.
redirect - returns temporary redirect with code 302; it is used if the substituting line begins with http://
permanent - returns permanent redirect with code 301
이 중에 last 와 break 플래그의 정의를 좀 더 쉽게 (우리말로) 바꿔보면 아래와 같다.
last: rewrite 직후에 현재 블럭의 프로세싱을 종료하고 다음 URI 매칭을 찾아 진행한다.
break: rewrite 이후 현재 블럭을 마지막으로 프로세싱을 종료한다. 단, 현재 블럭 내에서 rewrite 가 아닌 작업까진 진행한다.
두 플래그의 동작 방식은 특히 헷갈려서, 쉽게 이해할 수 있는 예제를 만들었다.
(라인을 쉽게 설명하기 위해 A0, A1, … 과 같이 붙여놓았다)
A0 location /a {
A1 rewrite ^ /b;
A2 rewrite ^ /c;
A3 add_header x-a a;
A4 proxy_set_header foo foo;
A5 proxy_pass http://localhost:3000;
A6 }
B0 location /b { # B
B1 add_header x-b b;
B2 proxy_pass http://localhost:3000;
B3 }
C0 location /c { # C
C1 rewrite ^ /d;
C2 add_header x-c c;
C3 proxy_pass http://localhost:3000;
C4 }
D0 location /d { # D
D1 add_header x-d d;
D2 proxy_pass http://localhost:3000;
D3 }
nginx 룰이 위와 같은 때, `/a`로 요청을 할 경우 다음과 같은 순서로 룰이 적용된다.
`/a` 요청 시:
A0 -> A1 -> A2 -> C0 -> C1 -> D0 -> D1 -> D2
기본적으로 블럭 내에 rewrite 룰이 있으면, rewrite 을 수행한 후 해당 블럭의 프로세싱을 종료하고 변경된 URI 룰을 찾아 이동한다.
A0 location /a {
A1 rewrite ^ /b last;
A2 rewrite ^ /c;
A3 add_header x-a a;
A4 proxy_set_header foo foo;
A5 proxy_pass http://localhost:3000;
A6 }
위와 같이 `last` 플래그를 사용하면, 다음과 같이 `last` 플래그를 마지막으로 rewrite 를 종료한다.
`/a` 요청 시:
A0 -> A1 -> B0 -> B1 -> B2
A0 location /a {
A1 rewrite ^ /b break;
A2 rewrite ^ /c;
A3 add_header x-a a;
A4 proxy_set_header foo foo;
A5 proxy_pass http://localhost:3000;
A6 }
`break` 플래그를 사용하면, 현재 블럭 내에서의 rewrite 작업을 break 플래그가 있는 디렉티브에서 종료하고,
현재 블럭 내의 rewrite 가 아닌 다른 작업을 진행하고 프로세싱을 종료한다.
`/a/` 요청 시:
A0 -> A1 -> A3 -> A4 -> A5
이렇게 정리해두니 또 간단하네… -_-
여튼, 이제 헷갈리지 말자. ㅎㅎ
반응형