1. Rewrite 모듈 지시자
- RewriteEngine
- RewirteLog File-Path
- RewriteLogLevel Level
2. Rewrite Flag
RewriteRule 문법중 마지막에 패턴이 일치할 경우 어떤 동작을 취할지 지정하는 부분이며, 이를 플래그라고도 합니다. 지정할 수 있는 플래그중 자주 사용되는 것들은 다음과 같은 항목이 있습니다. 플래그는 전체 단어를 써도 되지만 축약어로 써도 됩니다. 필자의 프로젝트에 적용된 것을 위주로 정리를 해보겠습니다.- Last : L
- Nocase : NC
- Noescape: NE 기본적으로 & 및 ?와 같은 특수 문자는 16진수 등가로 변환된다. [NE] 플래그를 사용하면 그런 일이 발생하지 않는다.
- Redirect:R
- Passthru:PT
- qsappend: QSA
3. RewriteCond
앞에서 RewriteRule 에 대한 설명을 보고 만약 조건문이 필요할 경우는 어떻게 해야 할지 의문이 생긴 독자들도 있을 것이다. RewriteCond 는 그런 독자들의 의문을 해소해 줄 지시자이다. 여러 가지 상황별로 조건을 확인하고 그 조건이 맞을 경우 처리를 하게 할 수 있다. RewriteCond는 다음과 같은 문법을 갖는다. RewriteCond TestString Pattern [Flags] TestString 에는 다음과 같은 값등을 사용할 수 있다.- 직전 RewriteRule 에서 일치한 캡처값 – RewriteCond 앞에 RewriteRule 을 사용했고 정규 표현식에서 그룹으로 지정된 값이 있을 경우 TestString 에 사용할 수 있다. 사용할 경우 $N (N 은 0 에서 9사이 값) 형식으로 사용한다.
- 직전 RewriteCond 에서 일치한 캡처값 – RewriteCond 앞에 RewriteCond를 사용했고 정규 표현식에서 그룹으로 지정된 값이 일치했을 경우 %N(N 은 0 에서 9) 형식으로 사용할 수 있다.
- 서버 변수 – 웹서버가 갖고 있는 변수값을 사용할 수 있다. 서버의 변수를 사용할 경우 %{변수명} 형식으로 사용한다. 제일 많이 사용하는 변수들은 %{HTTP_HOST}, %{QUERY_STRING} 등이다.
| 변수명 | 설명 |
|---|---|
| HTTP 요청 변수 | |
| HTTP_HOST | URL 에서 호스트 이름 부분이며 클라이언트가 보낸 HTTP 헤더중 Host: 헤더에 있는 값이 된다. 가상 호스트 기반 rewrite 규칙을 설정할 경우에 많이 사용된다. |
| HTTP_REFERER | 사용자가 현재 요청시 어떤 링크를 통해 들어왔는지 알수 있는 변수이다. |
| REQUEST_METHOD | HTTP 요청 메소드로 보통 GET 또는 POST 가 된다. |
| QUERY_STRING | GET 방식으로 URL 을 호출했을 때 넘긴 파라미터가 설정된다. 예로 “http://www.example.com/article/view.jsp?one=two&three=four” 로 호출했을 경우, QUERY_STRING 은 “one=two&three=four” 가 된다. |
| REQUEST_URI | 클라이언트가 요청한 리소스로 보통 URL 에서 호스트 이름과 파라미터를 제외한 부분이 된다. 위 QUERY_STRING 예제에서 REQUEST_URI는 “article/view.jsp” 가 된다. |
| 클라이언트 변수 | |
| HTTP_USER_AGENT | 사용자 브라우저 정보가 설정 |
| HTTP_ACCEPT | 브라우저가 처리할 수 있는 컨텐츠의 목록 |
| REMOTE_ADDR | 요청 클라이언트가 사용하는 IP |
| REMOTE_USER | 로그인이 필요한 리소스에 접근할 경우 사용자명 |
| 서버 내부 변수 | |
| DOCUMENT_ROOT | 현재 가상 호스트에 설정한 DocumentRoot 의 경로를 얻을 수 있다. |
| REQUEST_FILENAME | 클라이언트가 요청한 파일이나 스크립트가 현재 서버에 위치하는 절대 경로를 의미한다. 현재 가상호스트의 DocumentRoot 가 “/var/www/vhost1” 이고 클라이언트가 /book.php 를 요청했을 경우 REQUEST_FILENAME 은 /var/www/vhost1/book.php 가 된다. |
| SERVER_NAME | The canonical name of the current virtual host. |
| SERVER_ADDR | The IP address of the current virtual host. |
| SERVER_PORT | The port number from which the current request is being served. |
| HTTPS | SSL 이나 TLS 를 사용할 경우 on 으로 설정되고 HTTP 일 경우 off 이다. |
- NoCase:NC – RewriteRule 과 마찬가지로 대소 문자를 구분하지 않을 경우 사용한다.
- ORNext:OR – OR 플래그는 여러 개의 RewriteCond 를 사용할 경우 논리적인 OR 조건이 필요할 때 사용할 수 있다.(여러 개의 RewriteCond 가 있을 때 기본적으로 AND 로 처리한다.)
4. 실제 사용 사례
필자의 프로젝트에서 사용하는 RewriteRule에 대해서 정리를 해보도록 하겠습니다. # 1단계 URL 을 그냥 통과 시킬 리스트 적용
RewriteCond %{REQUEST_URI} ^/etc/designs(.*) [NC,OR]
RewriteCond %{REQUEST_URI} ^/etc.clientlibs(.*) [NC,OR]
RewriteCond %{REQUEST_URI} ^/apps/samsung/login(.*) [NC,OR]
RewriteCond %{REQUEST_URI} ^/bin(.*) [NC,OR]
RewriteCond %{REQUEST_URI} ^/aemapi(.*) [NC,OR]
RewriteCond %{REQUEST_URI} ^/sysapi(.*) [NC,OR]
RewriteCond %{REQUEST_URI} ^/libs/granite/csrf/token [NC,OR]
RewriteCond %{REQUEST_URI} ^/samsung(.*) [NC,OR]
RewriteCond %{REQUEST_URI} ^/content/dam(.*) [NC]
RewriteRule ^(.*)$ $1 [PT]
위의 예제는 재작성 조건에 대해서 여러개를 연결 시켜 놓은 것입니다. 개발코드로 치면 조건문에서 or조건으로 여러개의 체크 조건을 갖고 있습니다.
- 대소문자를 가리지 않는다. [NC]
- 조건체크를 or조건으로 한다. [OR]
- 최종 나온 path에 대해서 그대로 통과 시킨다. [PT]
# 2단계 /content/samsung 이 붙어 있을 경우 제거
RewriteCond %{REQUEST_URI} ^/content/samsung/(.*)$ [NC]
RewriteRule ^/content/samsung/(.*)$ /$1 [R=302,NE,QSA,L]
위의 조건은 url 요청이 특정 문자열(/content/samsung)을 붙이고 들어올때, 그부분을 제거하는 내용입니다.
- /content/samsung을 떼어주되, 특수문자를 그대로 둡니다.[NE]
- query string에 대해서 그대로 append 해줍니다.[QSA]
- 302 redirectino 처리를 하고 break를 수행합니다.[R=302, L]
# 3단계 /가 없거나 확장자가 없을때 / 붙여줌
RewriteCond %{REQUEST_URI} !.*\..*$
RewriteCond %{REQUEST_URI} !.*/$
RewriteRule ^(.*)$ $1/ [R=302,NE,QSA]
# handle requests to pages ending with .html
# 4단계 .html 로 끝날경우 / 를 붙여줌
RewriteCond %{REQUEST_URI} .*.html$
RewriteRule ^(.*).html$ $1/ [R=302,NE,QSA]
3단계와 4단계는 유사합니다. 모든 request에 대해서 끝에 슬래시를 추가해주는 내용입니다.
- 확장자가 없거나 (!...$), 슬래시가 없거나 (!.*/$)의 조건을 찾음.
- .html로 끝나는 경우(.*.html$)
- 특수문자 처리, query string append, Redirection 처리[R=302,NE,QSA]
# 5단계 앞의 작업이 끝났을경우 인터널로 호출할때 /content/samsung 을 붙여줌
# 앞에서 빼고 뒤에서 붙이는 이유는 사전 URL 작업을 진행하고 내부로 호출하기 위해서임
RewriteCond %{REQUEST_URI} ^/(.*)$ [NC]
RewriteRule ^/(.*)$ /content/samsung/$1 [NE,QSA]
# 6단계 내부적으로 호출할때 html 을 붙여줌
RewriteCond %{REQUEST_URI} .*/$
RewriteCond %{REQUEST_URI} !^/$
RewriteRule ^(.*)/$ $1.html [PT,NE,L,QSA]
5단계와 6단계를 거치면서 내부의 internal server(was)로 페이지를 요청하기 위해서 다시 /content/samsung과 확장자(.html)을 붙여줍니다.
5. apache debug 방법
아파치 rewriterule을 셋팅하면서 항상 어려웠던 부분이 rewrite rule에 대한 디버깅이였습니다. 서칭을 좀 하다보니, online으로 rewrite rule을 테스팅 해볼 수 있는 사이트가 있었습니다. online rewrite test tool
아래에 rewrite rule에 대해서 읿력을 하고, 위에 request 되는 url에 대해서 입력을 하면, 아래에 debugging된 내용이 노출이 됩니다. 이것을 통해서 개략적인 rewrite rule에 대해서 확인을 해 볼 수 있습니다.
6. 마치며…
이번시간에는 apache rewrite rule에 대해서 정리를 해 보았습니다. apache의 지극히 일부의 모듈에 대해서 정리를 한것이고, 지난 포스팅과 더불어 nginx, apache의 설정들에 대한 정리는 지속적으로 해볼 예정입니다. nginx-aapche-was로 이어지는 트래픽 흐름의 중간에 어디 부분에서 오류를 일으키고, 어떤 부분을 고쳐야 되는지 확인하기 위해서 각각의 미들웨어 + 어플리케이션 로그를 확인할줄도 알아야된다는 것을 느꼇습니다.함께 보면 좋은 글
- [DevOps] Nginx Configuration 정리
- [DevOps] Rinetd를 활용한 portforward
- [DevOps] Nginx Lua module 사용법
- [DevOps] Nginx Logrotation 설정
새 글이 올라오면 Threads @wonizz.ai 에도 올립니다. 팔로우해 두면 피드에서 바로 볼 수 있습니다.