메뉴 건너뛰기

Dev tips

Apache+Tomcat Apache Module mod_rewrite

taknim 2006.12.15 00:16 조회 수 : 8976 추천:2090

http://cafe.naver.com/q69.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=5117http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html
4. Apache Modules .. [ mod_rewrite ]

mod_rewrite module은 재작성 패턴(rewrite pattern)을 받아들여 URL에 적용을 한다. 여기서 패턴이라는 것은 정규 표현식(regular expression)을 의미하며 이 정규 표현 식에 match가 되는 pattern을 요청한 url에서 출력을 하게 되는 것이다.

이 module은 설정 전체, virtual host, Directory 지시자, .htaccess에서 사용이 가 능하다.

머 이렇다 저렇다 설명하는 것 보다 몇가지 예제를 보는 것이 더 낳을 것이다. 여기 서는 2가지의 예를 들려고 한다. mod_rewrite module에 대해서 전반적으로 다 다루기 에는 양이 너무 많고 혹시 관심이 있는 사람은 O'reilly 에서 나온 Apache: The Definitive Guide 의 8장 Redirection 을 참조하면 되겠다. 참고로 "아파치 핵심 가이드"라는 책으로 변역서 가 출판되어 있다.

1. domain.com/~id 를 id.domain.com 으로..

이 작업을 하기 전에 먼저 선행되어야 할 일이 있다. 일단 name server에서 a.com 에 대해서 설정을 하자면 a.com의 어떠한 서브 도메인들도 다 등록이 되어 있어야 한다. bind8 부터는 *.a.com 을 등록하여 이를 행할수가 있다.

Hanterm - cat /etc/httpd/conf/httpd.conf

 [root@bbuwoo /etc]$ cat /etc/httpd/conf/httpd.conf

  생략...
  RewriteEngine on
  RewriteCond   %{HTTP_HOST}             ^[^.]+\.oops\.org$
  RewriteRule   ^(.+)                     %{HTTP_HOST}$1 [C]
  RewriteRule   ^([^.]+)\.oops\.org(.*)   /home/$1/htdocs$2
  생략...

 [root@bbuwoo /etc]$

RewriteEngine을 on하여 Rewrite 기능을 활성화 한다.
RewriteCond 는 RewriteModule이 URI만 다룰수 있기 때문에 RewriteRule에서 domain 부분까지 다루기 위하여 %{HTTP_HOST}를 match시키게 한다.
RewriteRule로 먼저 접속한 서버의 경로(URI) 즉 domain.com의 뒤의 경로 부분을 %{HTP_HOST} 뒤로 매치시킨다. [C] 는 서로 연결된 규칙들을 순차적으로 적용을 하는 것을 의미한다.
RewriteRule을 한번더 적용시켜서 domain.com의 앞부분을 $1변수로 받고 뒤의 경로들을 $2로 받은 다음 읽혀져야할 절대 경로에 매치를 시킨다.

그리고 apache 를 재시작 한후에 id.domain.com 으로 접속을 해보기 바란다. :-)


2. 여러개의 도메인을 하나로 합칠때

이것을 설명하기 전에 어떠한 상황인지 예를 들어 보자. 일단 나의 홈페이지는 http://www.oops.org, http://oops.kr.net, http://goes.co.kr (외에도 2개가 더있다 ^^) 등으로 접속을 할수가 있다. 그런데 http://goes.co.kr 로 접속을 했을 경우 http://goes.co.kr/bbuwoo.html 이 아니라 http://www.oops.org/bbuwoo.html 로 자동으로 포워딩이 되게 하고 싶을때 아래처럼 구현을 하면 가능하다. 즉 위의 url중에서 domain부분만 자신의 대표 도메인으로 싸악 바꿔치기를 하기위한 방법이다.

실제로 예를 보고 싶다면 내 홈페이지의 아무 페이지나 oops.org외의 도메인으로 접근을 해 보기 바란다. 접근을 하는 순간 url이 www.oops.org로 바뀌는 것을 볼수 있을 것이다.

이것을 구현하기 위해서는 rewrite rule만으로는 불가능하고 domain 부분을 www.oops.org 로 변경해 주는 하나의 script가 필요하다. 일단 www.oops.org 의 웹 경로중의 하나에 Rewrite 라는 디렉토리를 만들고 위에서 domain부분을 바꿔 치기 하는 script를 아래와 같이 하나를 만들어 넣는다. 아래의 script 예는 PHP로 예를 들겠다.

Hanterm - cat /home/httpd/Rewrite/index.php

 [root@bbuwoo Rewrite]$ cat index.php

  

 [root@bbuwoo Rewrite]$

위의 script를 분석해 보면 getenv("REQUEST_URI") 는 domain name 뒤의 경로를 받아오는 apache 환경 변수이다. 그리고 $path라는 변수에 메인 domain을 지정 하고 나머지 경로를 변수값으로 부여를 해 준다. 즉 경로없이 도메인으로만 접 근했을 경우를 위해서 위와 같이 구성이 된다.

다음 실질岵막?matching을 해 주는 apache에서의 Rewrite rule을 살펴 보도록 한다.

Hanterm - cat /etc/httpd/conf/httpd.conf

 [root@bbuwoo /etc]$ cat /etc/httpd/conf/httpd.conf

 RewriteEngine on
 RewriteCond	%{HTTP_HOST}	(.+)\.(co\.kr|kr\.net)$
 RewriteRule   ^(.+)$		%{HTTP_HOST}$1  [C]
 RewriteRule   (.+)\.(co\.kr|kr\.net)(.*)	/Rewrite/index.php

 [root@bbuwoo /etc]$

위의 Virtual Host에서 Rewrite를 살짝 분석해 보자.

RewriteEngine을 on하여 Rewrite 기능을 활성화 한다.
RewriteCond를 이용하여 RewriteRule에 넘겨줄 도메인들을 지정한다. 위에서는 정규표현식(REGEX)를 이용하여 *.co.kr 또는 *.kr.net 의 도메인들만 rewrite rule에 적용을 시키겠다는 의미가 된다.
RewriteRule에서 RewirteCond에서 적용된 도메인들에 한해서 모든 URI앞에 해당 도메인들을 매치 시킨다음 [C]를 지정하여 순차 적용을 한다.
RewriteRule을 이용하여 해당 Domain으로 오는 모든 url (domain/path)를 http://www.oops.org/Rewrite/index.php 를 뿌려주게 한다.

이렇게 하는 이유는 Rewrite는 url을 바꾸는 것이 아니라 해당 url로 접속을 했을때 보여주는 부분만 match를 시키기 때문이다. 그래서 우리는 url을 바꾸기 위해서 특정 script를 이용하기 위함이다.

일단 Rewrite Rule에 적용되어진 도메인 즉, 예를 들어 http://www.goes.co.kr/bbuwoo.html 같은 경우 *.co.kr에 match가 되어 Rewrite/index.php를 출력하게 되고, index.php에서는 URI부분을 받은 다음 도메인 부분만 바꿔치기 하여 새로운 URL로 forwarding을 하게 되는 것이다.





아파치/conf/httpd.conf
<IfModule rewrite_module>
# on : 사용, off : 사용 안 함
RewriteEngine on
# 로그 레벨 0~9 숫자가 높을수록 자세히 로그 남김
#RewriteLogLevel 9
# 로그파일 경로
Rewritelog "|/usr/sbin/rotatelogs /var/log/httpd/rewrite_log.%Y%m%d-%H 3600"
# lowercase 설정 (소문자로 변경)
RewriteMap lowercase int:tolower
# REQUEST_URI(/경로명/파일명)에 /download/PortalService/ 가 있을 때 아래 줄 실행
RewriteCond %{REQUEST_URI} ^/download/PortalOCPService/
# /download/PortalService/ 뒤의 문장을 소문자로 변경하고 경로를 이동함, [L] : 실행 후 종료
RewriteRule ^/download/PortalOCPService/(.*) /var/www/html/download/portalocpservice/${lowercase:$1} [L]
# REQUEST_URI(/경로명/파일명)에 /download/ 가 없을 때 아래 줄 실행
RewriteCond %{REQUEST_URI} !^/download/
# 모든 문자열을 소문자로 변경하고 경로를 이동함, [L] : 실행 후 종료
RewriteRule ^(.+) ${lowercase:$1} [L]
</IfModule>